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
clientOnly:
type: boolean
webrtcHandshakeTimeout:
type: string
webrtcTrackGatherTimeout:
type: string
# SRT server
srt:

View File

@ -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
@ -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

View File

@ -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,
@ -848,6 +850,8 @@ func (p *Core) closeResources(newConf *conf.Conf, calledByAPI bool) {
!reflect.DeepEqual(newConf.WebRTCIPsFromInterfacesList, p.conf.WebRTCIPsFromInterfacesList) ||
!reflect.DeepEqual(newConf.WebRTCAdditionalHosts, p.conf.WebRTCAdditionalHosts) ||
!reflect.DeepEqual(newConf.WebRTCICEServers2, p.conf.WebRTCICEServers2) ||
newConf.WebRTCHandshakeTimeout != p.conf.WebRTCHandshakeTimeout ||
newConf.WebRTCTrackGatherTimeout != p.conf.WebRTCTrackGatherTimeout ||
closeMetrics ||
closePathManager ||
closeLogger

View File

@ -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 {
@ -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
@ -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:
@ -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 {

View File

@ -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)

View File

@ -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
@ -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 {
@ -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 {

View File

@ -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

View File

@ -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,
@ -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)
@ -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,
@ -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,

View File

@ -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,
@ -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,

View File

@ -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)

View File

@ -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