streaming

Media streaming and broadcast systems in Go
Log | Files | Refs | README | LICENSE

commit 5b0199e0674b051428672a1460ed5109b3cedadf
parent a2109c70b8c1180b4a6b9400e503e37ff4abdda8
Author: Oliver Lowe <o@olowe.co>
Date:   Sat,  3 May 2025 13:25:35 +1000

m3u8: add higher-level variant test

We weren't really testing whether variants we parse from a playlist
were what we expect.

References: https://github.com/untangledco/streaming/issues/34

Diffstat:
Mm3u8/parse.go | 3---
Mm3u8/parse_test.go | 49++++++++++++++++++++++++++++++++++++++++++++++---
Mm3u8/testdata/master.m3u8 | 6+++---
3 files changed, 49 insertions(+), 9 deletions(-)

diff --git a/m3u8/parse.go b/m3u8/parse.go @@ -151,9 +151,6 @@ func parseVariant(items chan item) (*Variant, error) { v.FrameRate = float32(n) case "HDCP-LEVEL": it = <-items - if it.typ != itemString { - return nil, fmt.Errorf("parse HDCP level: unexpected %s", it) - } l, err := parseHDCPLevel(it.val) if err != nil { return nil, fmt.Errorf("parse HDCP level: %w", err) diff --git a/m3u8/parse_test.go b/m3u8/parse_test.go @@ -5,6 +5,7 @@ import ( "os" "path" "path/filepath" + "reflect" "strings" "testing" "time" @@ -39,11 +40,11 @@ func ExampleEncode() { func ExampleDecode() { s := ` #EXTM3U -#EXT-X-STREAM-INF:BANDWIDTH=1280000,RESOLUTION=640x360 +#EXT-X-STREAM-INF:BANDWIDTH=1280000,RESOLUTION=640x360,HDCP-LEVEL=NONE url_0/low.m3u8 -#EXT-X-STREAM-INF:BANDWIDTH=2560000,RESOLUTION=1280x720 +#EXT-X-STREAM-INF:BANDWIDTH=2560000,RESOLUTION=1280x720,HDCP-LEVEL=NONE url_0/mid.m3u8 -#EXT-X-STREAM-INF:BANDWIDTH=7680000,RESOLUTION=1920x1080 +#EXT-X-STREAM-INF:BANDWIDTH=7680000,RESOLUTION=1920x1080,HDCP-LEVEL=NONE url_0/high.m3u8` p, err := Decode(strings.NewReader(s)) @@ -79,6 +80,48 @@ func TestDecode(t *testing.T) { } } +func TestVariant(t *testing.T) { + f, err := os.Open("testdata/master.m3u8") + if err != nil { + t.Fatal(err) + } + defer f.Close() + plist, err := Decode(f) + if err != nil { + t.Fatalf("read playlist: %v", err) + } + want := []Variant{ + { + Bandwidth: 1280000, + Video: "low", + HDCP: HDCPType0, + URI: "low/main/audio-video.m3u8", + }, + { + Bandwidth: 2560000, + Video: "mid", + HDCP: HDCPType1, + URI: "mid/main/audio-video.m3u8", + }, + { + Bandwidth: 7680000, + Video: "hi", + URI: "hi/main/audio-video.m3u8", + }, + { + Bandwidth: 65000, + Codecs: []string{"mp4a.40.5"}, + HDCP: HDCPNone, + URI: "main/audio-only.m3u8", + }, + } + for i, got := range plist.Variants { + if !reflect.DeepEqual(got, want[i]) { + t.Errorf("variant %d: got %v, want %v", i, got, want) + } + } +} + func TestParseDuration(t *testing.T) { want := 9967000 * time.Microsecond it := item{typ: itemNumber, val: "9.967"} diff --git a/m3u8/testdata/master.m3u8 b/m3u8/testdata/master.m3u8 @@ -2,17 +2,17 @@ #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="low",NAME="Main",DEFAULT=YES,URI="low/main/audio-video.m3u8" #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="low",NAME="Centerfield",DEFAULT=NO,URI="low/centerfield/audio-video.m3u8" #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="low",NAME="Dugout",DEFAULT=NO,URI="low/dugout/audio-video.m3u8" -#EXT-X-STREAM-INF:BANDWIDTH=1280000,VIDEO="low" +#EXT-X-STREAM-INF:BANDWIDTH=1280000,VIDEO="low",HDCP-LEVEL=TYPE-0 low/main/audio-video.m3u8 #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="mid",NAME="Main",DEFAULT=YES,URI="mid/main/audio-video.m3u8" #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="mid",NAME="Centerfield",DEFAULT=NO,URI="mid/centerfield/audio-video.m3u8" #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="mid",NAME="Dugout",DEFAULT=NO,URI="mid/dugout/audio-video.m3u8" -#EXT-X-STREAM-INF:BANDWIDTH=2560000,VIDEO="mid" +#EXT-X-STREAM-INF:BANDWIDTH=2560000,VIDEO="mid",HDCP-LEVEL=TYPE-1 mid/main/audio-video.m3u8 #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="hi",NAME="Main",DEFAULT=YES,URI="hi/main/audio-video.m3u8" #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="hi",NAME="Centerfield",DEFAULT=NO,URI="hi/centerfield/audio-video.m3u8" #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="hi",NAME="Dugout",DEFAULT=NO,URI="hi/dugout/audio-video.m3u8" #EXT-X-STREAM-INF:BANDWIDTH=7680000,VIDEO="hi" hi/main/audio-video.m3u8 -#EXT-X-STREAM-INF:BANDWIDTH=65000,CODECS="mp4a.40.5" +#EXT-X-STREAM-INF:BANDWIDTH=65000,CODECS="mp4a.40.5",HDCP-LEVEL=NONE main/audio-only.m3u8