Files
livekit/pkg/rtc/config.go
2021-05-07 01:16:33 -07:00

127 lines
3.0 KiB
Go

package rtc
import (
"errors"
"fmt"
"net"
"github.com/go-logr/zapr"
"github.com/pion/ice/v2"
"github.com/pion/ion-sfu/pkg/buffer"
"github.com/pion/logging"
"github.com/pion/webrtc/v3"
"github.com/livekit/livekit-server/pkg/config"
"github.com/livekit/livekit-server/pkg/logger"
)
type WebRTCConfig struct {
Configuration webrtc.Configuration
SettingEngine webrtc.SettingEngine
Receiver ReceiverConfig
BufferFactory *buffer.Factory
UDPMux ice.UDPMux
UDPMuxConn *net.UDPConn
TCPMuxListener *net.TCPListener
}
type ReceiverConfig struct {
packetBufferSize int
maxBitrate uint64
}
// number of packets to buffer up
const readBufferSize = 50
func NewWebRTCConfig(conf *config.RTCConfig, externalIP string) (*WebRTCConfig, error) {
c := webrtc.Configuration{
SDPSemantics: webrtc.SDPSemanticsUnifiedPlan,
}
s := webrtc.SettingEngine{}
loggerFactory := logging.NewDefaultLoggerFactory()
lkLogger := loggerFactory.NewLogger("livekit-mux")
iceUrls := make([]string, 0)
for _, stunServer := range conf.StunServers {
iceUrls = append(iceUrls, fmt.Sprintf("stun:%s", stunServer))
}
c.ICEServers = []webrtc.ICEServer{
{
URLs: iceUrls,
},
}
if conf.UseExternalIP && externalIP != "" {
s.SetNAT1To1IPs([]string{externalIP}, webrtc.ICECandidateTypeHost)
}
if conf.PacketBufferSize == 0 {
conf.PacketBufferSize = 500
}
bufferFactory := buffer.NewBufferFactory(conf.PacketBufferSize, zapr.NewLogger(logger.Desugar()))
s.BufferFactory = bufferFactory.GetOrNew
networkTypes := make([]webrtc.NetworkType, 0, 4)
if !conf.ForceTCP {
networkTypes = append(networkTypes,
webrtc.NetworkTypeUDP4,
)
}
var udpMux *ice.UDPMuxDefault
var udpMuxConn *net.UDPConn
var err error
if conf.UDPPort != 0 {
udpMuxConn, err = net.ListenUDP("udp4", &net.UDPAddr{
Port: int(conf.UDPPort),
})
if err != nil {
return nil, err
}
udpMux = ice.NewUDPMuxDefault(ice.UDPMuxParams{
Logger: lkLogger,
UDPConn: udpMuxConn,
})
s.SetICEUDPMux(udpMux)
} else if conf.ICEPortRangeStart != 0 && conf.ICEPortRangeEnd != 0 {
if err := s.SetEphemeralUDPPortRange(uint16(conf.ICEPortRangeStart), uint16(conf.ICEPortRangeEnd)); err != nil {
return nil, err
}
}
// use TCP mux when it's set
var tcpListener *net.TCPListener
if conf.TCPPort != 0 {
networkTypes = append(networkTypes,
webrtc.NetworkTypeTCP4,
)
tcpListener, err = net.ListenTCP("tcp4", &net.TCPAddr{
Port: int(conf.TCPPort),
})
if err != nil {
return nil, err
}
tcpMux := webrtc.NewICETCPMux(lkLogger, tcpListener, readBufferSize)
s.SetICETCPMux(tcpMux)
}
if len(networkTypes) == 0 {
return nil, errors.New("TCP is forced but not configured")
}
s.SetNetworkTypes(networkTypes)
return &WebRTCConfig{
Configuration: c,
SettingEngine: s,
BufferFactory: bufferFactory,
Receiver: ReceiverConfig{
packetBufferSize: conf.PacketBufferSize,
maxBitrate: conf.MaxBitrate,
},
UDPMux: udpMux,
UDPMuxConn: udpMuxConn,
TCPMuxListener: tcpListener,
}, nil
}