commit 9d0a9c380ce962f56c141d6db6fdacd7a41bf831
parent a30e111bb1d9e62aac3810e51749241f488e046a
Author: Oliver Lowe <o@olowe.co>
Date: Thu, 15 May 2025 23:19:36 +1000
m3u8: support parsing EXT-X-MAP tag
Diffstat:
2 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/m3u8/m3u8.go b/m3u8/m3u8.go
@@ -126,6 +126,9 @@ func parseEncryptMethod(s string) EncryptMethod {
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
diff --git a/m3u8/segment.go b/m3u8/segment.go
@@ -88,6 +88,12 @@ func parseSegment(items chan item, leading item) (*Segment, error) {
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)
}
@@ -184,11 +190,43 @@ func parseKey(items chan item) (Key, error) {
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("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 key, fmt.Errorf("TODO")
+ return Map{}, fmt.Errorf("unexpected end of tag")
}
func writeSegments(w io.Writer, segments []Segment) (n int, err error) {