Commit Diff


commit - a2109c70b8c1180b4a6b9400e503e37ff4abdda8
commit + 5b0199e0674b051428672a1460ed5109b3cedadf
blob - 0117911d561fd529fde1dada7019c2b885925615
blob + a1b372a4d257e5b477fb38b5925e2734f7f9da01
--- m3u8/parse.go
+++ 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)
blob - 96e924816a03c74379ff972dad1afc1f44551989
blob + da1832535bcf1ffd0759decdc5da937d5e849971
--- m3u8/parse_test.go
+++ 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"}
blob - ea6ea2f60408a28c137ab1f789a3503051d7c3fb
blob + cdf16df8f4dcaeaa22b442da57b73e06dbbad5be
--- m3u8/testdata/master.m3u8
+++ 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