mirror of
https://github.com/AlexxIT/go2rtc.git
synced 2026-04-22 15:47:06 +08:00
Merge branch 'AlexxIT:master' into documentation-site
This commit is contained in:
@@ -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})
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -136,7 +136,7 @@ streams:
|
||||
"ffmpeg:" + url3 + "#video=copy"
|
||||
```
|
||||
|
||||
## Comparsion
|
||||
## Comparison
|
||||
|
||||
| expr | python | js |
|
||||
|------------------------------|----------------------------|--------------------------------|
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user