Skip to content

Commit

Permalink
webrtc: allow configuring timeouts (bluenviron#3404)
Browse files Browse the repository at this point in the history
  • Loading branch information
jwalton committed May 28, 2024
1 parent 51387e8 commit f03b44d
Show file tree
Hide file tree
Showing 11 changed files with 72 additions and 28 deletions.
4 changes: 4 additions & 0 deletions apidocs/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,10 @@ components:
type: string
clientOnly:
type: boolean
webrtcHandshakeTimeout:
type: string
webrtcTrackGatherTimeout:
type: string

# SRT server
srt:
Expand Down
4 changes: 4 additions & 0 deletions internal/conf/conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ type Conf struct {
WebRTCIPsFromInterfacesList []string `json:"webrtcIPsFromInterfacesList"`
WebRTCAdditionalHosts []string `json:"webrtcAdditionalHosts"`
WebRTCICEServers2 WebRTCICEServers `json:"webrtcICEServers2"`
WebRTCHandshakeTimeout StringDuration `json:"webrtcHandshakeTimeout"`
WebRTCTrackGatherTimeout StringDuration `json:"webrtcTrackGatherTimeout"`
WebRTCICEUDPMuxAddress *string `json:"webrtcICEUDPMuxAddress,omitempty"` // deprecated
WebRTCICETCPMuxAddress *string `json:"webrtcICETCPMuxAddress,omitempty"` // deprecated
WebRTCICEHostNAT1To1IPs *[]string `json:"webrtcICEHostNAT1To1IPs,omitempty"` // deprecated
Expand Down Expand Up @@ -392,6 +394,8 @@ func (conf *Conf) setDefaults() {
conf.WebRTCIPsFromInterfacesList = []string{}
conf.WebRTCAdditionalHosts = []string{}
conf.WebRTCICEServers2 = []WebRTCICEServer{}
conf.WebRTCHandshakeTimeout = 10 * StringDuration(time.Second)
conf.WebRTCTrackGatherTimeout = 2 * StringDuration(time.Second)

// SRT server
conf.SRT = true
Expand Down
2 changes: 2 additions & 0 deletions internal/core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,8 @@ func (p *Core) createResources(initial bool) error {
IPsFromInterfacesList: p.conf.WebRTCIPsFromInterfacesList,
AdditionalHosts: p.conf.WebRTCAdditionalHosts,
ICEServers: p.conf.WebRTCICEServers2,
HandshakeTimeout: p.conf.WebRTCHandshakeTimeout,
TrackGatherTimeout: p.conf.WebRTCTrackGatherTimeout,
ExternalCmdPool: p.externalCmdPool,
PathManager: p.pathManager,
Parent: p,
Expand Down
11 changes: 6 additions & 5 deletions internal/protocols/webrtc/peer_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,12 @@ import (
"github.com/pion/interceptor"
"github.com/pion/webrtc/v3"

"github.com/bluenviron/mediamtx/internal/conf"
"github.com/bluenviron/mediamtx/internal/logger"
)

const (
webrtcHandshakeTimeout = 10 * time.Second
webrtcTrackGatherTimeout = 2 * time.Second
webrtcStreamID = "mediamtx"
webrtcStreamID = "mediamtx"
)

func stringInSlice(a string, list []string) bool {
Expand All @@ -39,6 +38,8 @@ type PeerConnection struct {
ICEServers []webrtc.ICEServer
ICEUDPMux ice.UDPMux
ICETCPMux ice.TCPMux
HandshakeTimeout conf.StringDuration
TrackGatherTimeout conf.StringDuration
LocalRandomUDP bool
IPsFromInterfaces bool
IPsFromInterfacesList []string
Expand Down Expand Up @@ -312,7 +313,7 @@ func (co *PeerConnection) WaitGatheringDone(ctx context.Context) error {
func (co *PeerConnection) WaitUntilConnected(
ctx context.Context,
) error {
t := time.NewTimer(webrtcHandshakeTimeout)
t := time.NewTimer(time.Duration(co.HandshakeTimeout))
defer t.Stop()

outer:
Expand All @@ -339,7 +340,7 @@ func (co *PeerConnection) GatherIncomingTracks(
) ([]*IncomingTrack, error) {
var tracks []*IncomingTrack

t := time.NewTimer(webrtcTrackGatherTimeout)
t := time.NewTimer(time.Duration(co.TrackGatherTimeout))
defer t.Stop()

for {
Expand Down
11 changes: 7 additions & 4 deletions internal/protocols/webrtc/peer_connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@ import (
"testing"
"time"

"github.com/bluenviron/mediamtx/internal/conf"
"github.com/bluenviron/mediamtx/internal/test"
"github.com/stretchr/testify/require"
)

func TestPeerConnectionCloseAfterError(t *testing.T) {
pc := &PeerConnection{
LocalRandomUDP: true,
IPsFromInterfaces: true,
Publish: false,
Log: test.NilLogger,
HandshakeTimeout: conf.StringDuration(10 * time.Second),
TrackGatherTimeout: conf.StringDuration(2 * time.Second),
LocalRandomUDP: true,
IPsFromInterfaces: true,
Publish: false,
Log: test.NilLogger,
}
err := pc.Start()
require.NoError(t, err)
Expand Down
32 changes: 21 additions & 11 deletions internal/protocols/webrtc/whip_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,16 @@ import (
"github.com/pion/sdp/v3"
"github.com/pion/webrtc/v3"

"github.com/bluenviron/mediamtx/internal/conf"
"github.com/bluenviron/mediamtx/internal/logger"
"github.com/bluenviron/mediamtx/internal/protocols/httpp"
)

const (
webrtcHandshakeTimeout = 10 * time.Second
webrtcTrackGatherTimeout = 2 * time.Second
)

// WHIPClient is a WHIP client.
type WHIPClient struct {
HTTPClient *http.Client
Expand Down Expand Up @@ -48,12 +54,14 @@ func (c *WHIPClient) Publish(
}

c.pc = &PeerConnection{
ICEServers: iceServers,
LocalRandomUDP: true,
IPsFromInterfaces: true,
Publish: true,
OutgoingTracks: outgoingTracks,
Log: c.Log,
ICEServers: iceServers,
HandshakeTimeout: conf.StringDuration(10 * time.Second),
TrackGatherTimeout: conf.StringDuration(2 * time.Second),
LocalRandomUDP: true,
IPsFromInterfaces: true,
Publish: true,
OutgoingTracks: outgoingTracks,
Log: c.Log,
}
err = c.pc.Start()
if err != nil {
Expand Down Expand Up @@ -122,11 +130,13 @@ func (c *WHIPClient) Read(ctx context.Context) ([]*IncomingTrack, error) {
}

c.pc = &PeerConnection{
ICEServers: iceServers,
LocalRandomUDP: true,
IPsFromInterfaces: true,
Publish: false,
Log: c.Log,
ICEServers: iceServers,
HandshakeTimeout: conf.StringDuration(10 * time.Second),
TrackGatherTimeout: conf.StringDuration(2 * time.Second),
LocalRandomUDP: true,
IPsFromInterfaces: true,
Publish: false,
Log: c.Log,
}
err = c.pc.Start()
if err != nil {
Expand Down
2 changes: 2 additions & 0 deletions internal/servers/webrtc/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ type Server struct {
IPsFromInterfacesList []string
AdditionalHosts []string
ICEServers []conf.WebRTCICEServer
HandshakeTimeout conf.StringDuration
TrackGatherTimeout conf.StringDuration
ExternalCmdPool *externalcmd.Pool
PathManager serverPathManager
Parent serverParent
Expand Down
14 changes: 11 additions & 3 deletions internal/servers/webrtc/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ func initializeTestServer(t *testing.T) *Server {
IPsFromInterfacesList: []string{},
AdditionalHosts: []string{},
ICEServers: []conf.WebRTCICEServer{},
HandshakeTimeout: conf.StringDuration(10 * time.Second),
TrackGatherTimeout: conf.StringDuration(2 * time.Second),
ExternalCmdPool: nil,
PathManager: pathManager,
Parent: test.NilLogger,
Expand Down Expand Up @@ -195,9 +197,11 @@ func TestServerOptionsICEServer(t *testing.T) {
Username: "myuser",
Password: "mypass",
}},
ExternalCmdPool: nil,
PathManager: pathManager,
Parent: test.NilLogger,
HandshakeTimeout: conf.StringDuration(10 * time.Second),
TrackGatherTimeout: conf.StringDuration(2 * time.Second),
ExternalCmdPool: nil,
PathManager: pathManager,
Parent: test.NilLogger,
}
err := s.Initialize()
require.NoError(t, err)
Expand Down Expand Up @@ -249,6 +253,8 @@ func TestServerPublish(t *testing.T) {
IPsFromInterfacesList: []string{},
AdditionalHosts: []string{},
ICEServers: []conf.WebRTCICEServer{},
HandshakeTimeout: conf.StringDuration(10 * time.Second),
TrackGatherTimeout: conf.StringDuration(2 * time.Second),
ExternalCmdPool: nil,
PathManager: pathManager,
Parent: test.NilLogger,
Expand Down Expand Up @@ -359,6 +365,8 @@ func TestServerRead(t *testing.T) {
IPsFromInterfacesList: []string{},
AdditionalHosts: []string{},
ICEServers: []conf.WebRTCICEServer{},
HandshakeTimeout: conf.StringDuration(10 * time.Second),
TrackGatherTimeout: conf.StringDuration(2 * time.Second),
ExternalCmdPool: nil,
PathManager: pathManager,
Parent: test.NilLogger,
Expand Down
4 changes: 4 additions & 0 deletions internal/servers/webrtc/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,8 @@ func (s *session) runPublish() (int, error) {

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

pc := &webrtc.PeerConnection{
ICEServers: iceServers,
HandshakeTimeout: s.parent.HandshakeTimeout,
TrackGatherTimeout: s.parent.TrackGatherTimeout,
IPsFromInterfaces: s.ipsFromInterfaces,
IPsFromInterfacesList: s.ipsFromInterfacesList,
AdditionalHosts: s.additionalHosts,
Expand Down
12 changes: 7 additions & 5 deletions internal/staticsources/webrtc/source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@ func TestSource(t *testing.T) {
ChannelCount: 2,
}}}
pc := &webrtc.PeerConnection{
LocalRandomUDP: true,
IPsFromInterfaces: true,
Publish: true,
OutgoingTracks: outgoingTracks,
Log: test.NilLogger,
LocalRandomUDP: true,
IPsFromInterfaces: true,
Publish: true,
HandshakeTimeout: conf.StringDuration(10 * time.Second),
TrackGatherTimeout: conf.StringDuration(2 * time.Second),
OutgoingTracks: outgoingTracks,
Log: test.NilLogger,
}
err := pc.Start()
require.NoError(t, err)
Expand Down
4 changes: 4 additions & 0 deletions mediamtx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,10 @@ webrtcICEServers2: []
# username: ''
# password: ''
# 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
Expand Down

0 comments on commit f03b44d

Please sign in to comment.