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:
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