292 lines
14 KiB
Markdown
292 lines
14 KiB
Markdown
|
|
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`
|
|
|
|
### Stream IP camera to peertube live
|
|
> `ffmpeg -loglevel error -i rtsp://garagecam.virtonline.eu:554/live3.sdp -c copy -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)
|
|
See supported codecs by the generation of the Intel CPU: [Intel Quick Sync Video](https://en.wikipedia.org/wiki/Intel_Quick_Sync_Video#Hardware_decoding_and_encoding)
|
|
Check your GPU
|
|
> `sudo lshw -C display`
|
|
```
|
|
*-display
|
|
description: VGA compatible controller
|
|
product: Skylake GT2 [HD Graphics 520]
|
|
vendor: Intel Corporation
|
|
physical id: 2
|
|
bus info: pci@0000:00:02.0
|
|
version: 07
|
|
width: 64 bits
|
|
clock: 33MHz
|
|
capabilities: pciexpress msi pm vga_controller bus_master cap_list rom
|
|
configuration: driver=i915 latency=0
|
|
resources: irq:134 memory:de000000-deffffff memory:c0000000-cfffffff ioport:f000(size=64) memory:c0000-dffff
|
|
```
|
|
Find out which codecs are supported by your GPU
|
|
> `docker run --rm -it --device=/dev/dri akashisn/vainfo`
|
|
```
|
|
Trying display: drm
|
|
libva info: VA-API version 1.19.0
|
|
libva info: User environment variable requested driver 'iHD'
|
|
libva info: Trying to open /usr/local/lib/dri/iHD_drv_video.so
|
|
libva info: Found init function __vaDriverInit_1_19
|
|
libva info: va_openDriver() returns 0
|
|
vainfo: VA-API version: 1.19 (libva 2.19.0)
|
|
vainfo: Driver version: Intel iHD driver for Intel(R) Gen Graphics - 23.3.3 (1c13afa)
|
|
vainfo: Supported profile and entrypoints
|
|
VAProfileNone : VAEntrypointVideoProc
|
|
VAProfileNone : VAEntrypointStats
|
|
VAProfileMPEG2Simple : VAEntrypointVLD
|
|
VAProfileMPEG2Simple : VAEntrypointEncSlice
|
|
VAProfileMPEG2Main : VAEntrypointVLD
|
|
VAProfileMPEG2Main : VAEntrypointEncSlice
|
|
VAProfileH264Main : VAEntrypointVLD
|
|
VAProfileH264Main : VAEntrypointEncSlice
|
|
VAProfileH264Main : VAEntrypointFEI
|
|
VAProfileH264Main : VAEntrypointEncSliceLP
|
|
VAProfileH264High : VAEntrypointVLD
|
|
VAProfileH264High : VAEntrypointEncSlice
|
|
VAProfileH264High : VAEntrypointFEI
|
|
VAProfileH264High : VAEntrypointEncSliceLP
|
|
VAProfileVC1Simple : VAEntrypointVLD
|
|
VAProfileVC1Main : VAEntrypointVLD
|
|
VAProfileVC1Advanced : VAEntrypointVLD
|
|
VAProfileJPEGBaseline : VAEntrypointVLD
|
|
VAProfileJPEGBaseline : VAEntrypointEncPicture
|
|
VAProfileH264ConstrainedBaseline: VAEntrypointVLD
|
|
VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
|
|
VAProfileH264ConstrainedBaseline: VAEntrypointFEI
|
|
VAProfileH264ConstrainedBaseline: VAEntrypointEncSliceLP
|
|
VAProfileVP8Version0_3 : VAEntrypointVLD
|
|
VAProfileVP8Version0_3 : VAEntrypointEncSlice
|
|
VAProfileHEVCMain : VAEntrypointVLD
|
|
VAProfileHEVCMain : VAEntrypointEncSlice
|
|
VAProfileHEVCMain : VAEntrypointFEI
|
|
```
|
|
- `VAEntrypointEncSlice` Can encode
|
|
- `VAEntrypointVLD` Can decode
|
|
|
|
Or install natively
|
|
> `sudo apt install vainfo`
|
|
`vainfo`
|
|
|
|
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`
|
|
|
|
For the 'bookworm' version of Raspberry OS usig rpicam-vid with the silent audio stream
|
|
|
|
> `rpicam-vid --inline --nopreview -t 0 --width 640 --height 480 --framerate 15 --bitrate 500000 --codec h264 -o - | ffmpeg -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100 -thread_queue_size 1024 -use_wallclock_as_timestamps 1 -i pipe:0 -c:v copy -c:a aac -preset fast -strict experimental -f flv rtmp://peertube.virtonline.eu:1935/live/LIVE-STREAM-KEY`
|
|
|
|
### Setup a systemd service for a non-stop streaming
|
|
Adapt VIDEO_BITRATE="3500000" to your max network upload speed
|
|
```
|
|
sudo nano /etc/systemd/system/webcam-streamer.service
|
|
[Unit]
|
|
Description=Webcam Streamer service
|
|
Requires=network-online.target
|
|
After=network-online.target
|
|
DefaultDependencies=no
|
|
|
|
[Service]
|
|
Type=simple
|
|
|
|
Environment="HOME=/root"
|
|
Environment=PEERTUBE_LIVE="rtmp://peertube.virtonline.eu:1935/live/LIVE-STREAM-KEY"
|
|
Environment=VIDEO_DEVICE="/dev/video0"
|
|
Environment=VIDEO_CODEC="h264"
|
|
Environment=VIDEO_BITRATE="3500000"
|
|
Environment=VIDEO_RESOLUTION="1920x1080"
|
|
Environment=VIDEO_FRAMERATE="30"
|
|
|
|
ExecStartPre=-/usr/bin/env sh -c 'killall ffmpeg 2>/dev/null || true'
|
|
ExecStartPre=-/usr/bin/env sh -c 'v4l2-ctl -d ${VIDEO_DEVICE} -c video_bitrate=${VIDEO_BITRATE}'
|
|
|
|
ExecStart=/bin/bash -c 'ffmpeg -loglevel error \
|
|
-f v4l2 \
|
|
-input_format ${VIDEO_CODEC} \
|
|
-video_size ${VIDEO_RESOLUTION} \
|
|
-framerate ${VIDEO_FRAMERATE} \
|
|
-i ${VIDEO_DEVICE} \
|
|
-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
|
|
```
|
|
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 <option>=<value>`
|
|
|
|
Ingrease GPU memory. Select "7 Advanced Options", then "A3 Memory Split", select "256" and press Return key, go to finish, and select to reboot.
|
|
> `sudo raspi-config`
|
|
|
|
See used GPU memory
|
|
> `sudo vcdbg reloc` |