commit - a30e111bb1d9e62aac3810e51749241f488e046a
commit + 9d0a9c380ce962f56c141d6db6fdacd7a41bf831
blob - b524a68ce5470a6e0137bb827ed7145edd7d5f99
blob + cad16cdf5b3e2c9aeaa5df7f69207b3151bc066a
--- m3u8/m3u8.go
+++ m3u8/m3u8.go
return encryptMethodInvalid
}
+// Map represents the EXT-X-MAP tag.
+// A Map informs of any byte sequences to initialise readers of
+// some media formats.
type Map struct {
URI string
ByteRange ByteRange
blob - d019ec22dc533455dad16f1fa9b75bc93bb9732f
blob + 0d706d6f50a48b0bc89983ee9fa72a8a9c18b968
--- m3u8/segment.go
+++ m3u8/segment.go
return nil, fmt.Errorf("parse key: %w", err)
}
seg.Key = &key
+ case tagMap:
+ m, err := parseMap(items)
+ if err != nil {
+ return nil, fmt.Errorf("parse map: %w", err)
+ }
+ seg.Map = &m
default:
return nil, fmt.Errorf("parsing %s unsupported", it)
}
key.FormatVersions[i] = uint32(n)
}
default:
- return key, fmt.Errorf("TODO %s", it.val)
+ return key, fmt.Errorf("unexpected attribute %q", it.val)
}
}
}
- return key, fmt.Errorf("TODO")
+ return key, fmt.Errorf("unexpected end of tag")
}
+func parseMap(items chan item) (Map, error) {
+ var mmap Map
+ for it := range items {
+ switch it.typ {
+ case itemError:
+ return mmap, errors.New(it.val)
+ case itemNewline:
+ return mmap, nil
+ case itemAttrName:
+ v := <-items
+ if v.typ != itemEquals {
+ return Map{}, fmt.Errorf("expected %q after %s, got %s", "=", it.typ, v)
+ }
+ switch it.val {
+ case "URI":
+ v = <-items
+ mmap.URI = strings.Trim(it.val, `"`)
+ case "BYTERANGE":
+ v = <-items
+ r, err := parseByteRange(v.val)
+ if err != nil {
+ return Map{}, fmt.Errorf("parse byte range: %w", err)
+ }
+ mmap.ByteRange = r
+ default:
+ return Map{}, fmt.Errorf("unexpected attribute %q", it.val)
+ }
+ }
+ }
+ return Map{}, fmt.Errorf("unexpected end of tag")
+}
+
func writeSegments(w io.Writer, segments []Segment) (n int, err error) {
for i, seg := range segments {
b, err := seg.MarshalText()