diff --git a/internal/hls/client_downloader_primary.go b/internal/hls/client_downloader_primary.go index 7128c5a3..e930ac72 100644 --- a/internal/hls/client_downloader_primary.go +++ b/internal/hls/client_downloader_primary.go @@ -43,20 +43,10 @@ func clientDownloadPlaylist(ctx context.Context, httpClient *http.Client, ur *ur return m3u8.Unmarshal(byts) } -func allCodecsAreSupported(codecs string) bool { - for _, codec := range strings.Split(codecs, ",") { - if !strings.HasPrefix(codec, "avc1") && - !strings.HasPrefix(codec, "mp4a") { - return false - } - } - return true -} - func pickLeadingPlaylist(variants []*gm3u8.Variant) *gm3u8.Variant { var candidates []*gm3u8.Variant //nolint:prealloc for _, v := range variants { - if v.Codecs != "" && !allCodecsAreSupported(v.Codecs) { + if v.Codecs != "" && !codecParametersAreSupported(v.Codecs) { continue } candidates = append(candidates, v) diff --git a/internal/hls/client_processor_fmp4.go b/internal/hls/client_processor_fmp4.go index e56137ec..37dda07c 100644 --- a/internal/hls/client_processor_fmp4.go +++ b/internal/hls/client_processor_fmp4.go @@ -146,7 +146,7 @@ func (p *clientProcessorFMP4) processSegment(ctx context.Context, byts []byte) e proc, ok := p.trackProcs[track.ID] if !ok { - return fmt.Errorf("track ID %d not present in init file", track.ID) + continue } if processingCount >= (clientFMP4MaxPartTracksPerSegment - 1) { diff --git a/internal/hls/codecparameters.go b/internal/hls/codecparameters.go new file mode 100644 index 00000000..b86ea559 --- /dev/null +++ b/internal/hls/codecparameters.go @@ -0,0 +1,47 @@ +package hls + +import ( + "encoding/hex" + "strconv" + "strings" + + "github.com/aler9/gortsplib/v2/pkg/codecs/h265" + "github.com/aler9/gortsplib/v2/pkg/format" +) + +func codecParametersGenerate(track format.Format) string { + switch ttrack := track.(type) { + case *format.H264: + sps := ttrack.SafeSPS() + if len(sps) >= 4 { + return "avc1." + hex.EncodeToString(sps[1:4]) + } + + case *format.H265: + var sps h265.SPS + err := sps.Unmarshal(ttrack.SafeSPS()) + if err == nil { + return "hvc1." + strconv.FormatInt(int64(sps.ProfileTierLevel.GeneralProfileIdc), 10) + + ".4.L" + strconv.FormatInt(int64(sps.ProfileTierLevel.GeneralLevelIdc), 10) + ".B0" + } + + case *format.MPEG4Audio: + // https://developer.mozilla.org/en-US/docs/Web/Media/Formats/codecs_parameter + return "mp4a.40." + strconv.FormatInt(int64(ttrack.Config.Type), 10) + + case *format.Opus: + return "opus" + } + + return "" +} + +func codecParametersAreSupported(codecs string) bool { + for _, codec := range strings.Split(codecs, ",") { + if !strings.HasPrefix(codec, "avc1.") && + !strings.HasPrefix(codec, "mp4a.") { + return false + } + } + return true +} diff --git a/internal/hls/fmp4/init.go b/internal/hls/fmp4/init.go index 1ec9ba74..9ccf3e0e 100644 --- a/internal/hls/fmp4/init.go +++ b/internal/hls/fmp4/init.go @@ -221,9 +221,6 @@ func (i *Init) Unmarshal(byts []byte) error { } state = waitingTrak - case "ac-3": - return nil, fmt.Errorf("AC-3 codec is not supported (yet)") - case "Opus": if state != waitingCodec { return nil, fmt.Errorf("unexpected box 'Opus'") @@ -247,6 +244,24 @@ func (i *Init) Unmarshal(byts []byte) error { ChannelCount: int(dops.OutputChannelCount), } state = waitingTrak + + case "ac-3": // ac-3, not supported yet + i.Tracks = i.Tracks[:len(i.Tracks)-1] + state = waitingTrak + return nil, nil + + case "ec-3": // ec-3, not supported yet + i.Tracks = i.Tracks[:len(i.Tracks)-1] + state = waitingTrak + return nil, nil + + case "c608", "c708": // closed captions, not supported yet + i.Tracks = i.Tracks[:len(i.Tracks)-1] + state = waitingTrak + return nil, nil + + case "chrm", "nmhd": + return nil, nil } return h.Expand() @@ -259,7 +274,7 @@ func (i *Init) Unmarshal(byts []byte) error { return fmt.Errorf("parse error") } - if i.Tracks == nil { + if len(i.Tracks) == 0 { return fmt.Errorf("no tracks found") } diff --git a/internal/hls/fmp4/init_test.go b/internal/hls/fmp4/init_test.go index dadae46b..ced6d84f 100644 --- a/internal/hls/fmp4/init_test.go +++ b/internal/hls/fmp4/init_test.go @@ -684,247 +684,587 @@ func TestInitUnmarshal(t *testing.T) { } func TestInitUnmarshalExternal(t *testing.T) { - t.Run("h264", func(t *testing.T) { - byts := []byte{ - 0x00, 0x00, 0x00, 0x1c, - 'f', 't', 'y', 'p', - 0x64, 0x61, 0x73, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x69, 0x73, 0x6f, 0x6d, 0x61, 0x76, 0x63, 0x31, - 0x64, 0x61, 0x73, 0x68, 0x00, 0x00, 0x02, 0x92, - 'm', 'o', 'o', 'v', - 0x00, 0x00, 0x00, 0x6c, - 'm', 'v', 'h', 'd', - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x98, 0x96, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x01, 0xf6, - 't', 'r', 'a', 'k', - 0x00, 0x00, 0x00, 0x5c, - 't', 'k', 'h', 'd', - 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, - 0x02, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x92, - 'm', 'd', 'i', 'a', - 0x00, 0x00, 0x00, 0x20, - 'm', 'd', 'h', 'd', - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x98, 0x96, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x55, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, - 'h', 'd', 'l', 'r', - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x76, 0x69, 0x64, 0x65, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x42, 0x72, 0x6f, 0x61, - 0x64, 0x70, 0x65, 0x61, 0x6b, 0x20, 0x56, 0x69, - 0x64, 0x65, 0x6f, 0x20, 0x48, 0x61, 0x6e, 0x64, - 0x6c, 0x65, 0x72, 0x00, 0x00, 0x00, 0x01, 0x32, - 'm', 'i', 'n', 'f', - 0x00, 0x00, 0x00, 0x14, - 'v', 'm', 'h', 'd', - 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x24, - 'd', 'i', 'n', 'f', - 0x00, 0x00, 0x00, 0x1c, 0x64, 0x72, 0x65, 0x66, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x0c, 0x75, 0x72, 0x6c, 0x20, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xf2, - 0x73, 0x74, 0x62, 0x6c, 0x00, 0x00, 0x00, 0xa6, - 0x73, 0x74, 0x73, 0x64, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x96, - 0x61, 0x76, 0x63, 0x31, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x02, 0x1c, - 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x68, - 0x32, 0x36, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x30, 0x61, 0x76, - 0x63, 0x43, 0x01, 0x42, 0xc0, 0x1f, 0xff, 0xe1, - 0x00, 0x19, 0x67, 0x42, 0xc0, 0x1f, 0xd9, 0x00, - 0xf0, 0x11, 0x7e, 0xf0, 0x11, 0x00, 0x00, 0x03, - 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x30, 0x8f, - 0x18, 0x32, 0x48, 0x01, 0x00, 0x04, 0x68, 0xcb, - 0x8c, 0xb2, 0x00, 0x00, 0x00, 0x10, 0x70, 0x61, - 0x73, 0x70, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x73, 0x74, - 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x73, 0x74, - 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x73, 0x74, - 0x73, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x73, 0x74, 0x63, 0x6f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x28, 0x6d, 0x76, 0x65, 0x78, 0x00, 0x00, - 0x00, 0x20, 0x74, 0x72, 0x65, 0x78, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - } - - var init Init - err := init.Unmarshal(byts) - require.NoError(t, err) - - require.Equal(t, Init{ - Tracks: []*InitTrack{ - { - ID: 256, - TimeScale: 10000000, + for _, ca := range []struct { + name string + byts []byte + init Init + }{ + { + "h264", + []byte{ + 0x00, 0x00, 0x00, 0x1c, + 'f', 't', 'y', 'p', + 0x64, 0x61, 0x73, 0x68, 0x00, 0x00, 0x00, 0x01, + 0x69, 0x73, 0x6f, 0x6d, 0x61, 0x76, 0x63, 0x31, + 0x64, 0x61, 0x73, 0x68, 0x00, 0x00, 0x02, 0x92, + 'm', 'o', 'o', 'v', + 0x00, 0x00, 0x00, 0x6c, + 'm', 'v', 'h', 'd', + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x98, 0x96, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x01, 0xf6, + 't', 'r', 'a', 'k', + 0x00, 0x00, 0x00, 0x5c, + 't', 'k', 'h', 'd', + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, + 0x02, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x92, + 'm', 'd', 'i', 'a', + 0x00, 0x00, 0x00, 0x20, + 'm', 'd', 'h', 'd', + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x98, 0x96, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x55, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, + 'h', 'd', 'l', 'r', + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x76, 0x69, 0x64, 0x65, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x42, 0x72, 0x6f, 0x61, + 0x64, 0x70, 0x65, 0x61, 0x6b, 0x20, 0x56, 0x69, + 0x64, 0x65, 0x6f, 0x20, 0x48, 0x61, 0x6e, 0x64, + 0x6c, 0x65, 0x72, 0x00, 0x00, 0x00, 0x01, 0x32, + 'm', 'i', 'n', 'f', + 0x00, 0x00, 0x00, 0x14, + 'v', 'm', 'h', 'd', + 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x24, + 'd', 'i', 'n', 'f', + 0x00, 0x00, 0x00, 0x1c, 0x64, 0x72, 0x65, 0x66, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x0c, 0x75, 0x72, 0x6c, 0x20, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xf2, + 0x73, 0x74, 0x62, 0x6c, 0x00, 0x00, 0x00, 0xa6, + 0x73, 0x74, 0x73, 0x64, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x96, + 0x61, 0x76, 0x63, 0x31, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x02, 0x1c, + 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x68, + 0x32, 0x36, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x30, 0x61, 0x76, + 0x63, 0x43, 0x01, 0x42, 0xc0, 0x1f, 0xff, 0xe1, + 0x00, 0x19, 0x67, 0x42, 0xc0, 0x1f, 0xd9, 0x00, + 0xf0, 0x11, 0x7e, 0xf0, 0x11, 0x00, 0x00, 0x03, + 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x30, 0x8f, + 0x18, 0x32, 0x48, 0x01, 0x00, 0x04, 0x68, 0xcb, + 0x8c, 0xb2, 0x00, 0x00, 0x00, 0x10, 0x70, 0x61, + 0x73, 0x70, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x73, 0x74, + 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x73, 0x74, + 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x73, 0x74, + 0x73, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x73, 0x74, 0x63, 0x6f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x6d, 0x76, 0x65, 0x78, 0x00, 0x00, + 0x00, 0x20, 0x74, 0x72, 0x65, 0x78, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + Init{ + Tracks: []*InitTrack{ + { + ID: 256, + TimeScale: 10000000, + Format: &format.H264{ + PayloadTyp: 96, + SPS: []byte{ + 0x67, 0x42, 0xc0, 0x1f, 0xd9, 0x00, 0xf0, 0x11, + 0x7e, 0xf0, 0x11, 0x00, 0x00, 0x03, 0x00, 0x01, + 0x00, 0x00, 0x03, 0x00, 0x30, 0x8f, 0x18, 0x32, + 0x48, + }, + PPS: []byte{ + 0x68, 0xcb, 0x8c, 0xb2, + }, + PacketizationMode: 1, + }, + }, + }, + }, + }, + { + "mpeg4audio", + []byte{ + 0x00, 0x00, 0x00, 0x18, + 'f', 't', 'y', 'p', + 0x69, 0x73, 0x6f, 0x35, 0x00, 0x00, 0x00, 0x01, + 0x69, 0x73, 0x6f, 0x35, 0x64, 0x61, 0x73, 0x68, + 0x00, 0x00, 0x02, 0x43, + 'm', 'o', 'o', 'v', + 0x00, 0x00, 0x00, 0x6c, + 'm', 'v', 'h', 'd', + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x96, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0xa7, + 't', 'r', 'a', 'k', + 0x00, 0x00, 0x00, 0x5c, + 't', 'k', 'h', 'd', + 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x43, + 'm', 'd', 'i', 'a', + 0x00, 0x00, 0x00, 0x20, + 'm', 'd', 'h', 'd', + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x96, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x55, 0xc4, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x38, + 'h', 'd', 'l', 'r', + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x73, 0x6f, 0x75, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x72, 0x6f, 0x61, 0x64, 0x70, 0x65, 0x61, + 0x6b, 0x20, 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x20, + 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x00, + 0x00, 0x00, 0x00, 0xe3, + 'm', 'i', 'n', 'f', + 0x00, 0x00, 0x00, 0x10, + 's', 'm', 'h', 'd', + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x24, + 'd', 'i', 'n', 'f', + 0x00, 0x00, 0x00, 0x1c, 0x64, 0x72, 0x65, 0x66, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x0c, 0x75, 0x72, 0x6c, 0x20, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa7, + 0x73, 0x74, 0x62, 0x6c, 0x00, 0x00, 0x00, 0x5b, + 0x73, 0x74, 0x73, 0x64, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4b, + 0x6d, 0x70, 0x34, 0x61, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0xbb, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x27, 0x65, 0x73, 0x64, 0x73, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x19, 0x00, 0x00, + 0x00, 0x04, 0x11, 0x40, 0x15, 0x00, 0x30, 0x00, + 0x00, 0x11, 0x94, 0x00, 0x00, 0x11, 0x94, 0x00, + 0x05, 0x02, 0x11, 0x90, 0x06, 0x01, 0x02, 0x00, + 0x00, 0x00, 0x10, 0x73, 0x74, 0x74, 0x73, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x73, 0x74, 0x73, 0x63, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x73, 0x74, 0x73, 0x7a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x73, + 0x74, 0x63, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6d, + 0x76, 0x65, 0x78, 0x00, 0x00, 0x00, 0x20, 0x74, + 0x72, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + }, + Init{ + Tracks: []*InitTrack{ + { + ID: 257, + TimeScale: 10000000, + Format: &format.MPEG4Audio{ + PayloadTyp: 96, + Config: &mpeg4audio.Config{ + Type: mpeg4audio.ObjectTypeAACLC, + SampleRate: 48000, + ChannelCount: 2, + }, + SizeLength: 13, + IndexLength: 3, + IndexDeltaLength: 3, + }, + }, + }, + }, + }, + { + "ignored closed captions", + []byte{ + 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, + 0x6d, 0x70, 0x34, 0x32, 0x00, 0x00, 0x00, 0x01, + 0x6d, 0x70, 0x34, 0x31, 0x6d, 0x70, 0x34, 0x32, + 0x69, 0x73, 0x6f, 0x6d, 0x68, 0x6c, 0x73, 0x66, + 0x00, 0x00, 0x04, 0x3f, 0x6d, 0x6f, 0x6f, 0x76, + 0x00, 0x00, 0x00, 0x6c, 0x6d, 0x76, 0x68, 0x64, + 0x00, 0x00, 0x00, 0x00, 0xd5, 0x5b, 0xc6, 0x62, + 0xd5, 0x5b, 0xc6, 0x62, 0x00, 0x00, 0x02, 0x58, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x19, + 0x74, 0x72, 0x61, 0x6b, 0x00, 0x00, 0x00, 0x5c, + 0x74, 0x6b, 0x68, 0x64, 0x00, 0x00, 0x00, 0x01, + 0xd5, 0x5b, 0xc6, 0x62, 0xd5, 0x5b, 0xc6, 0x62, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x07, 0x80, 0x00, 0x00, 0x04, 0x38, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xb5, 0x6d, 0x64, 0x69, 0x61, + 0x00, 0x00, 0x00, 0x20, 0x6d, 0x64, 0x68, 0x64, + 0x00, 0x00, 0x00, 0x00, 0xd5, 0x5b, 0xc6, 0x62, + 0xd5, 0x5b, 0xc6, 0x62, 0x00, 0x00, 0x17, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x15, 0xc7, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x68, 0x64, 0x6c, 0x72, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x76, 0x69, 0x64, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x43, 0x6f, 0x72, 0x65, 0x20, 0x4d, 0x65, 0x64, + 0x69, 0x61, 0x20, 0x56, 0x69, 0x64, 0x65, 0x6f, + 0x00, 0x00, 0x00, 0x01, 0x5c, 0x6d, 0x69, 0x6e, + 0x66, 0x00, 0x00, 0x00, 0x14, 0x76, 0x6d, 0x68, + 0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x64, 0x69, 0x6e, 0x66, 0x00, 0x00, 0x00, + 0x1c, 0x64, 0x72, 0x65, 0x66, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0c, 0x75, 0x72, 0x6c, 0x20, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x01, 0x1c, 0x73, 0x74, 0x62, + 0x6c, 0x00, 0x00, 0x00, 0xd0, 0x73, 0x74, 0x73, + 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0xc0, 0x61, 0x76, 0x63, + 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x80, 0x04, 0x38, 0x00, 0x48, 0x00, + 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x33, 0x61, 0x76, 0x63, 0x43, 0x01, + 0x64, 0x00, 0x2a, 0xff, 0xe1, 0x00, 0x1b, 0x27, + 0x64, 0x00, 0x2a, 0xac, 0x52, 0x14, 0x07, 0x80, + 0x22, 0x7e, 0x5f, 0xfc, 0x00, 0x04, 0x00, 0x05, + 0xa8, 0x08, 0x08, 0x0d, 0xb6, 0x15, 0xaf, 0x7b, + 0xe0, 0x20, 0x01, 0x00, 0x05, 0x28, 0xf9, 0x09, + 0x09, 0xcb, 0x00, 0x00, 0x00, 0x13, 0x63, 0x6f, + 0x6c, 0x72, 0x6e, 0x63, 0x6c, 0x78, 0x00, 0x01, + 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x63, 0x68, 0x72, 0x6d, 0x01, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x70, 0x61, 0x73, + 0x70, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x73, 0x74, 0x74, + 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x73, 0x74, 0x73, + 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x73, 0x74, 0x73, + 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x73, 0x74, 0x63, 0x6f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x6a, 0x74, 0x72, 0x61, 0x6b, 0x00, 0x00, 0x00, + 0x5c, 0x74, 0x6b, 0x68, 0x64, 0x00, 0x00, 0x00, + 0x01, 0xd5, 0x5b, 0xc6, 0x62, 0xd5, 0x5b, 0xc6, + 0x62, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x06, 0x6d, 0x64, 0x69, + 0x61, 0x00, 0x00, 0x00, 0x20, 0x6d, 0x64, 0x68, + 0x64, 0x00, 0x00, 0x00, 0x00, 0xd5, 0x5b, 0xc6, + 0x62, 0xd5, 0x5b, 0xc6, 0x62, 0x00, 0x00, 0x75, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x15, 0xc7, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3a, 0x68, 0x64, 0x6c, + 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x63, 0x6c, 0x63, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x4d, 0x65, + 0x64, 0x69, 0x61, 0x20, 0x43, 0x6c, 0x6f, 0x73, + 0x65, 0x64, 0x20, 0x43, 0x61, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x6d, + 0x69, 0x6e, 0x66, 0x00, 0x00, 0x00, 0x0c, 0x6e, + 0x6d, 0x68, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x24, 0x64, 0x69, 0x6e, 0x66, 0x00, + 0x00, 0x00, 0x1c, 0x64, 0x72, 0x65, 0x66, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x0c, 0x75, 0x72, 0x6c, 0x20, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x6c, 0x73, + 0x74, 0x62, 0x6c, 0x00, 0x00, 0x00, 0x20, 0x73, + 0x74, 0x73, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x63, + 0x36, 0x30, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x73, + 0x74, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x73, + 0x74, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x73, + 0x74, 0x73, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x73, 0x74, 0x63, 0x6f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x48, 0x6d, 0x76, 0x65, 0x78, 0x00, + 0x00, 0x00, 0x20, 0x74, 0x72, 0x65, 0x78, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x74, 0x72, 0x65, 0x78, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + Init{ + Tracks: []*InitTrack{{ + ID: 1, + TimeScale: 6000, Format: &format.H264{ - PayloadTyp: 96, + PayloadTyp: 96, + PacketizationMode: 1, SPS: []byte{ - 0x67, 0x42, 0xc0, 0x1f, 0xd9, 0x00, 0xf0, 0x11, - 0x7e, 0xf0, 0x11, 0x00, 0x00, 0x03, 0x00, 0x01, - 0x00, 0x00, 0x03, 0x00, 0x30, 0x8f, 0x18, 0x32, - 0x48, + 0x27, 0x64, 0x00, 0x2a, 0xac, 0x52, 0x14, 0x07, + 0x80, 0x22, 0x7e, 0x5f, 0xfc, 0x00, 0x04, 0x00, + 0x05, 0xa8, 0x08, 0x08, 0x0d, 0xb6, 0x15, 0xaf, + 0x7b, 0xe0, 0x20, }, PPS: []byte{ - 0x68, 0xcb, 0x8c, 0xb2, + 0x28, 0xf9, 0x09, 0x09, 0xcb, }, - PacketizationMode: 1, }, - }, + }}, }, - }, init) - }) - - t.Run("mpeg4audio", func(t *testing.T) { - byts := []byte{ - 0x00, 0x00, 0x00, 0x18, - 'f', 't', 'y', 'p', - 0x69, 0x73, 0x6f, 0x35, 0x00, 0x00, 0x00, 0x01, - 0x69, 0x73, 0x6f, 0x35, 0x64, 0x61, 0x73, 0x68, - 0x00, 0x00, 0x02, 0x43, - 'm', 'o', 'o', 'v', - 0x00, 0x00, 0x00, 0x6c, - 'm', 'v', 'h', 'd', - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x96, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0xa7, - 't', 'r', 'a', 'k', - 0x00, 0x00, 0x00, 0x5c, - 't', 'k', 'h', 'd', - 0x00, 0x00, 0x00, 0x07, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x43, - 'm', 'd', 'i', 'a', - 0x00, 0x00, 0x00, 0x20, - 'm', 'd', 'h', 'd', - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x96, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x55, 0xc4, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x38, - 'h', 'd', 'l', 'r', - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x73, 0x6f, 0x75, 0x6e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x42, 0x72, 0x6f, 0x61, 0x64, 0x70, 0x65, 0x61, - 0x6b, 0x20, 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x20, - 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x00, - 0x00, 0x00, 0x00, 0xe3, - 'm', 'i', 'n', 'f', - 0x00, 0x00, 0x00, 0x10, - 's', 'm', 'h', 'd', - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x24, - 'd', 'i', 'n', 'f', - 0x00, 0x00, 0x00, 0x1c, 0x64, 0x72, 0x65, 0x66, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x0c, 0x75, 0x72, 0x6c, 0x20, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa7, - 0x73, 0x74, 0x62, 0x6c, 0x00, 0x00, 0x00, 0x5b, - 0x73, 0x74, 0x73, 0x64, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4b, - 0x6d, 0x70, 0x34, 0x61, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x00, 0xbb, 0x80, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x27, 0x65, 0x73, 0x64, 0x73, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x19, 0x00, 0x00, - 0x00, 0x04, 0x11, 0x40, 0x15, 0x00, 0x30, 0x00, - 0x00, 0x11, 0x94, 0x00, 0x00, 0x11, 0x94, 0x00, - 0x05, 0x02, 0x11, 0x90, 0x06, 0x01, 0x02, 0x00, - 0x00, 0x00, 0x10, 0x73, 0x74, 0x74, 0x73, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x73, 0x74, 0x73, 0x63, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x14, 0x73, 0x74, 0x73, 0x7a, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x73, - 0x74, 0x63, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6d, - 0x76, 0x65, 0x78, 0x00, 0x00, 0x00, 0x20, 0x74, - 0x72, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, - } - - var init Init - err := init.Unmarshal(byts) - require.NoError(t, err) - - require.Equal(t, Init{ - Tracks: []*InitTrack{ - { - ID: 257, - TimeScale: 10000000, - Format: &format.MPEG4Audio{ - PayloadTyp: 96, - Config: &mpeg4audio.Config{ - Type: mpeg4audio.ObjectTypeAACLC, - SampleRate: 48000, - ChannelCount: 2, - }, - SizeLength: 13, - IndexLength: 3, - IndexDeltaLength: 3, - }, - }, - }, - }, init) - }) + }, + } { + t.Run(ca.name, func(t *testing.T) { + var init Init + err := init.Unmarshal(ca.byts) + require.NoError(t, err) + require.Equal(t, ca.init, init) + }) + } +} + +func TestInitUnmarshalErrors(t *testing.T) { + for _, ca := range []struct { + name string + byts []byte + err string + }{ + { + "ac3", + []byte{ + 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, + 0x6d, 0x70, 0x34, 0x32, 0x00, 0x00, 0x00, 0x01, + 0x6d, 0x70, 0x34, 0x31, 0x6d, 0x70, 0x34, 0x32, + 0x69, 0x73, 0x6f, 0x6d, 0x68, 0x6c, 0x73, 0x66, + 0x00, 0x00, 0x02, 0x20, 0x6d, 0x6f, 0x6f, 0x76, + 0x00, 0x00, 0x00, 0x6c, 0x6d, 0x76, 0x68, 0x64, + 0x00, 0x00, 0x00, 0x00, 0xd5, 0x5b, 0xc6, 0x5d, + 0xd5, 0x5b, 0xc6, 0x5d, 0x00, 0x00, 0x02, 0x58, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x84, + 0x74, 0x72, 0x61, 0x6b, 0x00, 0x00, 0x00, 0x5c, + 0x74, 0x6b, 0x68, 0x64, 0x00, 0x00, 0x00, 0x01, + 0xd5, 0x5b, 0xc6, 0x5d, 0xd5, 0x5b, 0xc6, 0x5d, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x20, 0x6d, 0x64, 0x69, 0x61, + 0x00, 0x00, 0x00, 0x20, 0x6d, 0x64, 0x68, 0x64, + 0x00, 0x00, 0x00, 0x00, 0xd5, 0x5b, 0xc6, 0x5d, + 0xd5, 0x5b, 0xc6, 0x5d, 0x00, 0x00, 0xbb, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x55, 0xc4, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x68, 0x64, 0x6c, 0x72, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x73, 0x6f, 0x75, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x43, 0x6f, 0x72, 0x65, 0x20, 0x4d, 0x65, 0x64, + 0x69, 0x61, 0x20, 0x41, 0x75, 0x64, 0x69, 0x6f, + 0x00, 0x00, 0x00, 0x00, 0xc7, 0x6d, 0x69, 0x6e, + 0x66, 0x00, 0x00, 0x00, 0x10, 0x73, 0x6d, 0x68, + 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x64, 0x69, 0x6e, + 0x66, 0x00, 0x00, 0x00, 0x1c, 0x64, 0x72, 0x65, + 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0c, 0x75, 0x72, 0x6c, + 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x8b, 0x73, 0x74, 0x62, 0x6c, 0x00, 0x00, 0x00, + 0x3f, 0x73, 0x74, 0x73, 0x64, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2f, 0x61, 0x63, 0x2d, 0x33, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0xbb, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0b, 0x64, 0x61, 0x63, + 0x33, 0x0c, 0x3d, 0x40, 0x00, 0x00, 0x00, 0x10, + 0x73, 0x74, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x73, 0x74, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, + 0x73, 0x74, 0x73, 0x7a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x73, 0x74, 0x63, 0x6f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x6d, 0x76, 0x65, 0x78, + 0x00, 0x00, 0x00, 0x20, 0x74, 0x72, 0x65, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + "no tracks found", + }, + { + "ac-3", + []byte{ + 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, + 0x6d, 0x70, 0x34, 0x32, 0x00, 0x00, 0x00, 0x01, + 0x6d, 0x70, 0x34, 0x31, 0x6d, 0x70, 0x34, 0x32, + 0x69, 0x73, 0x6f, 0x6d, 0x68, 0x6c, 0x73, 0x66, + 0x00, 0x00, 0x02, 0x22, 0x6d, 0x6f, 0x6f, 0x76, + 0x00, 0x00, 0x00, 0x6c, 0x6d, 0x76, 0x68, 0x64, + 0x00, 0x00, 0x00, 0x00, 0xd5, 0x5b, 0xc6, 0x5d, + 0xd5, 0x5b, 0xc6, 0x5d, 0x00, 0x00, 0x02, 0x58, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x86, + 0x74, 0x72, 0x61, 0x6b, 0x00, 0x00, 0x00, 0x5c, + 0x74, 0x6b, 0x68, 0x64, 0x00, 0x00, 0x00, 0x01, + 0xd5, 0x5b, 0xc6, 0x5d, 0xd5, 0x5b, 0xc6, 0x5d, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x22, 0x6d, 0x64, 0x69, 0x61, + 0x00, 0x00, 0x00, 0x20, 0x6d, 0x64, 0x68, 0x64, + 0x00, 0x00, 0x00, 0x00, 0xd5, 0x5b, 0xc6, 0x5d, + 0xd5, 0x5b, 0xc6, 0x5d, 0x00, 0x00, 0xbb, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x55, 0xc4, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x68, 0x64, 0x6c, 0x72, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x73, 0x6f, 0x75, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x43, 0x6f, 0x72, 0x65, 0x20, 0x4d, 0x65, 0x64, + 0x69, 0x61, 0x20, 0x41, 0x75, 0x64, 0x69, 0x6f, + 0x00, 0x00, 0x00, 0x00, 0xc9, 0x6d, 0x69, 0x6e, + 0x66, 0x00, 0x00, 0x00, 0x10, 0x73, 0x6d, 0x68, + 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x64, 0x69, 0x6e, + 0x66, 0x00, 0x00, 0x00, 0x1c, 0x64, 0x72, 0x65, + 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0c, 0x75, 0x72, 0x6c, + 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x8d, 0x73, 0x74, 0x62, 0x6c, 0x00, 0x00, 0x00, + 0x41, 0x73, 0x74, 0x73, 0x64, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x31, 0x65, 0x63, 0x2d, 0x33, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0xbb, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0d, 0x64, 0x65, 0x63, + 0x33, 0x00, 0xc0, 0x20, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x73, 0x74, 0x74, 0x73, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x73, 0x74, 0x73, 0x63, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x14, 0x73, 0x74, 0x73, 0x7a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x73, 0x74, + 0x63, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6d, 0x76, + 0x65, 0x78, 0x00, 0x00, 0x00, 0x20, 0x74, 0x72, + 0x65, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + }, + "no tracks found", + }, + } { + t.Run(ca.name, func(t *testing.T) { + var init Init + err := init.Unmarshal(ca.byts) + require.EqualError(t, err, ca.err) + }) + } } diff --git a/internal/hls/muxer_primary_playlist.go b/internal/hls/muxer_primary_playlist.go index 7dbad7c0..5724abb1 100644 --- a/internal/hls/muxer_primary_playlist.go +++ b/internal/hls/muxer_primary_playlist.go @@ -2,43 +2,14 @@ package hls import ( "bytes" - "encoding/hex" "io" "net/http" "strconv" "strings" - "github.com/aler9/gortsplib/v2/pkg/codecs/h265" "github.com/aler9/gortsplib/v2/pkg/format" ) -func codecParameters(track format.Format) string { - switch ttrack := track.(type) { - case *format.H264: - sps := ttrack.SafeSPS() - if len(sps) >= 4 { - return "avc1." + hex.EncodeToString(sps[1:4]) - } - - case *format.H265: - var sps h265.SPS - err := sps.Unmarshal(ttrack.SafeSPS()) - if err == nil { - return "hvc1." + strconv.FormatInt(int64(sps.ProfileTierLevel.GeneralProfileIdc), 10) + - ".4.L" + strconv.FormatInt(int64(sps.ProfileTierLevel.GeneralLevelIdc), 10) + ".B0" - } - - case *format.MPEG4Audio: - // https://developer.mozilla.org/en-US/docs/Web/Media/Formats/codecs_parameter - return "mp4a.40." + strconv.FormatInt(int64(ttrack.Config.Type), 10) - - case *format.Opus: - return "opus" - } - - return "" -} - type muxerPrimaryPlaylist struct { fmp4 bool videoTrack format.Format @@ -67,10 +38,10 @@ func (p *muxerPrimaryPlaylist) file() *MuxerFileResponse { var codecs []string if p.videoTrack != nil { - codecs = append(codecs, codecParameters(p.videoTrack)) + codecs = append(codecs, codecParametersGenerate(p.videoTrack)) } if p.audioTrack != nil { - codecs = append(codecs, codecParameters(p.audioTrack)) + codecs = append(codecs, codecParametersGenerate(p.audioTrack)) } var version int