Files
video-processing/README.md
2023-12-30 13:23:47 +01:00

9.9 KiB

Prerequisities

Install the collection of command line video4linux utilities

sudo apt-get install v4l-utils

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)

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

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

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?). 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

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

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 (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 the non-stop streaming

Adjust jrottenberg/ffmpeg:4.4-alpine if you want to use a specific ffmpeg version

sudo tee /etc/systemd/system/virt-garage-webcam-streamer.service <<EOF
[Unit]
Description=Garage Webcam Streamer service
Requires=docker.service
After=docker.service
DefaultDependencies=no

[Service]
Type=simple

Environment="HOME=/root"
Environment=WEBCAM_URI="rtsp://garagecam.virtonline.eu:554/live3.sdp"
Environment=PEERTUBE_LIVE="rtmp://peertube.virtonline.eu:1935/live/LIVE-STREAM-KEY"
Environment=FFMPEG="docker run --rm --name virt-garage-webcam-streamer jrottenberg/ffmpeg:4.4-alpine"

ExecStartPre=-/usr/bin/env sh -c '/usr/bin/env docker kill virt-garage-webcam-streamer 2>/dev/null || true'
ExecStartPre=-/usr/bin/env sh -c '/usr/bin/env docker rm virt-garage-webcam-streamer 2>/dev/null || true'

# Re-stream (Audio/Video) from IP camera to peertube live
ExecStart=/bin/bash -c '${FFMPEG} -loglevel error \
				-i ${WEBCAM_URI} \
				-c copy \
				-f flv \
				${PEERTUBE_LIVE}'

ExecStop=-/usr/bin/env sh -c '/usr/bin/env docker kill virt-garage-webcam-streamer 2>/dev/null || true'
ExecStop=-/usr/bin/env sh -c '/usr/bin/env docker rm virt-garage-webcam-streamer 2>/dev/null || true'
Restart=always
RestartSec=5
SyslogIdentifier=virt-garage-webcam-streamer

[Install]
WantedBy=multi-user.target
EOF

Reload systemd manager configuration

sudo systemctl daemon-reload

Enable the virt-garage-webcam-streamer service at boot time and also run it

sudo systemctl enable --now virt-garage-webcam-streamer

If it does not work check logs

journalctl -f -u virt-garage-webcam-streamer

Transcode and scale video file (and copy audio) using VAAPI (see 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 <option>=<value>