install go2rtc on bob
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
package webrtc
|
||||
|
||||
import (
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/AlexxIT/go2rtc/internal/api/ws"
|
||||
"github.com/AlexxIT/go2rtc/pkg/core"
|
||||
"github.com/AlexxIT/go2rtc/pkg/webrtc"
|
||||
"github.com/AlexxIT/go2rtc/pkg/xnet"
|
||||
pion "github.com/pion/webrtc/v4"
|
||||
)
|
||||
|
||||
type Address struct {
|
||||
host string
|
||||
Port string
|
||||
Network string
|
||||
Priority uint32
|
||||
}
|
||||
|
||||
var stuns []string
|
||||
|
||||
func (a *Address) Host() string {
|
||||
if a.host == "stun" {
|
||||
ip, err := webrtc.GetCachedPublicIP(stuns...)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return ip.String()
|
||||
}
|
||||
return a.host
|
||||
}
|
||||
|
||||
func (a *Address) Marshal() string {
|
||||
if host := a.Host(); host != "" {
|
||||
return webrtc.CandidateICE(a.Network, host, a.Port, a.Priority)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var addresses []*Address
|
||||
var filters webrtc.Filters
|
||||
|
||||
func AddCandidate(network, address string) {
|
||||
if network == "" {
|
||||
AddCandidate("tcp", address)
|
||||
AddCandidate("udp", address)
|
||||
return
|
||||
}
|
||||
|
||||
host, port, err := net.SplitHostPort(address)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// start from 1, so manual candidates will be lower than built-in
|
||||
// and every next candidate will have a lower priority
|
||||
candidateIndex := 1 + len(addresses)
|
||||
|
||||
priority := webrtc.CandidateHostPriority(network, candidateIndex)
|
||||
addresses = append(addresses, &Address{host, port, network, priority})
|
||||
}
|
||||
|
||||
func GetCandidates() (candidates []string) {
|
||||
for _, address := range addresses {
|
||||
if candidate := address.Marshal(); candidate != "" {
|
||||
candidates = append(candidates, candidate)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// FilterCandidate return true if candidate passed the check
|
||||
func FilterCandidate(candidate *pion.ICECandidate) bool {
|
||||
if candidate == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// remove any Docker-like IP from candidates
|
||||
if ip := net.ParseIP(candidate.Address); ip != nil && xnet.Docker.Contains(ip) {
|
||||
return false
|
||||
}
|
||||
|
||||
// host candidate should be in the hosts list
|
||||
if candidate.Typ == pion.ICECandidateTypeHost && filters.Candidates != nil {
|
||||
if !core.Contains(filters.Candidates, candidate.Address) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if filters.Networks != nil {
|
||||
networkType := NetworkType(candidate.Protocol.String(), candidate.Address)
|
||||
if !core.Contains(filters.Networks, networkType) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// NetworkType convert tcp/udp network to tcp4/tcp6/udp4/udp6
|
||||
func NetworkType(network, host string) string {
|
||||
if strings.IndexByte(host, ':') >= 0 {
|
||||
return network + "6"
|
||||
} else {
|
||||
return network + "4"
|
||||
}
|
||||
}
|
||||
|
||||
func asyncCandidates(tr *ws.Transport, cons *webrtc.Conn) {
|
||||
tr.WithContext(func(ctx map[any]any) {
|
||||
if candidates, ok := ctx["candidate"].([]string); ok {
|
||||
// process candidates that receive before this moment
|
||||
for _, candidate := range candidates {
|
||||
_ = cons.AddCandidate(candidate)
|
||||
}
|
||||
|
||||
// remove already processed candidates
|
||||
delete(ctx, "candidate")
|
||||
}
|
||||
|
||||
// set variable for process candidates after this moment
|
||||
ctx["webrtc"] = cons
|
||||
})
|
||||
|
||||
for _, candidate := range GetCandidates() {
|
||||
log.Trace().Str("candidate", candidate).Msg("[webrtc] config")
|
||||
tr.Write(&ws.Message{Type: "webrtc/candidate", Value: candidate})
|
||||
}
|
||||
}
|
||||
|
||||
func candidateHandler(tr *ws.Transport, msg *ws.Message) error {
|
||||
// process incoming candidate in sync function
|
||||
tr.WithContext(func(ctx map[any]any) {
|
||||
candidate := msg.String()
|
||||
log.Trace().Str("candidate", candidate).Msg("[webrtc] remote")
|
||||
|
||||
if cons, ok := ctx["webrtc"].(*webrtc.Conn); ok {
|
||||
// if webrtc.Server already initialized - process candidate
|
||||
_ = cons.AddCandidate(candidate)
|
||||
} else {
|
||||
// or collect candidate and process it later
|
||||
list, _ := ctx["candidate"].([]string)
|
||||
ctx["candidate"] = append(list, candidate)
|
||||
}
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user