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.
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:
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.
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.
Now you can explore the fun video effects and scene switching capabilities of OBS Studio!
Pingback: Remote Work Makes Us All Content Creators - Gestalt IT
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
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:
Try this:
apt install --reinstall gcc g++
and then try running cmake again.
Hi Justin,
Why does this procedure need a paid Zoom account?
Thanks.
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.
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.
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.
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.
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.
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.
@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 :)
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.
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.
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
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/
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”.
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.
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
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
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.
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.
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
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
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 ofpwd
?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.
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!
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.
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
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?
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
Unfortunately, it’s a build in webcam.
Thank you very much for this article! Very helpful.
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
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
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.
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.
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.