diff --git a/internal/core/webrtc_http_server.go b/internal/core/webrtc_http_server.go index 4d4a5606..f7edd842 100644 --- a/internal/core/webrtc_http_server.go +++ b/internal/core/webrtc_http_server.go @@ -304,6 +304,7 @@ func (s *webRTCHTTPServer) onRequest(ctx *gin.Context) { videoCodec: ctx.Query("video_codec"), audioCodec: ctx.Query("audio_codec"), videoBitrate: ctx.Query("video_bitrate"), + audioBitrate: ctx.Query("audio_bitrate"), }) if res.err != nil { if res.errStatusCode != 0 { diff --git a/internal/core/webrtc_manager.go b/internal/core/webrtc_manager.go index c29f45bf..23f85bad 100644 --- a/internal/core/webrtc_manager.go +++ b/internal/core/webrtc_manager.go @@ -137,6 +137,7 @@ type webRTCSessionNewReq struct { videoCodec string audioCodec string videoBitrate string + audioBitrate string res chan webRTCSessionNewRes } diff --git a/internal/core/webrtc_pc.go b/internal/core/webrtc_pc.go index 14a35dcb..e2a28ecb 100644 --- a/internal/core/webrtc_pc.go +++ b/internal/core/webrtc_pc.go @@ -11,6 +11,82 @@ import ( "github.com/bluenviron/mediamtx/internal/logger" ) +var videoCodecs = map[string][]webrtc.RTPCodecParameters{ + "av1": {{ + RTPCodecCapability: webrtc.RTPCodecCapability{ + MimeType: webrtc.MimeTypeAV1, + ClockRate: 90000, + }, + PayloadType: 96, + }}, + "vp9": { + { + RTPCodecCapability: webrtc.RTPCodecCapability{ + MimeType: webrtc.MimeTypeVP9, + ClockRate: 90000, + SDPFmtpLine: "profile-id=0", + }, + PayloadType: 96, + }, + { + RTPCodecCapability: webrtc.RTPCodecCapability{ + MimeType: webrtc.MimeTypeVP9, + ClockRate: 90000, + SDPFmtpLine: "profile-id=1", + }, + PayloadType: 96, + }, + }, + "vp8": {{ + RTPCodecCapability: webrtc.RTPCodecCapability{ + MimeType: webrtc.MimeTypeVP8, + ClockRate: 90000, + }, + PayloadType: 96, + }}, + "h264": {{ + RTPCodecCapability: webrtc.RTPCodecCapability{ + MimeType: webrtc.MimeTypeH264, + ClockRate: 90000, + SDPFmtpLine: "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f", + }, + PayloadType: 96, + }}, +} + +var audioCodecs = map[string][]webrtc.RTPCodecParameters{ + "opus": {{ + RTPCodecCapability: webrtc.RTPCodecCapability{ + MimeType: webrtc.MimeTypeOpus, + ClockRate: 48000, + Channels: 2, + SDPFmtpLine: "minptime=10;useinbandfec=1", + }, + PayloadType: 111, + }}, + "g722": {{ + RTPCodecCapability: webrtc.RTPCodecCapability{ + MimeType: webrtc.MimeTypeG722, + ClockRate: 8000, + }, + PayloadType: 9, + }}, + "pcmu": {{ + RTPCodecCapability: webrtc.RTPCodecCapability{ + MimeType: webrtc.MimeTypePCMU, + ClockRate: 8000, + }, + PayloadType: 0, + }}, + "pcma": {{ + RTPCodecCapability: webrtc.RTPCodecCapability{ + MimeType: webrtc.MimeTypePCMA, + ClockRate: 8000, + }, + PayloadType: 8, + }}, +} + type peerConnection struct { *webrtc.PeerConnection stateChangeMutex sync.Mutex @@ -49,156 +125,42 @@ func newPeerConnection( mediaEngine := &webrtc.MediaEngine{} if videoCodec != "" || audioCodec != "" { - switch videoCodec { - case "av1": - err := mediaEngine.RegisterCodec( - webrtc.RTPCodecParameters{ - RTPCodecCapability: webrtc.RTPCodecCapability{ - MimeType: webrtc.MimeTypeAV1, - ClockRate: 90000, - }, - PayloadType: 96, - }, - webrtc.RTPCodecTypeVideo) - if err != nil { - return nil, err - } - - case "vp9": - err := mediaEngine.RegisterCodec( - webrtc.RTPCodecParameters{ - RTPCodecCapability: webrtc.RTPCodecCapability{ - MimeType: webrtc.MimeTypeVP9, - ClockRate: 90000, - SDPFmtpLine: "profile-id=0", - }, - PayloadType: 96, - }, - webrtc.RTPCodecTypeVideo) - if err != nil { - return nil, err - } - - err = mediaEngine.RegisterCodec( - webrtc.RTPCodecParameters{ - RTPCodecCapability: webrtc.RTPCodecCapability{ - MimeType: webrtc.MimeTypeVP9, - ClockRate: 90000, - SDPFmtpLine: "profile-id=1", - }, - PayloadType: 96, - }, - webrtc.RTPCodecTypeVideo) - if err != nil { - return nil, err - } - - case "vp8": - err := mediaEngine.RegisterCodec( - webrtc.RTPCodecParameters{ - RTPCodecCapability: webrtc.RTPCodecCapability{ - MimeType: webrtc.MimeTypeVP8, - ClockRate: 90000, - }, - PayloadType: 96, - }, - webrtc.RTPCodecTypeVideo) - if err != nil { - return nil, err - } - - case "h264": - err := mediaEngine.RegisterCodec( - webrtc.RTPCodecParameters{ - RTPCodecCapability: webrtc.RTPCodecCapability{ - MimeType: webrtc.MimeTypeH264, - ClockRate: 90000, - SDPFmtpLine: "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f", - }, - PayloadType: 96, - }, - webrtc.RTPCodecTypeVideo) - if err != nil { - return nil, err + codec, ok := videoCodecs[videoCodec] + if ok { + for _, params := range codec { + err := mediaEngine.RegisterCodec(params, webrtc.RTPCodecTypeVideo) + if err != nil { + return nil, err + } } } - switch audioCodec { - case "opus": - err := mediaEngine.RegisterCodec( - webrtc.RTPCodecParameters{ - RTPCodecCapability: webrtc.RTPCodecCapability{ - MimeType: webrtc.MimeTypeOpus, - ClockRate: 48000, - Channels: 2, - SDPFmtpLine: "minptime=10;useinbandfec=1", - }, - PayloadType: 111, - }, - webrtc.RTPCodecTypeAudio) - if err != nil { - return nil, err - } - - case "g722": - err := mediaEngine.RegisterCodec( - webrtc.RTPCodecParameters{ - RTPCodecCapability: webrtc.RTPCodecCapability{ - MimeType: webrtc.MimeTypeG722, - ClockRate: 8000, - }, - PayloadType: 9, - }, - webrtc.RTPCodecTypeAudio) - if err != nil { - return nil, err - } - - case "pcmu": - err := mediaEngine.RegisterCodec( - webrtc.RTPCodecParameters{ - RTPCodecCapability: webrtc.RTPCodecCapability{ - MimeType: webrtc.MimeTypePCMU, - ClockRate: 8000, - }, - PayloadType: 0, - }, - webrtc.RTPCodecTypeAudio) - if err != nil { - return nil, err - } - - case "pcma": - err := mediaEngine.RegisterCodec( - webrtc.RTPCodecParameters{ - RTPCodecCapability: webrtc.RTPCodecCapability{ - MimeType: webrtc.MimeTypePCMA, - ClockRate: 8000, - }, - PayloadType: 8, - }, - webrtc.RTPCodecTypeAudio) - if err != nil { - return nil, err + codec, ok = audioCodecs[audioCodec] + if ok { + for _, params := range codec { + err := mediaEngine.RegisterCodec(params, webrtc.RTPCodecTypeAudio) + if err != nil { + return nil, err + } } } - } else { - // register all codecs - err := mediaEngine.RegisterDefaultCodecs() - if err != nil { - return nil, err + } else { // register all codecs + for _, codec := range videoCodecs { + for _, params := range codec { + err := mediaEngine.RegisterCodec(params, webrtc.RTPCodecTypeVideo) + if err != nil { + return nil, err + } + } } - err = mediaEngine.RegisterCodec( - webrtc.RTPCodecParameters{ - RTPCodecCapability: webrtc.RTPCodecCapability{ - MimeType: webrtc.MimeTypeAV1, - ClockRate: 90000, - }, - PayloadType: 105, - }, - webrtc.RTPCodecTypeVideo) - if err != nil { - return nil, err + + for _, codec := range audioCodecs { + for _, params := range codec { + err := mediaEngine.RegisterCodec(params, webrtc.RTPCodecTypeAudio) + if err != nil { + return nil, err + } + } } } diff --git a/internal/core/webrtc_publish_index.html b/internal/core/webrtc_publish_index.html index 6792d4ce..44adf3dc 100644 --- a/internal/core/webrtc_publish_index.html +++ b/internal/core/webrtc_publish_index.html @@ -72,6 +72,9 @@ select {