install go2rtc on bob

This commit is contained in:
2026-04-04 19:36:14 +02:00
parent f0b56e63d1
commit ccf88187b8
537 changed files with 69213 additions and 0 deletions
@@ -0,0 +1,41 @@
# Video4Linux
[`new in v1.9.9`](https://github.com/AlexxIT/go2rtc/releases/tag/v1.9.9)
What you should to know about [V4L2](https://en.wikipedia.org/wiki/Video4Linux):
- V4L2 (Video for Linux API version 2) works only in Linux
- supports USB cameras and other similar devices
- one device can only be connected to one software simultaneously
- cameras support a fixed list of formats, resolutions and frame rates
- basic cameras supports only RAW (non-compressed) pixel formats
- regular cameras supports MJPEG format (series of JPEG frames)
- advances cameras support H264 format (MSE/MP4, WebRTC compatible)
- using MJPEG and H264 formats (if the camera supports them) won't cost you the CPU usage
- transcoding RAW format to MJPEG or H264 - will cost you a significant CPU usage
- H265 (HEVC) format is also supported (if the camera supports it)
Tests show that the basic Keenetic router with MIPS processor can broadcast three MJPEG cameras in the following resolutions: 1600х1200 + 640х480 + 640х480. The USB bus bandwidth is no more enough for larger resolutions. CPU consumption is no more than 5%.
Supported formats for your camera can be found here: **Go2rtc > WebUI > Add > V4L2**.
## RAW format
Example:
```yaml
streams:
camera1: v4l2:device?video=/dev/video0&input_format=yuyv422&video_size=1280x720&framerate=10
```
Go2rtc supports built-in transcoding of RAW to MJPEG format. This does not need to be additionally configured.
```
ffplay http://localhost:1984/api/stream.mjpeg?src=camera1
```
**Important.** You don't have to transcode the RAW format to transmit it over the network. You can stream it in `y4m` format, which is perfectly supported by ffmpeg. It won't cost you a CPU usage. But will require high network bandwidth.
```
ffplay http://localhost:1984/api/stream.y4m?src=camera1
```
@@ -0,0 +1,7 @@
//go:build !(linux && (386 || arm || mipsle || amd64 || arm64))
package v4l2
func Init() {
// not supported
}
@@ -0,0 +1,91 @@
//go:build linux && (386 || arm || mipsle || amd64 || arm64)
package v4l2
import (
"encoding/binary"
"fmt"
"net/http"
"os"
"strings"
"github.com/AlexxIT/go2rtc/internal/api"
"github.com/AlexxIT/go2rtc/internal/streams"
"github.com/AlexxIT/go2rtc/pkg/core"
"github.com/AlexxIT/go2rtc/pkg/v4l2"
"github.com/AlexxIT/go2rtc/pkg/v4l2/device"
)
func Init() {
streams.HandleFunc("v4l2", func(source string) (core.Producer, error) {
return v4l2.Open(source)
})
api.HandleFunc("api/v4l2", apiV4L2)
}
func apiV4L2(w http.ResponseWriter, r *http.Request) {
files, err := os.ReadDir("/dev")
if err != nil {
return
}
var sources []*api.Source
for _, file := range files {
if !strings.HasPrefix(file.Name(), core.KindVideo) {
continue
}
path := "/dev/" + file.Name()
dev, err := device.Open(path)
if err != nil {
continue
}
formats, _ := dev.ListFormats()
for _, fourCC := range formats {
name, ffmpeg := findFormat(fourCC)
source := &api.Source{Name: name}
sizes, _ := dev.ListSizes(fourCC)
for _, wh := range sizes {
if source.Info != "" {
source.Info += " "
}
source.Info += fmt.Sprintf("%dx%d", wh[0], wh[1])
frameRates, _ := dev.ListFrameRates(fourCC, wh[0], wh[1])
for _, fr := range frameRates {
source.Info += fmt.Sprintf("@%d", fr)
if source.URL == "" && ffmpeg != "" {
source.URL = fmt.Sprintf(
"v4l2:device?video=%s&input_format=%s&video_size=%dx%d&framerate=%d",
path, ffmpeg, wh[0], wh[1], fr,
)
}
}
}
if source.Info != "" {
sources = append(sources, source)
}
}
_ = dev.Close()
}
api.ResponseSources(w, sources)
}
func findFormat(fourCC uint32) (name, ffmpeg string) {
for _, format := range device.Formats {
if format.FourCC == fourCC {
return format.Name, format.FFmpeg
}
}
return string(binary.LittleEndian.AppendUint32(nil, fourCC)), ""
}