Merge branch 'AlexxIT:master' into documentation-site

This commit is contained in:
Sergey Krashevich
2026-01-26 04:22:35 +03:00
committed by GitHub
8 changed files with 49 additions and 48 deletions
+2 -2
View File
@@ -11,7 +11,7 @@ import (
"github.com/AlexxIT/go2rtc/internal/api"
"github.com/AlexxIT/go2rtc/internal/app"
"github.com/AlexxIT/go2rtc/pkg/core"
"github.com/AlexxIT/go2rtc/pkg/creds"
"github.com/gorilla/websocket"
"github.com/rs/zerolog"
)
@@ -133,7 +133,7 @@ func apiWS(w http.ResponseWriter, r *http.Request) {
if handler := wsHandlers[msg.Type]; handler != nil {
go func() {
if err = handler(tr, msg); err != nil {
errMsg := core.StripUserinfo(err.Error())
errMsg := creds.SecretString(err.Error())
tr.Write(&Message{Type: "error", Value: msg.Type + ": " + errMsg})
}
}()
+1 -1
View File
@@ -35,7 +35,7 @@ rtsp:
Editors like [GoLand](https://www.jetbrains.com/go/) and [VS Code](https://code.visualstudio.com/) supports autocomplete and syntax validation.
```yaml
# yaml-language-server: $schema=https://raw.githubusercontent.com/AlexxIT/go2rtc/master/website/schema.json
# yaml-language-server: $schema=https://raw.githubusercontent.com/AlexxIT/go2rtc/master/www/schema.json
```
## Defaults
+1 -1
View File
@@ -136,7 +136,7 @@ streams:
"ffmpeg:" + url3 + "#video=copy"
```
## Comparsion
## Comparison
| expr | python | js |
|------------------------------|----------------------------|--------------------------------|
+3 -3
View File
@@ -22,7 +22,7 @@ You **NEED** hardware acceleration if you using `#video=h264`, `#video=h265`, `#
streams:
# auto select hardware encoder
camera1_hw: ffmpeg:rtsp://rtsp:12345678@192.168.1.123/av_stream/ch0#video=h264#hardware
# manual select hardware encoder (vaapi, cuda, v4l2m2m, dxva2, videotoolbox)
camera1_vaapi: ffmpeg:rtsp://rtsp:12345678@192.168.1.123/av_stream/ch0#video=h264#hardware=vaapi
```
@@ -47,7 +47,7 @@ Read more [here](https://en.wikipedia.org/wiki/Intel_Quick_Sync_Video#Hardware_d
Linux and Docker:
- It may be important to have the latest version of the OS with the latest version of the Linux kernel. For example, on my **Debian 10 (kernel 4.19)** it did not work, but after update to **Debian 11 (kernel 5.10)** all was fine.
- In case of troube check you have `/dev/dri/` folder on your host.
- In case of trouble check you have `/dev/dri/` folder on your host.
Docker users should add `--privileged` option to container for access to Hardware.
@@ -79,7 +79,7 @@ Read more [here](https://docs.frigate.video/configuration/hardware_acceleration)
**Supported on:** Linux binary, Docker, Hass Addon.
I don't recommend using transcoding on the Raspberry Pi 3. It's extreamly slow, even with hardware acceleration. Also it may fail when transcoding 2K+ stream.
I don't recommend using transcoding on the Raspberry Pi 3. It's extremely slow, even with hardware acceleration. Also it may fail when transcoding 2K+ stream.
## Raspberry Pi 4
+7 -7
View File
@@ -10,8 +10,8 @@ What you should to know about WebRTC:
If an external connection via STUN is used:
- Uses [UDP hole punching](https://en.wikipedia.org/wiki/UDP_hole_punching) technology to bypass NAT even if you not open your server to the World
- For about 20% of users, the techology will not work because of the [Symmetric NAT](https://tomchen.github.io/symmetric-nat-test/)
- UDP is not suitable for transmitting 2K and 4K high bitrate video over open networks because of the high loss rate:
- For about 20% of users, the technology will not work because of the [Symmetric NAT](https://tomchen.github.io/symmetric-nat-test/)
- UDP is not suitable for transmitting 2K and 4K high bit rate video over open networks because of the high loss rate:
- https://habr.com/ru/companies/flashphoner/articles/480006/
- https://www.youtube.com/watch?v=FXVg2ckuKfs
@@ -26,7 +26,7 @@ webrtc:
## Config
**Important!** This example is not for copypasting!
**Important!** This example is not for copy pasting!
```yaml
webrtc:
@@ -49,13 +49,13 @@ webrtc:
credential: your_pass
# optional filter list for auto discovery logic
# some settings only make sense if you don't specify a fixed UDP port
# some settings only make sense if you don't specify a fixed UDP port
filters:
# list of host candidates from auto discovery to be sent
# including candidates from the `listen` option
# use `candidates: []` to remove all auto discovery candidates
candidates: [ 192.168.1.123 ]
# enable localhost candidates
loopback: true
@@ -84,7 +84,7 @@ Don't know why, but you can disable TCP port and leave only random UDP ports - `
## Config filters
**Importan!** By default go2rtc exclude all Docker-like candidates (`172.16.0.0/12`). This can not be disabled.
**Important!** By default go2rtc exclude all Docker-like candidates (`172.16.0.0/12`). This can not be disabled.
Filters allow you to exclude unnecessary candidates. Extra candidates don't make your connection worse or better. But the wrong filter settings can break everything. Skip this setting if you don't understand it.
@@ -106,7 +106,7 @@ webrtc:
candidates: [ 192.168.1.2:8555 ] # add manual host candidate (use docker port forwarding)
```
## Userful links
## Useful links
- https://www.ietf.org/archive/id/draft-ietf-wish-whip-01.html
- https://www.ietf.org/id/draft-murillo-whep-01.html
-12
View File
@@ -2,7 +2,6 @@ package core
import (
"crypto/rand"
"regexp"
"runtime"
"strconv"
"strings"
@@ -93,14 +92,3 @@ func Caller() string {
_, file, line, _ := runtime.Caller(1)
return file + ":" + strconv.Itoa(line)
}
const (
unreserved = `A-Za-z0-9-._~`
subdelims = `!$&'()*+,;=`
userinfo = unreserved + subdelims + `%:`
)
func StripUserinfo(s string) string {
sanitizer := regexp.MustCompile(`://[` + userinfo + `]+@`)
return sanitizer.ReplaceAllString(s, `://***@`)
}
+30 -19
View File
@@ -3,6 +3,7 @@ package creds
import (
"io"
"net/http"
"regexp"
"slices"
"strings"
"sync"
@@ -27,6 +28,7 @@ func AddSecret(value string) {
var secrets []string
var secretsMu sync.Mutex
var secretsReplacer *strings.Replacer
var userinfoRegexp *regexp.Regexp
func getReplacer() *strings.Replacer {
secretsMu.Lock()
@@ -40,14 +42,33 @@ func getReplacer() *strings.Replacer {
secretsReplacer = strings.NewReplacer(oldnew...)
}
if userinfoRegexp == nil {
userinfoRegexp = regexp.MustCompile(`://[` + userinfo + `]+@`)
}
return secretsReplacer
}
// Uniform Resource Identifier (URI)
// https://datatracker.ietf.org/doc/html/rfc3986
const (
unreserved = `A-Za-z0-9-._~`
subdelims = `!$&'()*+,;=`
userinfo = unreserved + subdelims + `%:`
)
func SecretString(s string) string {
re := getReplacer()
s = userinfoRegexp.ReplaceAllString(s, `://***@`)
return re.Replace(s)
}
func SecretWrite(w io.Writer, s string) (n int, err error) {
re := getReplacer()
s = userinfoRegexp.ReplaceAllString(s, `://***@`)
return re.WriteString(w, s)
}
func SecretWriter(w io.Writer) io.Writer {
return &secretWriter{w}
}
@@ -57,27 +78,17 @@ type secretWriter struct {
}
func (s *secretWriter) Write(b []byte) (int, error) {
re := getReplacer()
return re.WriteString(s.w, string(b))
}
type secretResponse struct {
w http.ResponseWriter
}
func (s *secretResponse) Header() http.Header {
return s.w.Header()
}
func (s *secretResponse) Write(b []byte) (int, error) {
re := getReplacer()
return re.WriteString(s.w, string(b))
}
func (s *secretResponse) WriteHeader(statusCode int) {
s.w.WriteHeader(statusCode)
return SecretWrite(s.w, string(b))
}
func SecretResponse(w http.ResponseWriter) http.ResponseWriter {
return &secretResponse{w}
}
type secretResponse struct {
http.ResponseWriter
}
func (s *secretResponse) Write(b []byte) (int, error) {
return SecretWrite(s.ResponseWriter, string(b))
}
+5 -3
View File
@@ -36,7 +36,7 @@ func NewClient(rawURL string) (*Client, error) {
} else if model == ModelMijia || model == ModelXiaobai {
username = "admin"
password = query.Get("password")
} else if model == ModelXiaofang {
} else if model == ModelDafang || model == ModelXiaofang {
username = "admin"
} else {
return nil, fmt.Errorf("xiaomi: unsupported model: %s", model)
@@ -47,7 +47,7 @@ func NewClient(rawURL string) (*Client, error) {
return nil, err
}
if model == ModelXiaofang {
if model == ModelDafang || model == ModelXiaofang {
err = xiaofangLogin(conn, query.Get("password"))
if err != nil {
_ = conn.Close()
@@ -196,7 +196,7 @@ func (c *Client) StartMedia(video, audio string) error {
c.WriteCommandJSON(cmdVideoStart, `{}`),
)
case ModelXiaofang:
case ModelDafang, ModelXiaofang:
// 00010000 4943414d 95010400000000000000000600000000000000d20400005a07 - 90k bitrate
// 00010000 4943414d 95010400000000000000000600000000000000d20400001e07 - 30k bitrate
//var b byte
@@ -258,6 +258,8 @@ const (
ModelXiaofang = "isa.camera.isc5"
// ModelMijia support miss format for new fw and legacy format for old fw
ModelMijia = "chuangmi.camera.v2"
// ModelDafang support miss format for new fw and legacy format for old fw
ModelDafang = "isa.camera.df3"
)
func Supported(model string) bool {