1
0
Fork 0
forked from External/mediamtx

webrtc: allow configuring timeouts (#3404) (#3406)

* webrtc: allow configuring timeouts (#3404)

* fix from code inspect
This commit is contained in:
Jason Walton 2024-05-30 07:36:58 -04:00 committed by GitHub
parent 500c5ef350
commit 1c2f95f609
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 74 additions and 28 deletions

View file

@ -246,6 +246,10 @@ components:
type: string type: string
clientOnly: clientOnly:
type: boolean type: boolean
webrtcHandshakeTimeout:
type: string
webrtcTrackGatherTimeout:
type: string
# SRT server # SRT server
srt: srt:

View file

@ -238,6 +238,8 @@ type Conf struct {
WebRTCIPsFromInterfacesList []string `json:"webrtcIPsFromInterfacesList"` WebRTCIPsFromInterfacesList []string `json:"webrtcIPsFromInterfacesList"`
WebRTCAdditionalHosts []string `json:"webrtcAdditionalHosts"` WebRTCAdditionalHosts []string `json:"webrtcAdditionalHosts"`
WebRTCICEServers2 WebRTCICEServers `json:"webrtcICEServers2"` WebRTCICEServers2 WebRTCICEServers `json:"webrtcICEServers2"`
WebRTCHandshakeTimeout StringDuration `json:"webrtcHandshakeTimeout"`
WebRTCTrackGatherTimeout StringDuration `json:"webrtcTrackGatherTimeout"`
WebRTCICEUDPMuxAddress *string `json:"webrtcICEUDPMuxAddress,omitempty"` // deprecated WebRTCICEUDPMuxAddress *string `json:"webrtcICEUDPMuxAddress,omitempty"` // deprecated
WebRTCICETCPMuxAddress *string `json:"webrtcICETCPMuxAddress,omitempty"` // deprecated WebRTCICETCPMuxAddress *string `json:"webrtcICETCPMuxAddress,omitempty"` // deprecated
WebRTCICEHostNAT1To1IPs *[]string `json:"webrtcICEHostNAT1To1IPs,omitempty"` // deprecated WebRTCICEHostNAT1To1IPs *[]string `json:"webrtcICEHostNAT1To1IPs,omitempty"` // deprecated
@ -392,6 +394,8 @@ func (conf *Conf) setDefaults() {
conf.WebRTCIPsFromInterfacesList = []string{} conf.WebRTCIPsFromInterfacesList = []string{}
conf.WebRTCAdditionalHosts = []string{} conf.WebRTCAdditionalHosts = []string{}
conf.WebRTCICEServers2 = []WebRTCICEServer{} conf.WebRTCICEServers2 = []WebRTCICEServer{}
conf.WebRTCHandshakeTimeout = 10 * StringDuration(time.Second)
conf.WebRTCTrackGatherTimeout = 2 * StringDuration(time.Second)
// SRT server // SRT server
conf.SRT = true conf.SRT = true

View file

@ -580,6 +580,8 @@ func (p *Core) createResources(initial bool) error {
IPsFromInterfacesList: p.conf.WebRTCIPsFromInterfacesList, IPsFromInterfacesList: p.conf.WebRTCIPsFromInterfacesList,
AdditionalHosts: p.conf.WebRTCAdditionalHosts, AdditionalHosts: p.conf.WebRTCAdditionalHosts,
ICEServers: p.conf.WebRTCICEServers2, ICEServers: p.conf.WebRTCICEServers2,
HandshakeTimeout: p.conf.WebRTCHandshakeTimeout,
TrackGatherTimeout: p.conf.WebRTCTrackGatherTimeout,
ExternalCmdPool: p.externalCmdPool, ExternalCmdPool: p.externalCmdPool,
PathManager: p.pathManager, PathManager: p.pathManager,
Parent: p, Parent: p,
@ -848,6 +850,8 @@ func (p *Core) closeResources(newConf *conf.Conf, calledByAPI bool) {
!reflect.DeepEqual(newConf.WebRTCIPsFromInterfacesList, p.conf.WebRTCIPsFromInterfacesList) || !reflect.DeepEqual(newConf.WebRTCIPsFromInterfacesList, p.conf.WebRTCIPsFromInterfacesList) ||
!reflect.DeepEqual(newConf.WebRTCAdditionalHosts, p.conf.WebRTCAdditionalHosts) || !reflect.DeepEqual(newConf.WebRTCAdditionalHosts, p.conf.WebRTCAdditionalHosts) ||
!reflect.DeepEqual(newConf.WebRTCICEServers2, p.conf.WebRTCICEServers2) || !reflect.DeepEqual(newConf.WebRTCICEServers2, p.conf.WebRTCICEServers2) ||
newConf.WebRTCHandshakeTimeout != p.conf.WebRTCHandshakeTimeout ||
newConf.WebRTCTrackGatherTimeout != p.conf.WebRTCTrackGatherTimeout ||
closeMetrics || closeMetrics ||
closePathManager || closePathManager ||
closeLogger closeLogger

View file

@ -11,13 +11,12 @@ import (
"github.com/pion/interceptor" "github.com/pion/interceptor"
"github.com/pion/webrtc/v3" "github.com/pion/webrtc/v3"
"github.com/bluenviron/mediamtx/internal/conf"
"github.com/bluenviron/mediamtx/internal/logger" "github.com/bluenviron/mediamtx/internal/logger"
) )
const ( const (
webrtcHandshakeTimeout = 10 * time.Second webrtcStreamID = "mediamtx"
webrtcTrackGatherTimeout = 2 * time.Second
webrtcStreamID = "mediamtx"
) )
func stringInSlice(a string, list []string) bool { func stringInSlice(a string, list []string) bool {
@ -39,6 +38,8 @@ type PeerConnection struct {
ICEServers []webrtc.ICEServer ICEServers []webrtc.ICEServer
ICEUDPMux ice.UDPMux ICEUDPMux ice.UDPMux
ICETCPMux ice.TCPMux ICETCPMux ice.TCPMux
HandshakeTimeout conf.StringDuration
TrackGatherTimeout conf.StringDuration
LocalRandomUDP bool LocalRandomUDP bool
IPsFromInterfaces bool IPsFromInterfaces bool
IPsFromInterfacesList []string IPsFromInterfacesList []string
@ -312,7 +313,7 @@ func (co *PeerConnection) WaitGatheringDone(ctx context.Context) error {
func (co *PeerConnection) WaitUntilConnected( func (co *PeerConnection) WaitUntilConnected(
ctx context.Context, ctx context.Context,
) error { ) error {
t := time.NewTimer(webrtcHandshakeTimeout) t := time.NewTimer(time.Duration(co.HandshakeTimeout))
defer t.Stop() defer t.Stop()
outer: outer:
@ -339,7 +340,7 @@ func (co *PeerConnection) GatherIncomingTracks(
) ([]*IncomingTrack, error) { ) ([]*IncomingTrack, error) {
var tracks []*IncomingTrack var tracks []*IncomingTrack
t := time.NewTimer(webrtcTrackGatherTimeout) t := time.NewTimer(time.Duration(co.TrackGatherTimeout))
defer t.Stop() defer t.Stop()
for { for {

View file

@ -4,16 +4,19 @@ import (
"testing" "testing"
"time" "time"
"github.com/bluenviron/mediamtx/internal/conf"
"github.com/bluenviron/mediamtx/internal/test" "github.com/bluenviron/mediamtx/internal/test"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestPeerConnectionCloseAfterError(t *testing.T) { func TestPeerConnectionCloseAfterError(t *testing.T) {
pc := &PeerConnection{ pc := &PeerConnection{
LocalRandomUDP: true, HandshakeTimeout: conf.StringDuration(10 * time.Second),
IPsFromInterfaces: true, TrackGatherTimeout: conf.StringDuration(2 * time.Second),
Publish: false, LocalRandomUDP: true,
Log: test.NilLogger, IPsFromInterfaces: true,
Publish: false,
Log: test.NilLogger,
} }
err := pc.Start() err := pc.Start()
require.NoError(t, err) require.NoError(t, err)

View file

@ -13,10 +13,16 @@ import (
"github.com/pion/sdp/v3" "github.com/pion/sdp/v3"
"github.com/pion/webrtc/v3" "github.com/pion/webrtc/v3"
"github.com/bluenviron/mediamtx/internal/conf"
"github.com/bluenviron/mediamtx/internal/logger" "github.com/bluenviron/mediamtx/internal/logger"
"github.com/bluenviron/mediamtx/internal/protocols/httpp" "github.com/bluenviron/mediamtx/internal/protocols/httpp"
) )
const (
webrtcHandshakeTimeout = 10 * time.Second
webrtcTrackGatherTimeout = 2 * time.Second
)
// WHIPClient is a WHIP client. // WHIPClient is a WHIP client.
type WHIPClient struct { type WHIPClient struct {
HTTPClient *http.Client HTTPClient *http.Client
@ -48,12 +54,14 @@ func (c *WHIPClient) Publish(
} }
c.pc = &PeerConnection{ c.pc = &PeerConnection{
ICEServers: iceServers, ICEServers: iceServers,
LocalRandomUDP: true, HandshakeTimeout: conf.StringDuration(10 * time.Second),
IPsFromInterfaces: true, TrackGatherTimeout: conf.StringDuration(2 * time.Second),
Publish: true, LocalRandomUDP: true,
OutgoingTracks: outgoingTracks, IPsFromInterfaces: true,
Log: c.Log, Publish: true,
OutgoingTracks: outgoingTracks,
Log: c.Log,
} }
err = c.pc.Start() err = c.pc.Start()
if err != nil { if err != nil {
@ -122,11 +130,13 @@ func (c *WHIPClient) Read(ctx context.Context) ([]*IncomingTrack, error) {
} }
c.pc = &PeerConnection{ c.pc = &PeerConnection{
ICEServers: iceServers, ICEServers: iceServers,
LocalRandomUDP: true, HandshakeTimeout: conf.StringDuration(10 * time.Second),
IPsFromInterfaces: true, TrackGatherTimeout: conf.StringDuration(2 * time.Second),
Publish: false, LocalRandomUDP: true,
Log: c.Log, IPsFromInterfaces: true,
Publish: false,
Log: c.Log,
} }
err = c.pc.Start() err = c.pc.Start()
if err != nil { if err != nil {

View file

@ -192,6 +192,8 @@ type Server struct {
IPsFromInterfacesList []string IPsFromInterfacesList []string
AdditionalHosts []string AdditionalHosts []string
ICEServers []conf.WebRTCICEServer ICEServers []conf.WebRTCICEServer
HandshakeTimeout conf.StringDuration
TrackGatherTimeout conf.StringDuration
ExternalCmdPool *externalcmd.Pool ExternalCmdPool *externalcmd.Pool
PathManager serverPathManager PathManager serverPathManager
Parent serverParent Parent serverParent

View file

@ -117,6 +117,8 @@ func initializeTestServer(t *testing.T) *Server {
IPsFromInterfacesList: []string{}, IPsFromInterfacesList: []string{},
AdditionalHosts: []string{}, AdditionalHosts: []string{},
ICEServers: []conf.WebRTCICEServer{}, ICEServers: []conf.WebRTCICEServer{},
HandshakeTimeout: conf.StringDuration(10 * time.Second),
TrackGatherTimeout: conf.StringDuration(2 * time.Second),
ExternalCmdPool: nil, ExternalCmdPool: nil,
PathManager: pathManager, PathManager: pathManager,
Parent: test.NilLogger, Parent: test.NilLogger,
@ -195,9 +197,11 @@ func TestServerOptionsICEServer(t *testing.T) {
Username: "myuser", Username: "myuser",
Password: "mypass", Password: "mypass",
}}, }},
ExternalCmdPool: nil, HandshakeTimeout: conf.StringDuration(10 * time.Second),
PathManager: pathManager, TrackGatherTimeout: conf.StringDuration(2 * time.Second),
Parent: test.NilLogger, ExternalCmdPool: nil,
PathManager: pathManager,
Parent: test.NilLogger,
} }
err := s.Initialize() err := s.Initialize()
require.NoError(t, err) require.NoError(t, err)
@ -249,6 +253,8 @@ func TestServerPublish(t *testing.T) {
IPsFromInterfacesList: []string{}, IPsFromInterfacesList: []string{},
AdditionalHosts: []string{}, AdditionalHosts: []string{},
ICEServers: []conf.WebRTCICEServer{}, ICEServers: []conf.WebRTCICEServer{},
HandshakeTimeout: conf.StringDuration(10 * time.Second),
TrackGatherTimeout: conf.StringDuration(2 * time.Second),
ExternalCmdPool: nil, ExternalCmdPool: nil,
PathManager: pathManager, PathManager: pathManager,
Parent: test.NilLogger, Parent: test.NilLogger,
@ -359,6 +365,8 @@ func TestServerRead(t *testing.T) {
IPsFromInterfacesList: []string{}, IPsFromInterfacesList: []string{},
AdditionalHosts: []string{}, AdditionalHosts: []string{},
ICEServers: []conf.WebRTCICEServer{}, ICEServers: []conf.WebRTCICEServer{},
HandshakeTimeout: conf.StringDuration(10 * time.Second),
TrackGatherTimeout: conf.StringDuration(2 * time.Second),
ExternalCmdPool: nil, ExternalCmdPool: nil,
PathManager: pathManager, PathManager: pathManager,
Parent: test.NilLogger, Parent: test.NilLogger,

View file

@ -409,6 +409,8 @@ func (s *session) runPublish() (int, error) {
pc := &webrtc.PeerConnection{ pc := &webrtc.PeerConnection{
ICEServers: iceServers, ICEServers: iceServers,
HandshakeTimeout: s.parent.HandshakeTimeout,
TrackGatherTimeout: s.parent.TrackGatherTimeout,
IPsFromInterfaces: s.ipsFromInterfaces, IPsFromInterfaces: s.ipsFromInterfaces,
IPsFromInterfacesList: s.ipsFromInterfacesList, IPsFromInterfacesList: s.ipsFromInterfacesList,
AdditionalHosts: s.additionalHosts, AdditionalHosts: s.additionalHosts,
@ -566,6 +568,8 @@ func (s *session) runRead() (int, error) {
pc := &webrtc.PeerConnection{ pc := &webrtc.PeerConnection{
ICEServers: iceServers, ICEServers: iceServers,
HandshakeTimeout: s.parent.HandshakeTimeout,
TrackGatherTimeout: s.parent.TrackGatherTimeout,
IPsFromInterfaces: s.ipsFromInterfaces, IPsFromInterfaces: s.ipsFromInterfaces,
IPsFromInterfacesList: s.ipsFromInterfacesList, IPsFromInterfacesList: s.ipsFromInterfacesList,
AdditionalHosts: s.additionalHosts, AdditionalHosts: s.additionalHosts,

View file

@ -32,11 +32,13 @@ func TestSource(t *testing.T) {
ChannelCount: 2, ChannelCount: 2,
}}} }}}
pc := &webrtc.PeerConnection{ pc := &webrtc.PeerConnection{
LocalRandomUDP: true, LocalRandomUDP: true,
IPsFromInterfaces: true, IPsFromInterfaces: true,
Publish: true, Publish: true,
OutgoingTracks: outgoingTracks, HandshakeTimeout: conf.StringDuration(10 * time.Second),
Log: test.NilLogger, TrackGatherTimeout: conf.StringDuration(2 * time.Second),
OutgoingTracks: outgoingTracks,
Log: test.NilLogger,
} }
err := pc.Start() err := pc.Start()
require.NoError(t, err) require.NoError(t, err)

View file

@ -381,6 +381,10 @@ webrtcICEServers2: []
# username: '' # username: ''
# password: '' # password: ''
# clientOnly: false # clientOnly: false
# Time to wait for the WebRTC handshake to complete.
webrtcHandshakeTimeout: 10s
# Maximum time to gather video tracks.
webrtcTrackGatherTimeout: 2s
############################################### ###############################################
# Global settings -> SRT server # Global settings -> SRT server