-
Notifications
You must be signed in to change notification settings - Fork 535
FFmpeg
Pushing in real time (-re
) a video test source to the /dev/video1
V4L2 device:
ffmpeg -re -i testsrc.avi -f v4l2 /dev/video1
To show a static image, you may need to set the output format: ffmpeg -loop 1 -re -i foo.jpg -f v4l2 -vcodec rawvideo -pix_fmt yuv420p /dev/video1
. Note that the -loop
parameter is named -stream_loop
in newer FFmpeg versions.
If you have an older FFmpeg version, you can rely on GStreamer: this is a dummy producer using GStreamer, forcing the format to I420 (i'm not sure whether this is needed, probably not)
gst-launch -v videotestsrc ! "video/x-raw-yuv,width=640,height=360,framerate=30/1,format=(fourcc)I420" ! v4l2sink device=/dev/video1
this encodes the v4l2loopback output into a flash video and writes it to /tmp/flash.flv
ffmpeg -f video4linux2 -s 640x360 -i /dev/video1 -r 30 -vcodec libx264 -vpre placebo -b 800k -coder 0 -g 2 -bf 0 -ab 64k -f flv /tmp/flash.flv
FFmpeg also comes with a basic video player, which can be used to view the loopback device's stream:
ffplay /dev/video1
Your boss wants you in a webex but you have no camera available, but a raspberrypi + camera module (CSI)? No problem. Build up a network webcam in a minute. With ffmpeg + v4l2loopback.
To stream the camera data (raw h264 stream, 1280x720 and 1MBit/s) over network just use the raspivid command:
raspivid -t 0 -hf -fps 30 -w 1280 -h 720 -b 1000000 -l -o tcp://0.0.0.0:5000
So, a tcp server is now ready to deliver our data. If you do not want to limit the h264 data bandwidth, just omit the -b parameter.
First, you need to get your /dev/video0 device up which is accepted by firefox:
modprobe v4l2loopback devices=1 max_buffers=2 exclusive_caps=1 card_label="VirtualCam #0"
Be sure to run this command as root. Otherwise no kernel module can be loaded.
Now comes the final step. We will receive the stream from network and writing it into the /dev/video0 device:
ffmpeg -f h264 -i tcp://RASPICAM:5000 -f v4l2 -pix_fmt yuv420p /dev/video0
Set RASPICAM to your hostname/ip of the raspberrypi with the camera.
To offload h264 graphics decoding to your graphics card via VDPAU you can do this:
ffmpeg -f h264 -hwaccel vdpau -i tcp://goldeneye:5000 -f v4l2 -pix_fmt yuv420p /dev/video0
Your graphics card will now do the hard work. Check in top/htop if you have less load on your ffmpeg task.
For me this works with both firefox (74.0.1 (64-bit)) and chromium (80.0.3987.149 (Official Build) Arch Linux (64-Bit)). To test if the virtual webcam is working in your browser, you can use https://webcamtests.com. By the time of writing there are no browsers available for linux which are doing accelerated video encoding. They (firefox, chromium) use a browser extension named openh264 from Cisco which is doing the h264 encoding in software. Additionally it looks like it is not possible to pass the raw h264 stream from the raspberrypi into the WebRTC framework.
Similar to the RPI above also an Android device can be used a source for a network stream. Install IP Webcam and start it. Then you can connect to the IP address on port 8080:
ffmpeg -i http://<Android-IP>:8080/video -vf format=yuv420p -f v4l2 /dev/video0
Depending on the network connection, the IP Webcam might have a lot of latency an be quite choppy. If you activate ADB on the device, it is possible to tunnel the IP Webcam stream over a USB cable, which provides a more stable connection:
adb wait-for-usb-device && adb forward tcp:8080 tcp:8080 && ffmpeg -i http://127.0.0.1:8080/video -vf format=yuv420p -f v4l2 /dev/video0
Search online how to enable ADB for your specific Android version. Use adb devices -l
to check for connected ADB devices.
If you are running X11 you can also use FFmpeg to to select a region on the screen and then stream it to a v4l2 device (ffmpeg version needs to be somewhat recent):
ffmpeg -f x11grab -select_region 1 -show_region 1 -framerate 25 -i $DISPLAY -vf format=yuv420p -f v4l2 /dev/video0