commit - a2109c70b8c1180b4a6b9400e503e37ff4abdda8
commit + 5b0199e0674b051428672a1460ed5109b3cedadf
blob - 0117911d561fd529fde1dada7019c2b885925615
blob + a1b372a4d257e5b477fb38b5925e2734f7f9da01
--- m3u8/parse.go
+++ m3u8/parse.go
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
"os"
"path"
"path/filepath"
+ "reflect"
"strings"
"testing"
"time"
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))
}
}
+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
#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