Browse Source

hls: prefer Opus tracks to MPEG-4 tracks (#2158)

pull/2159/head
Alessandro Ros 3 years ago committed by GitHub
parent
commit
d9b7878c3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 74
      internal/core/hls_muxer.go

74
internal/core/hls_muxer.go

@ -456,20 +456,16 @@ func (m *hlsMuxer) createVideoTrack(stream *stream.Stream) (*media.Media, *gohls
} }
func (m *hlsMuxer) createAudioTrack(stream *stream.Stream) (*media.Media, *gohlslib.Track) { func (m *hlsMuxer) createAudioTrack(stream *stream.Stream) (*media.Media, *gohlslib.Track) {
var audioFormatMPEG4AudioGeneric *formats.MPEG4AudioGeneric var audioFormatOpus *formats.Opus
audioMedia := stream.Medias().FindFormat(&audioFormatMPEG4AudioGeneric) audioMedia := stream.Medias().FindFormat(&audioFormatOpus)
if audioMedia != nil { if audioMedia != nil {
audioStartPTSFilled := false audioStartPTSFilled := false
var audioStartPTS time.Duration var audioStartPTS time.Duration
stream.AddReader(m, audioMedia, audioFormatMPEG4AudioGeneric, func(unit formatprocessor.Unit) { stream.AddReader(m, audioMedia, audioFormatOpus, func(unit formatprocessor.Unit) {
m.ringBuffer.Push(func() error { m.ringBuffer.Push(func() error {
tunit := unit.(*formatprocessor.UnitMPEG4AudioGeneric) tunit := unit.(*formatprocessor.UnitOpus)
if tunit.AUs == nil {
return nil
}
if !audioStartPTSFilled { if !audioStartPTSFilled {
audioStartPTSFilled = true audioStartPTSFilled = true
@ -477,10 +473,10 @@ func (m *hlsMuxer) createAudioTrack(stream *stream.Stream) (*media.Media, *gohls
} }
pts := tunit.PTS - audioStartPTS pts := tunit.PTS - audioStartPTS
err := m.muxer.WriteMPEG4Audio( err := m.muxer.WriteOpus(
tunit.NTP, tunit.NTP,
pts, pts,
tunit.AUs) tunit.Packets)
if err != nil { if err != nil {
return fmt.Errorf("muxer error: %v", err) return fmt.Errorf("muxer error: %v", err)
} }
@ -490,27 +486,29 @@ func (m *hlsMuxer) createAudioTrack(stream *stream.Stream) (*media.Media, *gohls
}) })
return audioMedia, &gohlslib.Track{ return audioMedia, &gohlslib.Track{
Codec: &codecs.MPEG4Audio{ Codec: &codecs.Opus{
Config: *audioFormatMPEG4AudioGeneric.Config, ChannelCount: func() int {
if audioFormatOpus.IsStereo {
return 2
}
return 1
}(),
}, },
} }
} }
var audioFormatMPEG4AudioLATM *formats.MPEG4AudioLATM var audioFormatMPEG4AudioGeneric *formats.MPEG4AudioGeneric
audioMedia = stream.Medias().FindFormat(&audioFormatMPEG4AudioLATM) audioMedia = stream.Medias().FindFormat(&audioFormatMPEG4AudioGeneric)
if audioMedia != nil && if audioMedia != nil {
audioFormatMPEG4AudioLATM.Config != nil &&
len(audioFormatMPEG4AudioLATM.Config.Programs) == 1 &&
len(audioFormatMPEG4AudioLATM.Config.Programs[0].Layers) == 1 {
audioStartPTSFilled := false audioStartPTSFilled := false
var audioStartPTS time.Duration var audioStartPTS time.Duration
stream.AddReader(m, audioMedia, audioFormatMPEG4AudioLATM, func(unit formatprocessor.Unit) { stream.AddReader(m, audioMedia, audioFormatMPEG4AudioGeneric, func(unit formatprocessor.Unit) {
m.ringBuffer.Push(func() error { m.ringBuffer.Push(func() error {
tunit := unit.(*formatprocessor.UnitMPEG4AudioLATM) tunit := unit.(*formatprocessor.UnitMPEG4AudioGeneric)
if tunit.AU == nil { if tunit.AUs == nil {
return nil return nil
} }
@ -523,7 +521,7 @@ func (m *hlsMuxer) createAudioTrack(stream *stream.Stream) (*media.Media, *gohls
err := m.muxer.WriteMPEG4Audio( err := m.muxer.WriteMPEG4Audio(
tunit.NTP, tunit.NTP,
pts, pts,
[][]byte{tunit.AU}) tunit.AUs)
if err != nil { if err != nil {
return fmt.Errorf("muxer error: %v", err) return fmt.Errorf("muxer error: %v", err)
} }
@ -534,21 +532,28 @@ func (m *hlsMuxer) createAudioTrack(stream *stream.Stream) (*media.Media, *gohls
return audioMedia, &gohlslib.Track{ return audioMedia, &gohlslib.Track{
Codec: &codecs.MPEG4Audio{ Codec: &codecs.MPEG4Audio{
Config: *audioFormatMPEG4AudioLATM.Config.Programs[0].Layers[0].AudioSpecificConfig, Config: *audioFormatMPEG4AudioGeneric.Config,
}, },
} }
} }
var audioFormatOpus *formats.Opus var audioFormatMPEG4AudioLATM *formats.MPEG4AudioLATM
audioMedia = stream.Medias().FindFormat(&audioFormatOpus) audioMedia = stream.Medias().FindFormat(&audioFormatMPEG4AudioLATM)
if audioMedia != nil { if audioMedia != nil &&
audioFormatMPEG4AudioLATM.Config != nil &&
len(audioFormatMPEG4AudioLATM.Config.Programs) == 1 &&
len(audioFormatMPEG4AudioLATM.Config.Programs[0].Layers) == 1 {
audioStartPTSFilled := false audioStartPTSFilled := false
var audioStartPTS time.Duration var audioStartPTS time.Duration
stream.AddReader(m, audioMedia, audioFormatOpus, func(unit formatprocessor.Unit) { stream.AddReader(m, audioMedia, audioFormatMPEG4AudioLATM, func(unit formatprocessor.Unit) {
m.ringBuffer.Push(func() error { m.ringBuffer.Push(func() error {
tunit := unit.(*formatprocessor.UnitOpus) tunit := unit.(*formatprocessor.UnitMPEG4AudioLATM)
if tunit.AU == nil {
return nil
}
if !audioStartPTSFilled { if !audioStartPTSFilled {
audioStartPTSFilled = true audioStartPTSFilled = true
@ -556,10 +561,10 @@ func (m *hlsMuxer) createAudioTrack(stream *stream.Stream) (*media.Media, *gohls
} }
pts := tunit.PTS - audioStartPTS pts := tunit.PTS - audioStartPTS
err := m.muxer.WriteOpus( err := m.muxer.WriteMPEG4Audio(
tunit.NTP, tunit.NTP,
pts, pts,
tunit.Packets) [][]byte{tunit.AU})
if err != nil { if err != nil {
return fmt.Errorf("muxer error: %v", err) return fmt.Errorf("muxer error: %v", err)
} }
@ -569,13 +574,8 @@ func (m *hlsMuxer) createAudioTrack(stream *stream.Stream) (*media.Media, *gohls
}) })
return audioMedia, &gohlslib.Track{ return audioMedia, &gohlslib.Track{
Codec: &codecs.Opus{ Codec: &codecs.MPEG4Audio{
ChannelCount: func() int { Config: *audioFormatMPEG4AudioLATM.Config.Programs[0].Layers[0].AudioSpecificConfig,
if audioFormatOpus.IsStereo {
return 2
}
return 1
}(),
}, },
} }
} }

Loading…
Cancel
Save