Skip to content

Instantly share code, notes, and snippets.

@catrielmuller
Last active June 17, 2025 14:01
Show Gist options
  • Save catrielmuller/71ae055871893d289476ee570fd953d8 to your computer and use it in GitHub Desktop.
Save catrielmuller/71ae055871893d289476ee570fd953d8 to your computer and use it in GitHub Desktop.
ArchLinux ElGato FaceCam - Chrome V4L2Loopback

ArchLinux ElGato FaceCam - Chrome V4L2Loopback

IMPORTANT

This is not required any more, you need upgrade your firmware to the version +4.09 using ElGato Cammera Hub

https://help.elgato.com/hc/en-us/articles/4406041241997-Elgato-Facecam-Firmware-Update

Changes in firmware 4.09

  • Added MJPEG as a fallback video format. MJPEG requires less USB bandwidth and improves compatibility with programs that cannot handle uncompressed video.

Loopback Config

I'm creating 3 Loopback devices, if you only need do this for the Facecam you can define only one like this:

options v4l2loopback video_nr=11 card_label="ElGato FaceCam"

WebCam Path

I'm using my serial as a path to not conflict with my another input devices /dev/v4l/by-id/usb-Elgato_Elgato_Facecam_FW42K1A07115-video-index0 on the facecam-init.sh.

You can check what is your correct path with this command:

ls /dev/v4l/by-id/

WebCam Config

On my facecam-init.sh, I set some parameters that make sense for my enviroment, this maybe cannot fit for you, so you can remove this line.

v4l2-ctl -d /dev/v4l/by-id/usb-Elgato_Elgato_Facecam_FW42K1A07115-video-index0 --set-ctrl="brightness=180,contrast=3,saturation=35,white_balance_temperature_auto=1,power_line_frequency=2,sharpness=1,exposure_auto=2,zoom_absolute=5"

or adjust the parameters that you want.

Run

You need start the script to create the pipe from the FaceCam Device to the LoopBack Virtual Device

  • Add execution permissions:
chmod +x facecam-init.sh
  • Run
./facecam-init.sh
#!/bin/bash
v4l2-ctl -d /dev/v4l/by-id/usb-Elgato_Elgato_Facecam_FW42K1A07115-video-index0 --set-ctrl="brightness=180,contrast=3,saturation=35,white_balance_temperature_auto=1,power_line_frequency=2,sharpness=1,exposure_auto=2,zoom_absolute=5"
ffmpeg -f v4l2 -input_format uyvy422 -framerate 60 -video_size 1920x1080 -i /dev/v4l/by-id/usb-Elgato_Elgato_Facecam_FW42K1A07115-video-index0 -pix_fmt yuyv422 -f v4l2 /dev/video11
# /etc/modules-load.d/v4l2loopback.conf
v4l2loopback
# /etc/modprobe.d/v4l2loopback.conf
options v4l2loopback video_nr=10,11,12 card_label="OBS Virtual","ElGato FaceCam","V4L2Loopback" exclusive_caps=1,1,1
@catrielmuller
Copy link
Author

Is this working consistently for you folks? I'm using obs-studio and its virtual camera, but while it works for a while (and needs an occassional usbreset between sessions), it still hangs/freezes mid-stream. I can't get it to work for an extended period of time. This is regardless if using MJPEG, or the frame rate, etc.

I been using the camera with the new firmware consistently (Without this script) , however as @kouak mention sometimes the camera don't show up on boot (a quick disconnect and connect fix the issue). I think that happen because the cam have in the firmware some logic to detect if is connected to usb2 and show the device as something like "Connect this in a USB 3.0 port".

@farnoy
Copy link

farnoy commented Jan 30, 2025

I'll check out the v4l2loopback method then. I'm already on the latest firmware but maybe this is some interaction with obs-studio.

@farnoy
Copy link

farnoy commented Jun 17, 2025

I have up to date firmware but the camera cuts out, once you stop recording, no other app can get a stream working.

I tried this method, and it looks like this on my end:

# modprobe.conf
options v4l2loopback devices=1 video_nr=1 card_label="OBS Cam" exclusive_caps=1

These are options from the obs setup but OBS is not running to I tried to repurpose /dev/video1:

$ ffmpeg -f v4l2 -input_format uyvy422 -framerate 60 -video_size 1920x1080 -i /dev/v4l/by-id/usb-Elgato_Elgato_Facecam_FW49K1A04697-video-index0 -pix_fmt yuyv422 -f v4l2 /dev/video1
ffmpeg version 7.1.1 Copyright (c) 2000-2025 the FFmpeg developers
  built with gcc 14.2.1 (GCC) 20250322
  configuration: --disable-static --prefix=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-ffmpeg-7.1.1 --target_os=linux --arch=x86_64 --pkg-config=pkg-config --enable-gpl --enable-version3 --disable-nonfree --disable-static --enable-shared --enable-pic --disable-thumb --disable-small --enable-runtime-cpudetect --disable-gray --enable-swscale-alpha --enable-hardcoded-tables --enable-safe-bitstream-reader --enable-pthreads --disable-w32threads --disable-os2threads --enable-network --enable-pixelutils --datadir=/nix/store/nbs8kinkznw795sbw5mabfn1980hjr8w-ffmpeg-7.1.1-data/share/ffmpeg --enable-ffmpeg --enable-ffplay --enable-ffprobe --bindir=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-ffmpeg-7.1.1-bin/bin --enable-avcodec --enable-avdevice --enable-avfilter --enable-avformat --enable-avutil --enable-postproc --enable-swresample --enable-swscale --libdir=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-ffmpeg-7.1.1-lib/lib --incdir=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-ffmpeg-7.1.1-dev/include --enable-doc --enable-htmlpages --enable-manpages --mandir=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-ffmpeg-7.1.1-man/share/man --enable-podpages --enable-txtpages --docdir=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-ffmpeg-7.1.1-doc/share/doc/ffmpeg --enable-alsa --enable-amf --enable-libaom --disable-libaribb24 --disable-libaribcaption --enable-libass --disable-avisynth --enable-libbluray --disable-libbs2b --enable-bzlib --disable-libcaca --disable-libcdio --disable-libcelt --disable-chromaprint --disable-libcodec2 --disable-cuda --enable-cuda-llvm --disable-cuda-nvcc --enable-cuvid --enable-libdav1d --disable-libdc1394 --enable-libdrm --disable-libdvdnav --disable-libdvdread --disable-libfdk-aac --enable-ffnvcodec --disable-libflite --enable-fontconfig --enable-libfontconfig --enable-libfreetype --disable-frei0r --enable-libfribidi --disable-libgme --enable-gnutls --disable-libgsm --enable-libharfbuzz --enable-iconv --disable-libilbc --disable-libjack --disable-libjxl --disable-libkvazaar --disable-ladspa --disable-liblc3 --disable-liblcevc-dec --disable-lcms2 --enable-lzma --disable-metal --disable-libmfx --disable-libmodplug --enable-libmp3lame --disable-libmysofa --disable-libnpp --enable-nvdec --enable-nvenc --disable-openal --enable-opencl --disable-libopencore-amrnb --disable-libopencore-amrwb --disable-opengl --disable-libopenh264 --enable-libopenjpeg --enable-libopenmpt --enable-libopus --disable-libplacebo --enable-libpulse --disable-libqrencode --disable-libquirc --disable-librav1e --enable-librist --disable-librtmp --disable-librubberband --disable-libsmbclient --enable-sdl2 --disable-libshaderc --disable-libshine --disable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --disable-librsvg --enable-libsvtav1 --disable-libtensorflow --enable-libtheora --disable-libtwolame --enable-libv4l2 --enable-v4l2-m2m --enable-vaapi --enable-vdpau --disable-libvpl --enable-libvidstab --disable-libvmaf --disable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-vulkan --disable-libvvenc --enable-libwebp --enable-libx264 --enable-libx265 --disable-libxavs --disable-libxcb --disable-libxcb-shape --disable-libxcb-shm --disable-libxcb-xfixes --disable-libxevd --disable-libxeve --disable-xlib --enable-libxml2 --enable-libxvid --enable-libzimg --enable-zlib --disable-libzmq --enable-libzvbi --disable-debug --enable-optimizations --disable-extra-warnings --disable-stripping
  libavutil      59. 39.100 / 59. 39.100
  libavcodec     61. 19.101 / 61. 19.101
  libavformat    61.  7.100 / 61.  7.100
  libavdevice    61.  3.100 / 61.  3.100
  libavfilter    10.  4.100 / 10.  4.100
  libswscale      8.  3.100 /  8.  3.100
  libswresample   5.  3.100 /  5.  3.100
  libpostproc    58.  3.100 / 58.  3.100
# HANGS AT THIS POINT
# I have to CTRL+c just to get it to continue
Input #0, video4linux2,v4l2, from '/dev/v4l/by-id/usb-Elgato_Elgato_Facecam_FW49K1A04697-video-index0':
  Duration: N/A, bitrate: 1990656 kb/s
  Stream #0:0: Video: rawvideo (UYVY / 0x59565955), uyvy422, 1920x1080, 1990656 kb/s, 60 fps, 60 tbr, 1000k tbn
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> rawvideo (native))
Press [q] to stop, [?] for help
# also hangs here, the only thing that kills it is ctrl+c three times

hangs in the two places I described.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment