1
0
Fork 0
forked from External/mediamtx

support routing multichannel Opus between RTSP, SRT, HLS, UDP and recording in MPEG-TS and fMP4 (#3355) (#3368)

This commit is contained in:
Alessandro Ros 2024-05-19 14:38:57 +02:00 committed by GitHub
parent d21506182b
commit e283725cde
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 23 additions and 34 deletions

2
go.mod
View file

@ -9,7 +9,7 @@ require (
github.com/abema/go-mp4 v1.2.0 github.com/abema/go-mp4 v1.2.0
github.com/alecthomas/kong v0.9.0 github.com/alecthomas/kong v0.9.0
github.com/bluenviron/gohlslib v1.3.2 github.com/bluenviron/gohlslib v1.3.2
github.com/bluenviron/gortsplib/v4 v4.9.1-0.20240515082130-f283abc2e7cd github.com/bluenviron/gortsplib/v4 v4.9.1-0.20240518103134-27831ced0c04
github.com/bluenviron/mediacommon v1.10.1-0.20240518092051-bab50c4ba9c5 github.com/bluenviron/mediacommon v1.10.1-0.20240518092051-bab50c4ba9c5
github.com/datarhei/gosrt v0.6.0 github.com/datarhei/gosrt v0.6.0
github.com/fsnotify/fsnotify v1.7.0 github.com/fsnotify/fsnotify v1.7.0

4
go.sum
View file

@ -22,8 +22,8 @@ github.com/benburkert/openpgp v0.0.0-20160410205803-c2471f86866c h1:8XZeJrs4+ZYh
github.com/benburkert/openpgp v0.0.0-20160410205803-c2471f86866c/go.mod h1:x1vxHcL/9AVzuk5HOloOEPrtJY0MaalYr78afXZ+pWI= github.com/benburkert/openpgp v0.0.0-20160410205803-c2471f86866c/go.mod h1:x1vxHcL/9AVzuk5HOloOEPrtJY0MaalYr78afXZ+pWI=
github.com/bluenviron/gohlslib v1.3.2 h1:xRiPfMIeYCkspL6jYa7Qrl4pIY+1w7IvFjx49CsyfKY= github.com/bluenviron/gohlslib v1.3.2 h1:xRiPfMIeYCkspL6jYa7Qrl4pIY+1w7IvFjx49CsyfKY=
github.com/bluenviron/gohlslib v1.3.2/go.mod h1:1/m7A2o5IWyBdZeauXe2bViu2l1mL2l8DMQl9302A2U= github.com/bluenviron/gohlslib v1.3.2/go.mod h1:1/m7A2o5IWyBdZeauXe2bViu2l1mL2l8DMQl9302A2U=
github.com/bluenviron/gortsplib/v4 v4.9.1-0.20240515082130-f283abc2e7cd h1:w1Uml4bXdixu7cArQ3JyiZTpaKzZ31eP9+bWoPPkWcY= github.com/bluenviron/gortsplib/v4 v4.9.1-0.20240518103134-27831ced0c04 h1:r0O2Dl6g31cjpuPnjWMbvjY5z9AIoaftLW4328yJdXc=
github.com/bluenviron/gortsplib/v4 v4.9.1-0.20240515082130-f283abc2e7cd/go.mod h1:iLJ1tmwGMbaN04ZYh/KRlAHsCbz9Rycn7cPAvdR+Vkc= github.com/bluenviron/gortsplib/v4 v4.9.1-0.20240518103134-27831ced0c04/go.mod h1:iLJ1tmwGMbaN04ZYh/KRlAHsCbz9Rycn7cPAvdR+Vkc=
github.com/bluenviron/mediacommon v1.10.1-0.20240518092051-bab50c4ba9c5 h1:fZL+8Bz8wT0ljvt+ZyGGzirT1jQxH1wgqOiyRifAL60= github.com/bluenviron/mediacommon v1.10.1-0.20240518092051-bab50c4ba9c5 h1:fZL+8Bz8wT0ljvt+ZyGGzirT1jQxH1wgqOiyRifAL60=
github.com/bluenviron/mediacommon v1.10.1-0.20240518092051-bab50c4ba9c5/go.mod h1:HDyW2CzjvhYJXtdxstdFPio3G0qSocPhqkhUt/qffec= github.com/bluenviron/mediacommon v1.10.1-0.20240518092051-bab50c4ba9c5/go.mod h1:HDyW2CzjvhYJXtdxstdFPio3G0qSocPhqkhUt/qffec=
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=

View file

@ -165,12 +165,7 @@ func FromStream(
case *format.Opus: case *format.Opus:
track := addTrack(&mcmpegts.CodecOpus{ track := addTrack(&mcmpegts.CodecOpus{
ChannelCount: func() int { ChannelCount: forma.ChannelCount,
if forma.IsStereo {
return 2
}
return 1
}(),
}) })
stream.AddReader(writer, medi, forma, func(u unit.Unit) error { stream.AddReader(writer, medi, forma, func(u unit.Unit) error {

View file

@ -112,8 +112,8 @@ func ToStream(r *mpegts.Reader, stream **stream.Stream) ([]*description.Media, e
medi = &description.Media{ medi = &description.Media{
Type: description.MediaTypeAudio, Type: description.MediaTypeAudio,
Formats: []format.Format{&format.Opus{ Formats: []format.Format{&format.Opus{
PayloadTyp: 96, PayloadTyp: 96,
IsStereo: (codec.ChannelCount >= 2), ChannelCount: codec.ChannelCount,
}}, }},
} }

View file

@ -72,7 +72,12 @@ func newIncomingTrack(
case strings.ToLower(webrtc.MimeTypeOpus): case strings.ToLower(webrtc.MimeTypeOpus):
t.format = &format.Opus{ t.format = &format.Opus{
PayloadTyp: uint8(track.PayloadType()), PayloadTyp: uint8(track.PayloadType()),
IsStereo: strings.Contains(track.Codec().SDPFmtpLine, "stereo=1"), ChannelCount: func() int {
if strings.Contains(track.Codec().SDPFmtpLine, "stereo=1") {
return 2
}
return 1
}(),
} }
case strings.ToLower(webrtc.MimeTypeG722): case strings.ToLower(webrtc.MimeTypeG722):

View file

@ -594,12 +594,7 @@ func (f *formatFMP4) initialize() {
case *rtspformat.Opus: case *rtspformat.Opus:
codec := &fmp4.CodecOpus{ codec := &fmp4.CodecOpus{
ChannelCount: func() int { ChannelCount: forma.ChannelCount,
if forma.IsStereo {
return 2
}
return 1
}(),
} }
track := addTrack(forma, codec) track := addTrack(forma, codec)

View file

@ -184,12 +184,7 @@ func (f *formatMPEGTS) initialize() {
case *rtspformat.Opus: case *rtspformat.Opus:
track := addTrack(forma, &mpegts.CodecOpus{ track := addTrack(forma, &mpegts.CodecOpus{
ChannelCount: func() int { ChannelCount: forma.ChannelCount,
if forma.IsStereo {
return 2
}
return 1
}(),
}) })
f.a.agent.Stream.AddReader(f.a.writer, media, forma, func(u unit.Unit) error { f.a.agent.Stream.AddReader(f.a.writer, media, forma, func(u unit.Unit) error {

View file

@ -227,12 +227,7 @@ func (mi *muxerInstance) createAudioTrack() *gohlslib.Track {
return &gohlslib.Track{ return &gohlslib.Track{
Codec: &codecs.Opus{ Codec: &codecs.Opus{
ChannelCount: func() int { ChannelCount: audioFormatOpus.ChannelCount,
if audioFormatOpus.IsStereo {
return 2
}
return 1
}(),
}, },
} }
} }

View file

@ -215,6 +215,10 @@ func findAudioTrack(
if opusFormat != nil { if opusFormat != nil {
return opusFormat, func(track *webrtc.OutgoingTrack) error { return opusFormat, func(track *webrtc.OutgoingTrack) error {
if opusFormat.ChannelCount > 2 {
return fmt.Errorf("unsupported Opus channel count: %d", opusFormat.ChannelCount)
}
stream.AddReader(writer, media, opusFormat, func(u unit.Unit) error { stream.AddReader(writer, media, opusFormat, func(u unit.Unit) error {
for _, pkt := range u.GetRTPPackets() { for _, pkt := range u.GetRTPPackets() {
track.WriteRTP(pkt) //nolint:errcheck track.WriteRTP(pkt) //nolint:errcheck

View file

@ -180,8 +180,8 @@ func (s *Source) Run(params defs.StaticSourceRunParams) error {
medi = &description.Media{ medi = &description.Media{
Type: description.MediaTypeAudio, Type: description.MediaTypeAudio,
Formats: []format.Format{&format.Opus{ Formats: []format.Format{&format.Opus{
PayloadTyp: 96, PayloadTyp: 96,
IsStereo: (tcodec.ChannelCount >= 2), ChannelCount: tcodec.ChannelCount,
}}, }},
} }

View file

@ -45,8 +45,8 @@ func TestSource(t *testing.T) {
tracks, err := pc.SetupOutgoingTracks( tracks, err := pc.SetupOutgoingTracks(
nil, nil,
&format.Opus{ &format.Opus{
PayloadTyp: 111, PayloadTyp: 111,
IsStereo: true, ChannelCount: 2,
}, },
) )
require.NoError(t, err) require.NoError(t, err)