2020-05-26:

Timer / Text Overlay On Webcam Video

Zoom / Webex / Hangouts Teleconferencing

Table of Contents

Problem

There's no way to show information in most videoconferencing apps like Zoom, Webex, Hangouts and so forth, without sharing an entire screen.

That means that background information, such as a running timer, is not an easy thing to have.

This is particularly an issue for me because I have been playing a bunch of Werewolf online using teleconferencing apps like Zoom, and we need to be able to keep time for everyone. I presume that other video conference organizers for classes, toastmasters and so forth have similar problems.


Example timer "webcam" in top left

So we have two solutions for Linux, a Windows solution, and possible Mac OSX solutions. Take your pick below!

Linux Solutions

Linux barebones command-line solution
This is a command-line only solution that is simple and lightweight and requires less installs. The main drawback is that it uses the ffmpeg drawtext overlay which sometimes crashes, but there's a fix for that below.
Linux with OBS Studio
A GUI solution that uses OBS Studio which is free, but requires having a GUI running while you are using the webcam but has much more power for layout and controlling what appears in your webcam.
Both options have different requirements: (full install instructions below)

Linux Barebones Solution Requirements:

Linux GUI/OBS Solution Requirements:

Both linux solutions require v4l2loopback, so the install instructions are here:

  1. Install v4l2loopback. You need the current build (as of 2020-05-26) because the v0.11.0 and prior packages have a bug and none of this will work.
      sudo apt-get remove v4l2loopback-dkms
      sudo apt-get install build-essential libelf-dev linux-headers-$(uname -r) unzip
      wget https://github.com/umlaeute/v4l2loopback/archive/master.zip
      unzip master.zip
      cd v4l2loopback-master
      make
      sudo make install
      sudo depmod -a
  2. Edit /etc/modprobe.d/v4l2loopback.conf so you can specify the loopback device so that adding/removing cameras is less likely to break things. Add:
      options v4l2loopback video_nr=10 card_label="virtualCam"

Also - if you want to run a timer, I have a simple timer script that I wrote that can control and run a timer, putting it's output into /tmp/timer.txt which can then be read as a text source by either ffmpeg or OBS. So you'd need that script as well (and to install the 'ruby' language if somehow your linux install doesn't have it already) and then run that from the command-line. OBS also has some crude timer scripts, but they are difficult to control once started.

Linux Barebones

There are two text solutions, one for overlaying the text information and/or timer on your own webcam, and another one for creating a separate webcam that can also join the meeting as a separate participant.

Steps

  1. Install v4l2loopback as described in "Linux Solutions" above
  2. Create a text file ("/tmp/timer.txt" or as specified in the ffmpeg command below) or run a timer app that updates a file with timer info. I whipped together a ruby script timer that suits my needs and is fairly general purpose (and supports two timers)

  3. Run ffmpeg so that it creates the virtual webcam. Two options:
    1. Separate webcam with it's own timer: (Set to 5fps since that's good enough for a timer)
        ffmpeg -f lavfi -re -i color=size=640x480:rate=5:color=black \
          -vf "drawtext=textfile=/tmp/timer.txt:fontcolor=red:fontsize=80:x=(W-text_w)/2:y=30:reload=1:borderw=3:bordercolor=white" \
          -map 0:v -f v4l2 -pix_fmt yuyv422 /dev/video10
    2. Text overlay on your actual webcam (using /dev/video0 in this case):
         ffmpeg -i /dev/video0 \
      	   -vf "drawtext=textfile=/tmp/timer.txt:fontcolor=red:fontsize=60:x=(W-text_w)/2:y=30:reload=1:borderw=3:bordercolor=white" \ -
      	   map 0:v -f v4l2 -pix_fmt yuyv422 /dev/video10
  4. I find that ffmpeg sometimes crashes, but you can just restart it, so I simply created a bash script that automatically restarts it, something like:
      while [ true ]; do
         <ffmpeg command from above>
      end
  5. Test it if you like:
    ffplay /dev/video10
    (type 'q' in the window to quit before the next step)

  6. Join the video conference! Select your virtual (/dev/video10) webcam. If you are doing it as a separate webcam as opposed to an overlay on your webcam, then just open another browser and cancel launching the app and choose "join from your browser" Once you've joined and picked the virtual timer camera, under "... More" at the bottom select "Disable Video Receiving" so you don't unnecessarily download the conference twice, also be sure to not join audio in the other browser, else you will end up with an echo.

Linux Improvements/Settings

If you look at the ffmpeg command you will see there are many settings you can control, such as font color and size and the position of the text (that's the 'x=' and 'y=' and I've got the 'x=' set to an expression that centers the text, but you can just use pixel numbers). See the ffmpeg docs for the drawtext filter for more info.

You can set a fixed framerate for the virtual loopback device if it's not matching your webcam or set to what you want (ffplay can tell you what it's getting for a fps). For 30 fps:

v4l2-ctl -d /dev/video10 -p 30

If you want to force the capabilities of the virtual webcam, you can use:

v4l2loopback-ctl set-caps "video/x-raw,format=UYVY,width=640,height=480" /dev/video10

Linux with OBS Studio

OBS Studio is "Open Broadcaster Software" and is free to use streaming/recording platform that lets you mix video sources much like an audio mixer would let you mix audio. So you can "mix" your webcam and some text as an input and then output it to a virtual webcam.

Linux OBS Installation

Installation is somewhat involved. I'm on Ubuntu, and the package that you can install with apt-get is ancient (v0.1 vs v20 something!).
  1. Install v4l2loopback as described in "Linux Solutions" above
  2. Download and install OBS from source using the instructions at: https://obsproject.com/wiki/install-instructions#linux-build-directions
  3. Install plugin to get OBS virtual camera output

    This can be done from source of from the package - if you have issues with the package not working, remove it and try the source install.

    From package:
    1. Download: https://github.com/CatxFish/obs-v4l2sink/releases/download/0.1.0/obs-v4l2sink.deb
    2. sudo dpkg -i obs-v4l2sink.deb
    From source:
    	% sudo apt install libobs-dev qtbase5-dev cmake ffmpeg
    	# From the same directory where you have the OBS source (in 'obs-studio'):
    	% git clone https://github.com/CatxFish/obs-v4l2sink.git
    	% cd obs-v4l2sink
    	% cmake -DLIBOBS_INCLUDE_DIR="../obs-studio/libobs" -DCMAKE_INSTALL_PREFIX=/usr .
    	% make -j4
    	% sudo make install
  4. Setup OBS as shown below
  5. Create the virtual webcam output:
    Tools menu -> v4l2sink
    Use the device path of the virtual webcam as in the v4l2loopback install (/dev/video10 in our example) then click start
  6. Join the video conference! Select your virtual (/dev/video10) webcam

Windows with OBS Studio

OBS Studio is "Open Broadcaster Software" and is free to use streaming/recording platform that lets you mix video sources much like an audio mixer would let you mix audio. So you can "mix" your webcam and some text as an input and then output it to a virtual webcam.
  1. Download and install OBS Studio: https://obsproject.com/
  2. Download and install Virtual Cam to setup a virtual webcam: https://obsproject.com/forum/resources/obs-virtualcam.949/
  3. Setup OBS as shown below
  4. Join the video conference! Select your virtual webcam you created with Virtual Cam

Setup OBS (Linux/Windows/Mac?)

  1. Run OBS Studio: On linux, simply:
    % obs

    On Windows/Mac, run the application.
    If the auto-config wizard comes up, you can select "mostly for streaming", and then the default canvas, then use "temp" as the streaming key if you don't have one.
  2. Add your (real) webcam as a source:
    On the bottom in "Sources" box, click on "+" to add the webcam (on Linux this is a V4L2 source)
  3. Add the text as a source:
    Click on "Sources" -> "+" again to add text. If you want to use a timer, just add any text here and we'll explain the timer below.
  4. OPTIONALLY Use a timer. Pick one of a few possibilities:
    Simple option using command-line
    Use my timer script and run it (using ruby) from the command-line. Change the text source we added above so that it uses "read from file" and specify "/tmp/timer.txt" as the file

    More complex option using OBS/Gui
    Install the OBS plugin 'advanced timer':
    1. Download: https://github.com/cg2121/obs-advanced-timer/
    2. Find the "advanced-timer.lua" and install it:
      sudo cp advanced-timer.lua /usr/share/obs/obs-plugins/frontend-tools/scripts/
    3. Restart OBS
    4. Select "Tools" -> "Scripts"
    5. Click on '+' under "Loaded Scripts"
    6. Select the advanced-timer.lua file
    7. Click on "advanced-timer.lua" under "Loaded Scripts"
    8. Set the Countdown duration
    9. Select the "Text source" that has the name of your text source object you added above
    10. Click on Start/Stop to start and stop the timer. You will need to leave this window open to control/change the timer.

    Windows Only: Snaz plugin
    There's a Windows plugin for OBS called Snaz that I haven't tested, but you can find more info in this youtube video

Mac OSX Options

I have not tested or done much research on OSX, but there are likely a number of solutions. To consider:


Back to Solutions.

DaveSource.com - Dave's geek site GetDave.com - all the current Dave Pointers. MarginalHacks - I have an elegant script for that, but it's too small to fit in the margin.