Prerequisities -------------- Update the Raspberry Pi OS > `sudo apt update` `sudo apt full-upgrade` Install the collection of command line video4linux utilities > `sudo apt install v4l-utils ffmpeg` Lists all available cameras > `v4l2-ctl --list-devices` ``` USB Video device: USB Camera (usb-0000:01:00.0-1.1.4): /dev/video0 /dev/video1 ``` List available formats for your camera `/dev/video0` (e.g. [Logitech QuickCam Pro 9000](https://download01.logitech.com/support/25174.1.0.pdf)) > `v4l2-ctl -d /dev/video0 --list-formats-ext` ``` ioctl: VIDIOC_ENUM_FMT Type: Video Capture [0]: 'MJPG' (Motion-JPEG, compressed) Size: Discrete 640x480 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 800x600 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 960x720 Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) [1]: 'YUYV' (YUYV 4:2:2) Size: Discrete 640x480 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 800x600 Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 960x720 Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 1600x1200 Interval: Discrete 0.200s (5.000 fps) ``` Or using ffmpeg > `ffmpeg -hide_banner -f v4l2 -list_formats all -i /dev/video0` ``` Compressed: mjpeg : Motion-JPEG : 160x120 176x144 320x240 352x288 640x480 800x600 960x720 Raw : yuyv422 : YUYV 4:2:2 : 160x120 176x144 320x240 352x288 640x480 800x600 960x720 1600x1200 ``` Record a video > `ffmpeg -f v4l2 -input_format h264 -video_size 1920x1080 -framerate 30 -i /dev/video0 -vcodec copy video.mp4` Live Streaming -------------- Use you own `LIVE-STREAM-KEY` and run ### Live stream camera to peertube > `ffmpeg -hide_banner -f v4l2 -framerate 15 -video_size 1600x1200 -input_format yuyv422 -i /dev/video0 -vcodec libx264 -tune zerolatency -b:v 1M -maxrate 1M -bufsize 2M -f flv rtmp://peertube.virtonline.eu:1935/live/LIVE-STREAM-KEY` ### Live stream desktop to peertube Note: Does not work on Waylad ([What is Wayland in Linux Distros and Should You Use it?](https://www.ubuntupit.com/what-is-wayland-in-linux-distros-and-should-you-use-it/)). You can quickly check whether you're using X or Wayland `echo $XDG_SESSION_TYPE` > `DISPLAY=:0 ffmpeg -hide_banner -f x11grab -framerate 5 -video_size 830x630 -i :0.0+50,95 -vf format=pix_fmts=yuv420p -vcodec libx264 -tune zerolatency -preset veryfast -f flv rtmp://peertube.virtonline.eu:1935/live/LIVE-STREAM-KEY` ### Live stream camera with sound and desktop as an overlay to peertube Lists all available audio recording devices > `arecord -l` ``` **** List of CAPTURE Hardware Devices **** card 1: Q9000 [QuickCam Pro 9000], device 0: USB Audio [USB Audio] Subdevices: 1/1 Subdevice #0: subdevice #0 ``` > `DISPLAY=:0` # select display (only if run remotely e.g. ssh) `ffmpeg -hide_banner` # do not output compile flags `-thread_queue_size 4096 -f pulse -ac 2 -i default` # audio input from PulseAudio `-thread_queue_size 512 -f v4l2 -framerate 5 -video_size 1600x1200 -input_format yuyv422 -i /dev/video0` # camera input `-thread_queue_size 512 -f x11grab -framerate 5 -video_size 830x630 -i :0.0+50,95` # 830x630 window from screen 0 with offset 50,95 `-filter_complex 'overlay=main_w-overlay_w:main_h-overlay_h'` # picture-in-picture `-c:v libx264 -tune zerolatency -preset ultrafast -b:v 1M -maxrate 1M -bufsize 2M` # output video codec `-c:a aac -b:a 64k` # output audio codec `-f flv` # output container `rtmp://peertube.virtonline.eu:1935/live/LIVE-STREAM-KEY` # peertube streaming url ### Live stream white text on black background [ffmpeg create blank screen with text video](https://stackoverflow.com/questions/22710099/ffmpeg-create-blank-screen-with-text-video) > `ffmpeg -hide_banner -f lavfi -i color=size=320x240:rate=25:color=black -vf "drawtext=fontfile=/usr/share/fonts/truetype/freefont/FreeSans.ttf:fontsize=30:fontcolor=white:x=(w-text_w)/2:y=(h-text_h)/2:text='Stream začne čoskoro...'" -vcodec libx264 -preset slow -f flv rtmp://peertube.virtonline.eu:1935/live/LIVE-STREAM-KEY` ### Live stream camera using h.264 hardware acceleration [VAAPI](https://trac.ffmpeg.org/wiki/Hardware/VAAPI) (e.g. on Intel iGPU) Use the dockerized ffmpeg with precompiled vaapi support, adjust `/dev/video2` > `alias ffmpeg='docker run --rm -w $(pwd) -v $(pwd):$(pwd) --device=/dev/dri --device=/dev/video2 jrottenberg/ffmpeg:vaapi'` Adjust `/dev/video2`, `-video_size 1920x1080 -framerate 60` and stream to peertube (if it can handle that much) > `ffmpeg -hide_banner -y -f v4l2 -input_format mjpeg -video_size 1920x1080 -framerate 60 -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi -i /dev/video2 -vf 'scale_vaapi=format=nv12' -c:v h264_vaapi -b:v 10M -f flv rtmp://peertube.virtonline.eu:1935/live/LIVE-STREAM-KEY` ### Setup a systemd service for a non-stop streaming ``` sudo tee /etc/systemd/system/webcam-streamer.service </dev/null || true' ExecStart=/bin/bash -c 'ffmpeg -loglevel error \ -f v4l2 -input_format h264 \ -video_size 1920x1080 \ -framerate 20 \ -i /dev/video0 \ -c copy -f flv \ -tune zerolatency \ ${PEERTUBE_LIVE}' ExecStop=-/usr/bin/env sh -c 'killall ffmpeg 2>/dev/null || true' Restart=always RestartSec=5 SyslogIdentifier=webcam-streamer [Install] WantedBy=multi-user.target EOF ``` Reload systemd manager configuration `sudo systemctl daemon-reload` Start the service `sudo systemctl start webcam-streamer` If it does not work check logs `journalctl -f -u webcam-streamer` Enable the webcam-streamer service at boot time `sudo systemctl enable webcam-streamer` ### Transcode and scale video file (and copy audio) using VAAPI (see [HWAccelIntro](https://trac.ffmpeg.org/wiki/HWAccelIntro)) > `alias ffmpeg='docker run --rm -w $(pwd) -v $(pwd):$(pwd) --device=/dev/dri jrottenberg/ffmpeg:vaapi'` > `ffmpeg -y -hide_banner -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi -i 'https://github.com/bower-media-samples/big-buck-bunny-1080p-60fps-30s/raw/master/video.mp4' -c:v h264_vaapi -vf 'fps=60,scale_vaapi=w=1280:h=-2:format=nv12' -c:a copy -f mp4 big-buck-bunny-720p-60fps-30s-h264_vaapi.mp4` See iGPU load while transcoding > `sudo apt install intel-gpu-tools` > `sudo intel_gpu_top` ``` intel-gpu-top: Intel Skylake (Gen9) @ /dev/dri/card0 - 0/ 0 MHz; 100% RC6; 0.00/ 2.40 W; 0 irqs/s IMC reads: 166 MiB/s IMC writes: 30 MiB/s ENGINES BUSY MI_SEMA MI_WAIT Render/3D 0.00% | | 0% 0% Blitter 0.00% | | 0% 0% Video 0.00% | | 0% 0% VideoEnhance 0.00% | | 0% 0% ``` Adjusting camera functions -------------------------- Brightness, zoom, focus, etc, can be adjusted > `v4l2-ctl -L` ``` brightness 0x00980900 (int) : min=-64 max=64 step=1 default=0 value=0 contrast 0x00980901 (int) : min=0 max=95 step=1 default=0 value=0 saturation 0x00980902 (int) : min=0 max=100 step=1 default=64 value=64 hue 0x00980903 (int) : min=-2000 max=2000 step=1 default=0 value=0 white_balance_temperature_auto 0x0098090c (bool) : default=1 value=1 gamma 0x00980910 (int) : min=100 max=300 step=1 default=100 value=100 power_line_frequency 0x00980918 (menu) : min=0 max=2 default=1 value=1 0: Disabled 1: 50 Hz 2: 60 Hz white_balance_temperature 0x0098091a (int) : min=2800 max=6500 step=10 default=4600 value=4600 flags=inactive sharpness 0x0098091b (int) : min=1 max=7 step=1 default=2 value=2 backlight_compensation 0x0098091c (int) : min=0 max=1 step=1 default=0 value=0 exposure_auto 0x009a0901 (menu) : min=0 max=3 default=3 value=3 1: Manual Mode 3: Aperture Priority Mode exposure_auto_priority 0x009a0903 (bool) : default=0 value=1 ``` Then adjust the value > `v4l2-ctl -c