commit - 093b7480bc7275b0047361f2f87d3992bc71e5ee
commit + a5e36fbfb60aadd58d7a06c29272251c0a8f8c0e
blob - 3789c873abda6c7313d8e49d44f5bce71970f434
blob + f20f8a3d8585da03597a22dc361b29eebb0727f2
--- m3u8/segment.go
+++ m3u8/segment.go
// parseSegment returns the next segment from items and the leading
// item which indicated the start of a segment.
func parseSegment(items chan item, leading item) (*Segment, error) {
+ // we've already read one item, so send everything through again
+ // starting with the leading item to maintain the lexer's original order.
+ segItems := make(chan item)
+ go func() {
+ segItems <- leading
+ for it := range items {
+ if it.typ == itemURL {
+ segItems <- it
+ close(segItems)
+ return
+ }
+ segItems <- it
+ }
+ }()
+
var seg Segment
- switch leading.typ {
- case itemTag:
- switch leading.val {
- case tagSegmentDuration:
- it := <-items
- dur, err := parseSegmentDuration(it)
- if err != nil {
- return nil, fmt.Errorf("parse segment duration: %w", err)
- }
- seg.Duration = dur
- case tagKey:
- key, err := parseKey(items)
- if err != nil {
- 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("parse leading item %s: unsupported", leading)
- }
- }
-
- for it := range items {
+ for it := range segItems {
switch it.typ {
+ case itemNewline:
+ continue
case itemError:
return nil, errors.New(it.val)
case itemURL:
seg.URI = it.val
return &seg, nil
- case itemNewline:
- continue
- default:
- if it.typ != itemTag {
- return nil, fmt.Errorf("unexpected %s", it)
- }
}
switch it.val {
case tagSegmentDuration:
- it = <-items
+ it = <-segItems
dur, err := parseSegmentDuration(it)
if err != nil {
return nil, fmt.Errorf("parse segment duration: %w", err)
}
seg.Duration = dur
case tagByteRange:
- it = <-items
+ it = <-segItems
r, err := parseByteRange(it.val)
if err != nil {
return nil, fmt.Errorf("parse byte range: %w", err)
case tagDiscontinuity:
seg.Discontinuity = true
case tagKey:
- key, err := parseKey(items)
+ key, err := parseKey(segItems)
if err != nil {
return nil, fmt.Errorf("parse key: %w", err)
}
seg.Key = &key
case tagMap:
- m, err := parseMap(items)
+ m, err := parseMap(segItems)
if err != nil {
return nil, fmt.Errorf("parse map: %w", err)
}
seg.Map = &m
case tagDateTime:
- it = <-items
+ it = <-segItems
t, err := time.Parse(time.RFC3339Nano, it.val)
if err != nil {
return nil, fmt.Errorf("bad date time tag: %w", err)