diff --git a/CHANGELOG.md b/CHANGELOG.md index 83e67de..3e8cafe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -- Nothing yet +### Added + +- InitSegment.TweakSingleTrakLive changes an init segment to fit live streaming ## [0.42.0] - 2024-01-26 diff --git a/mp4/initsegment.go b/mp4/initsegment.go index beb41da..0d06bb1 100644 --- a/mp4/initsegment.go +++ b/mp4/initsegment.go @@ -248,6 +248,29 @@ func (s *InitSegment) GetMediaType() string { } } +// TweakSingleTrakLive assures that there is only one track and removes any mehd box. +func (s *InitSegment) TweakSingleTrakLive() error { + if len(s.Moov.Traks) != 1 { + return fmt.Errorf("only one track allowed for live") + } + mvex := s.Moov.Mvex + if mvex == nil { + return fmt.Errorf("no mvex box found") + + } + mehd := mvex.Mehd + if mehd != nil { + for i, c := range mvex.Children { + if c == mehd { + mvex.Children = append(mvex.Children[:i], mvex.Children[i+1:]...) + mvex.Mehd = nil + break + } + } + } + return nil +} + // SetAACDescriptor - Modify a TrakBox by adding AAC SampleDescriptor // objType is one of AAClc, HEAACv1, HEAACv2 // For HEAAC, the samplingFrequency is the base frequency (normally 24000) diff --git a/mp4/initsegment_test.go b/mp4/initsegment_test.go index 13c8aaf..5da7f87 100644 --- a/mp4/initsegment_test.go +++ b/mp4/initsegment_test.go @@ -211,3 +211,37 @@ func TestGenerateInitSegment(t *testing.T) { t.Errorf("Generated init segment different from %s", goldenAssetPath) } } + +func TestInitTweakSingleTrakLive(t *testing.T) { + // Check that mehd box is removed and that multiple tracks is not allowed. + goldenAssetPath := "testdata/golden_init_video.mp4" + r, err := os.Open(goldenAssetPath) + if err != nil { + t.Error(err) + } + f, err := DecodeFile(r) + if err != nil { + t.Error(err) + } + moov := f.Init.Moov + mvex := moov.Mvex + mehd := MehdBox{ + FragmentDuration: 1000, + } + mvex.AddChild(&mehd) + err = f.Init.TweakSingleTrakLive() + if err != nil { + t.Error(err) + } + if mvex.Mehd != nil { + t.Errorf("Mehd not removed") + } + f.Init.AddEmptyTrack(180000, "video", "und") + err = f.Init.TweakSingleTrakLive() + wantedErrMsg := "only one track allowed for live" + if err == nil { + t.Errorf("Did not get error") + } else if err.Error() != wantedErrMsg { + t.Errorf(`Did not get error %q but %q"`, wantedErrMsg, err) + } +}