How To Use OBS Studio With Zoom

I had the bright idea that I might like to use something like OBS Studio to make my video calls fancier.

It works! And it wasn’t too hard to get working, but it also wasn’t simple and I had to hunt around a lot to figure out how to do it. This post is a summary of the various steps I used to get OBS Studio working on Linux and piping video into Zoom.

Update 19 July 2022: OBS Studio now supports virtual cameras without a plugin as of version 26.1.0.

What This Is Not

This is not a discussion of how to use OBS Studio on Windows, or MacOS, any non-Ubuntu flavour of Linux, or anything else.

I’ll try to give you pointers for where to start looking for solutions if your problem involves Windows or Mac, but you won’t find the answer here. If you’re on a Debian derivative, this may work out for you, but if you’re on something like Arch it might be weirder.

Sorry. But at least you found out early, rather than wading through dozens of forum posts chasing a tantalising hint that ended up going nowhere. Been there, comrade.

The Basics

My setup involves the following components, which may materially affect the results:

  • Ubuntu 18.04 LTS
  • PulseAudio, but also jackd
  • Zoom client for Linux version 3.5 (specifically 3.5.361976.0301)
  • A paid Zoom account

Using APT

OBS Studio is available using APT in Ubuntu, so you can install it like this:

sudo apt install obs-studio

This installs version 25.0.4-0obsproject3~bionic at time of writing.

Add v4l2loopback driver

You need to add a new video output to the system that Zoom can use to pull the video in from. Think of it as a virtual camera, if you like.

Linux has a kernel driver called v4l2loopback that can do this for us. Install it with APT:

sudo apt install v4l2loopback-dkms

We need to load it using modprobe, and we’ll add some parameters to make it easier for us to identify it from inside programs like Zoom:

sudo modprobe v4l2loopback video_nr=10 card_label="OBS Video Source" exclusive_caps=1

This will create our new video device as /dev/video10.

The parameter to video_nr sets the number of the device created, so if you wanted /dev/video24 you would use video_nr=24.

The card_label should show up in Zoom (and other apps) as the name of the device, making it easier to select the right one.

exclusive_caps=1 is necessary for some applications (like Chrome) to be able to use the device. It sets the device to OUTPUT only mode and it won’t start announcing CAPTURE capabilities until you connect a producer (like OBS Studio) to it.

Adding v4l2sink

Update 19 July 2022: You can skip this section now as the plugin capability has been built into OBS since version 26.1.0

To get OBS Studio to send output to our new video device, I used the v4l2sink plugin from https://github.com/CatxFish/obs-v4l2sink. This plugin was originally for Windows but after people asked in this issue thread, the author wrote a version for Linux.

That thread contains a bunch of other hacks to get things working, which you might find interesting. The method I’m documenting here I found the simplest (relatively speaking), but if you want to do some more complex things with multi-streaming, you might find the discussion useful.

Building The Module

Building the source was fairly straightforward. The procedure is documented in the code repo, but I’ll duplicate it here so you can get all the info in one place. Do check the code if a lot of time has passed since this was published, since it might have changed.

Install some pre-requisites

I have a lot of code building tools already installed, so you might encounter some other missing dependencies. Do let me know if there are more I should include here.

sudo apt install cmake qtbase5-dev

Create a holding directory

Let’s create a directory to hold all the code related to this little exercise. It’s neater that way.

mkdir myobscode
cd myobscode

Clone the code for OBS Studio

This grabs the code for OBS Studio as well as a bunch of components it depends on.
git clone --recursive https://github.com/obsproject/obs-studio.git
The resulting code will be in directory myobscode/obs-studio

Clone the plugin code

We’re still in the myobscode directory, so we just grab the code:

git clone https://github.com/CatxFish/obs-v4l2sink

Build the plugin

cd obs-v4l2sink
mkdir build && cd build
cmake -DLIBOBS_INCLUDE_DIR="../../obs-studio/libobs" -DCMAKE_INSTALL_PREFIX=/usr ..

I’ll explain what the cmake line is doing.

The -DLIBOBS_INCLUDE_DIR parameter includes the OBS Studio libraries we need to link against.

The -DCMAKE_INSTALL_PREFIX tells cmake that we will be installing this plugin into the APT installed OBS Studio which gets installed into the /usr directory tree.

Let’s compile the code, using 4 CPUs in parallel:

make -j4

Install the plugin

sudo make install

If you used the install prefix of /usr as in the example above, the plugin will get installed into the APT packaged plugin location: /usr/lib/obs-plugins/

Now we’re ready to connect OBS Studio to Zoom.

Connect OBS Studio to Zoom

Setup OBS Studio

In versions of OBS Studio since 26.1.0, if you have a v4l2loopback device loaded, OBS will detect it and show you a Start Virtual Camera button in the controls.

The controls in OBS Studio, showing a Start Virtual Camera button.

The controls in OBS Studio, showing a Start Virtual Camera button.

I’ve found that, on my Ubuntu 22.04.0 LTS system, if I’ve started and stopped the virtual camera once, I have to unload the v4l2loopback module and re-load it via modprobe (as described above) for the virtual camera to work again. OBS doesn’t provide any information about why it can’t start the camera again, just a generic error message that it can’t. This isn’t very helpful for figuring out how to permanently fix the problem, but the workaround of an rmmod/modprobe script is working for me.

Previous Instructions

You don’t need to do this any more, but I’m leaving this information up so it’s here if anyone is using an older version of the software.

Run OBS Studio, either from commandline with obs or using the system launcher.

Click on the Tools menu, and you should see an item at the bottom of the list called v4l2sink. Click on that, and you’ll get a window like this:

Screenshot of v4l2sink properties

Screenshot of v4l2sink properties

I’ve turned on AutoStart so that OBS Studio immediately starts sending data to the video device when I start it. You’ll need to remember to start the sink manually if you don’t want this to happen.

The device path matches the one we chose for our v4l2loopback device earlier.

I chose format of YUY2 because that’s what worked.

Add Webcam to Scene

You’ll need to minimally configure a Scene and a Source in OBS Studio. The intricate details of setting up OBS Studio are beyond the scope of this article, but you’ll need at least one scene with a webcam in it. Here are the settings for my Logitech USB webcam.

OBS Studio webcam source config

OBS Studio webcam source config. Hanging green material behind you is left as an exercise.

Your scene should now be streaming out to the v4l2sink. Let’s tell Zoom to get its video from there.

Start Zoom Client

If you already have the Zoom client running, you’ll need to exit completely from it and start it again. Zoom only appears to scan for possible webcams when it starts.

Start Zoom, and then open the Settings menu.

Go to Video settings, and use the pulldown menu to select the OBS Video Source, and you should see your webcam output as mediated by OBS Studio.

Select OBS Studio video source for Zoom

Select OBS Studio video source for Zoom

Now you can explore the fun video effects and scene switching capabilities of OBS Studio!

Beware giant kittens!

Beware giant kittens!

 

Bookmark the permalink.

37 Comments

  1. Pingback: Remote Work Makes Us All Content Creators - Gestalt IT

  2. Thomas Balatsos

    hello from greece. I am a teacher and i would like to stream from obs to zoom. i follow your tutorial and im stack there
    cmake -DLIBOBS_INCLUDE_DIR=”../../obs-studio/libobs” -DCMAKE_INSTALL_PREFIX=/usr ..

    — The C compiler identification is GNU 7.5.0
    — The CXX compiler identification is unknown
    — Check for working C compiler: /usr/bin/cc
    — Check for working C compiler: /usr/bin/cc — broken
    CMake Error at /usr/share/cmake-3.10/Modules/CMakeTestCCompiler.cmake:52 (message):
    The C compiler

    “/usr/bin/cc”

    is not able to compile a simple test program.

    It fails with the following output:

    Change Dir: /home/balatsa/myobscode/obs-v4l2sink/build/CMakeFiles/CMakeTmp

    Run Build Command:”/usr/bin/make” “cmTC_ad30a/fast”
    /usr/bin/make -f CMakeFiles/cmTC_ad30a.dir/build.make CMakeFiles/cmTC_ad30a.dir/build
    make[1]: Entering directory ‘/home/balatsa/myobscode/obs-v4l2sink/build/CMakeFiles/CMakeTmp’
    Building C object CMakeFiles/cmTC_ad30a.dir/testCCompiler.c.o
    /usr/bin/cc -o CMakeFiles/cmTC_ad30a.dir/testCCompiler.c.o -c /home/balatsa/myobscode/obs-v4l2sink/build/CMakeFiles/CMakeTmp/testCCompiler.c
    Linking C executable cmTC_ad30a
    /usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_ad30a.dir/link.txt –verbose=1
    /usr/bin/cc CMakeFiles/cmTC_ad30a.dir/testCCompiler.c.o -o cmTC_ad30a
    /usr/bin/ld: cannot find Scrt1.o: ??? ??????? ?????? ?????? ? ?????????
    /usr/bin/ld: cannot find crti.o: ??? ??????? ?????? ?????? ? ?????????
    collect2: error: ld returned 1 exit status
    CMakeFiles/cmTC_ad30a.dir/build.make:97: recipe for target ‘cmTC_ad30a’ failed
    make[1]: *** [cmTC_ad30a] Error 1
    make[1]: Leaving directory ‘/home/balatsa/myobscode/obs-v4l2sink/build/CMakeFiles/CMakeTmp’
    Makefile:126: recipe for target ‘cmTC_ad30a/fast’ failed
    make: *** [cmTC_ad30a/fast] Error 2

    CMake will not be able to correctly generate this project.
    Call Stack (most recent call first):
    CMakeLists.txt:2 (project)

    CMake Error at CMakeLists.txt:2 (project):
    No CMAKE_CXX_COMPILER could be found.

    Tell CMake where to find the compiler by setting either the environment
    variable “CXX” or the CMake cache entry CMAKE_CXX_COMPILER to the full path
    to the compiler, or to the compiler name if it is in the PATH.

    — Configuring incomplete, errors occurred!
    See also “/home/balatsa/myobscode/obs-v4l2sink/build/CMakeFiles/CMakeOutput.log”.
    See also “/home/balatsa/myobscode/obs-v4l2sink/build/CMakeFiles/CMakeError.log”.

    what am i doing wrong;

    sorry for my english

    Thank you in advance

  3. Your development environment is broken. You’ll need to re-install the C-compiler.

    You can see the system trying to tell you this in the error message:

    The C compiler
    
    “/usr/bin/cc”
    
    is not able to compile a simple test program.
    

    Try this:

    apt install --reinstall gcc g++

    and then try running cmake again.

  4. Hi Justin,

    Why does this procedure need a paid Zoom account?

    Thanks.

  5. It might not, but as I tried to explain, my setup involves one so if you don’t have a paid account, your experience might be different to mine.

  6. Hello again Justin,

    I followed the instructions you provided here after re-reading above and noting that you did not say a paid Zoom account was needed but that that was what you had.

    Anyway, I ended up with the following CMake error:

    — Detecting CXX compile features – done
    — Could NOT find Libobs (missing: LIBOBS_LIB)
    CMake Error at external/FindLibObs.cmake:106 (message):
    Could not find the libobs library
    Call Stack (most recent call first):
    CMakeLists.txt:5 (include)

    — Configuring incomplete, errors occurred!
    See also “/home/mark/myobscode/obs-v4l2sink/build/CMakeFiles/CMakeOutput.log”.

    I’m on Ubuntu 20.04. Is there any recommendation you could make installing the libobs library?

    Thanks.

  7. Installed libons-dev and seem to have solved the problem.

    I think I got to my destination:
    Install the project…
    — Install configuration: “”
    — Installing: /usr/lib/obs-plugins/v4l2sink.so
    — Installing: /usr/share/obs/obs-plugins/v4l2sink/locale
    — Installing: /usr/share/obs/obs-plugins/v4l2sink/locale/de-DE.ini
    — Installing: /usr/share/obs/obs-plugins/v4l2sink/locale/en-US.ini
    — Installing: /usr/share/obs/obs-plugins/v4l2sink/locale/zh-TW.ini

    However, the v4l2sink menu item doesn’t show under Tools when I restarted OBS. I’ll look around and see what’s what.

    Thanks.

  8. Progress! Huzzah!

    You’ll need to figure out where OBS expects the plugins to be. On 18.04 LTS it expects them to be in /usr/lib/obs-plugins so make sure v4l2sink.so is in there, and copy it over if it isn’t and then restart OBS.

    You might like to use `checkinstall` to create a .dpkg wrapper thing to help manage the installation without having to learn how to set up the full Debian format package build pipeline.

  9. The folder /usr/lib/obs-plugins/ contains one file: v4l2sink.so.

    Folder /usr/share/obs/obs-plugins/ contains a v4l2sink/locale with three language .ini files.

    The file en-US.ini contains:

    V4l2sink=”V4L2 Video Output”
    AutoStart=”Auto Start”
    Device=”Path to V4L2 Device”
    Format=”Video Format”

    I restarted OBS and also logged out and back into Ubuntu with no luck seeing the plugin listed under the Tools menu.

    Continuing to look around.

  10. Hi Justin,

    The solution for Ubuntu 20.04 (must also be for earlier versions since the fix was for 19.x) is to sudo cp /usr/lib/obs-plugins/v4l2sink.so /usr/lib/x86_64-linux-gnu/obs-plugins/ (See https://srcco.de/posts/using-obs-studio-with-v4l2-for-google-hangouts-meet.html linked from https://github.com/CatxFish/obs-v4l2sink/issues/40)

    The writer says he was told it also works for 18.04, although you didn’t seem to need to do a fix.

    I took your advice and used `checkinstall` before finding this answer to the problem. Maybe the suthors need to set params in their make/install to address various situations.

    Thanks again.

  11. @mark: /usr/lib/obs-plugins/ should contain around 20 plugins.
    If it doesn’t, then your obs package is storing them somewhere else. Try: locate vlc-video.so to find out where, then move v4l2sink.so to the same place :)

  12. Francisco Lee Herera

    Hi Mark, same problem here… in my Debian Buster, the magic obs plugin’s folder is in /usr/lib/x86_64-linux-gnu/obs-plugins problem solved.

  13. There is now an unofficial snap package of OBS that includes v4l2loopback built in.

    sudo snap install obs-studio.

    No need to make the plugin from source. Only

    sudo modprobe v4l2loopback video_nr=10 card_label=”OBS Video Source” exclusive_caps=1

    is needed.

  14. On Debian Buster, I didn’t compile anything, just downloaded the deb from
    https://github.com/CatxFish/obs-v4l2sink/releases/

    e.g.
    $ wget https://github.com/CatxFish/obs-v4l2sink/releases/download/0.1.0/obs-v4l2sink.deb
    $ apt install obs-studio obs-plugins v4l2loopback-dkms
    $ apt install ./obs-v4l2sink.deb

    Now had some trouble with the v4l2loopback-dkms, ( needed linux-headers- )
    do the modprobe and go from there

  15. ESTEBAN RICHMOND-SALAZAR

    Ubuntu 20.04 workaround:

    If you get {
    CMake Error at external/FindLibObs.cmake:106 (message):
    Could not find the libobs library
    } you must do some extra steps

    sudo apt install libobs-dev

    sudo cp /usr/lib/obs-plugins/v4l2sink.so /usr/lib/x86_64-linux-gnu/obs-plugins/

  16. Hi Mark,
    Its probably something obvious (so apologies in advance) but I can’t figure it out… I get the following error message and the log file doesn’t give me any clues I can work with.

    mickey@penguin:~/myobscode/obs-v4l2sink/build$ cmake -DLIBOBS_INCLUDE_DIR=”../../obs-studio/libobs” -DCMAKE_INSTALL_PREFIX=/usr ..
    — The C compiler identification is GNU 8.3.0
    — The CXX compiler identification is GNU 8.3.0
    — Check for working C compiler: /usr/bin/cc
    — Check for working C compiler: /usr/bin/cc — works
    — Detecting C compiler ABI info
    — Detecting C compiler ABI info – done
    — Detecting C compile features
    — Detecting C compile features – done
    — Check for working CXX compiler: /usr/bin/c++
    — Check for working CXX compiler: /usr/bin/c++ — works
    — Detecting CXX compiler ABI info
    — Detecting CXX compiler ABI info – done
    — Detecting CXX compile features
    — Detecting CXX compile features – done
    — Could NOT find Libobs (missing: LIBOBS_LIB)
    CMake Error at external/FindLibObs.cmake:106 (message):
    Could not find the libobs library
    Call Stack (most recent call first):
    CMakeLists.txt:5 (include)

    — Configuring incomplete, errors occurred!
    See also “/home/mickey/myobscode/obs-v4l2sink/build/CMakeFiles/CMakeOutput.log”.

  17. Apologies all I didn’t notice the Typo in the comment above. A simple

    sudo apt-get install libobs-dev

    before building the plugin resolved the error message just fine.

  18. Hi all,

    The plugin installed w/o error messages after the above correction in my steps but now I can’t load it and in OBS I can see it now in the tool selection (after moving the file into the other plugin folder, as described above) but when I try to start the sink I get an error message “Device open failed”

    This is what it looks like when I run a modprobe:

    mickey@penguin:~/obs-v4l2sink/build$ sudo modprobe v4l2loopback devices=1 video_nr=10 card_label=”OBS Cam” exclusive_caps=1
    modprobe: ERROR: ../libkmod/libkmod.c:586 kmod_search_moddep() could not open moddep file ‘/lib/modules/4.19.113-08528-g5803a1c7e9f9/modules.dep.bin’
    modprobe: FATAL: Module v4l2loopback not found in directory /lib/modules/4.19.113-08528-g5803a1c7e9f9
    mickey@penguin:~/obs-v4l2sink/build$ ls /lib/modules/
    4.19.0-9-amd64

  19. In case it saves someone else the aggravation, my experience was that Zoom failed to find the virtual cam if the card_label has a space in it. So with card_label=”OBS Cam” I get a camera I can use in guvcview or skype, but not Zoom. And with card_label=”OBSCam” Zoom is happy too.
    This is with Ubuntu 20.04, OBS 25.0.8 and Zoom 5.1.418436.0628

  20. This works great on Ubuntu 20.04 Be sure to follow all the notes with this blog posting.
    And a big Thank you to Justin Warren. Now working at home and attending meetings can be a bit more exciting.

  21. Hi,

    I have an error at this part:
    cmake -DLIBOBS_INCLUDE_DIR=”../../obs-studio/libobs” -DCMAKE_INSTALL_PREFIX=/usr ..
    CMake Error: The source directory “/home/barney/myobscode” does not appear to contain CMakeLists.txt.
    Specify –help for usage, or press the help button on the CMake GUI.

    As I was looking online I tried the same command but with only 1 ‘dot’ instead of the 2 ‘dots’. This is what I got:
    cmake -DLIBOBS_INCLUDE_DIR=”../../obs-studio/libobs” -DCMAKE_INSTALL_PREFIX=/usr .
    CMake Error at external/FindLibObs.cmake:98 (include):
    include could not find load file:

    /home/barney/obs-studio/libobs/../cmake/external/ObsPluginHelpers.cmake
    Call Stack (most recent call first):
    CMakeLists.txt:5 (include)

    — Configuring incomplete, errors occurred!
    See also “/home/barney/myobscode/obs-v4l2sink/CMakeFiles/CMakeOutput.log”.

    Can anyone help? I have no experience in coding. I am trying to this on Ubuntu 16.04 LTS.

  22. Hi Justin,
    By chance i get here to see this post, i don’t quite understand the details of all this process but i got it you’re one expert on obs&zoom, now i have a issue on how to streaming a zoom meeting to a 3rd cdn platform. the zoom can add streaming url on its setting but that’s not good enough for streaming quality depending on your local bandwidth.. i once saw someone streaming a zoom meeting seemingly by some applications installed on clouds to pull stream from zoom meeting, then pushing it to cdn node.. maybe you can make some recommendations for this . thanks in advance

  23. This is going well beyond what I know anything about, sorry.

    Maybe take a look at Restream? It looks like they support what you’re trying to do: https://support.restream.io/en/articles/3314278-how-to-connect-zoom-with-restream

  24. It sounds like you might be running the command from the wrong directory?

    Go into the directory you’d run this cmake command from. What’s the output of pwd?

  25. Christopher Donham

    I followed along with your instructions for video and was successful — thanks very much.

    Have you done a write-up about how to hookup the audio as well? I am a teacher using OBS as a front end to Zoom for teaching, and need to be able to play pre-recorded videos as part of my presentation. This means I need the audio multiplexing in OBS in addition to the video multiplexing.

  26. Hi Christopher! I’m glad you got it working.

    OBS seems to use system audio inputs pretty well, but I’ve not delved into it in detail, sorry. Audio is a whole messy thing all its own that varies a lot by platform.

    My setup uses PulseAudio (because Ubuntu) and jackd (for Ardour DAW and USB mic sources via a Zoom H6) for microphone input routing, but I’ve not managed to get very far with application audio output routing. They all (mostly) send output to PulseAudio, which only appears as a single source in jackd. I’ve not figured out how to make the system apps use jackd directly so they can get routed manually, and since don’t have a specific need it hasn’t been a priority for me.

    Sorry I can’t be of more help there. If you do find something, I’d be interested to hear about it, though!

  27. Christopher Donham

    I’ve spent a day poking at this and have an ok, but not great solution. You can create a virtual device that OBS can write to and Zoom can read as follows:

    pactl load-module module-null-sink sink_name=Virtual-Speaker sink_properties=device.description=Virtual-Speaker

    pactl load-module module-remap-source source_name=Remap-Source master=Virtual-Speaker.monitor

    In OBS, set the Settings->Advanced->Monitoring Device to “Monitor of Virtual-Speaker”.

    In Zoom, set the microphone to the “Remapped Monitor of Virtual-Speaker”.

    With this setup, you can hear the OBS output in Zoom. This means that if you play a video, for example, you get both the audio and video available on Zoom. The problem is that the microphone has latency with respect to the video (so not the audio track that accompanies the video — the microphone so that any commentary you say over the video is delayed).

    Make sure that you turn “Monitoring” on for each of the audio sources in OBS.

    I think the delay is because I am using the “Monitoring” output. I am guessing that a better solution would be to merge the microphone input with the OBS output stream in pactl, but this is currently beyond my limited understanding of pactl.

  28. I followed your steps. Works perfectly, except that my camera picture has deteriorated. It is now “grainy”.

    I reverted all steps, but could not get my previous video quality back. I guess some settings have changed during this process, but I am not able to fix it.

    Any advice highly appreciated!

    Thanks
    Ben

  29. Occasionally something similar happens with my webcam. I’ve found unplugging it and then plugging it back in seems to reset it and clear the problem. Maybe give that a try?

  30. For those who what to make the modeprobe permanent, there are some useful instructions at https://askubuntu.com/questions/1245212/how-do-i-automatically-run-modprobe-v4l2loopback-on-boot

  31. Unfortunately, it’s a build in webcam.

  32. Thank you very much for this article! Very helpful.

  33. I followed the instructions listed on the website and found out that the plugin file (v4l2sink.so) is installed in the myobscode/obs-v4l2sink/build directory created during the process described here. Unfortunately, OBS-Studio doesn’t recognize the file in that location. OBS-Plugins reside in usr/lib/x86_64-linux-gnu/obs-plugins/ (check package manager properties for OBS-Plugins package if you have a different version). Copied the v4l2sink.so file to the referenced directory and it works perfectly

  34. I was progressing through your instructions on Ubuntu 18.04. When I attempted to execute:
    $ sudo modprobe v4l2loopback video_nr=3 card_label=”OBS Video Source” exclusive_caps=1
    I received the following error:
    modprobe: ERROR: could not insert ‘v4l2loopback’: Bad address

    Would you give me some clue as to what I need to fix?
    Dan

  35. Not sure, Dan, sorry.

    You could try to reinstall the v4l2loopback driver with something like:

    sudo apt install –reinstall v4l2loopback-dkms

    and then see if the modprobe succeeds? If not, check out the output from
    dmesg
    and see if there’s any more information about what’s causing the error in the system logs.

  36. I did this with Microsoft Teams as well. I had to change my Video – Output (Scaled) Resolution down to 1280×720 for Teams to recognize the input. The OBS Source wasn’t listed with my default of 1920×1080.

  37. Success! Thank you, so much!
    VERY Helpful; so much easier to follow than others I had seen.
    Great work! Two Thumbs Up… more if I had them.

Comments are closed