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:
parent
d21506182b
commit
e283725cde
11 changed files with 23 additions and 34 deletions
2
go.mod
2
go.mod
|
|
@ -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
4
go.sum
|
|
@ -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=
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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):
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
}(),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue