commit - b3f3a7ccc95f08e87b4df8d758c035e4ef5e0fc5
commit + 2be3531b0dcadd5c29adc1fff94844876de00afe
blob - 5c26bc7a91e5e7d4594e8c07fe98576ce77709ac
blob + d73bcc7147293cce0ea0a9a55185cccc5f9abd7d
--- m3u8/parse.go
+++ m3u8/parse.go
"errors"
"fmt"
"io"
+ "regexp"
"strconv"
"strings"
"time"
p.Segments = append(p.Segments, *segment)
case tagEndList:
p.End = true
+ case tagMediaSequence:
+ val, err := parseSequence(lex)
+ if err != nil {
+ return p, fmt.Errorf("parse media sequence: %w", err)
+ }
+ p.Sequence = val
}
}
}
}
return ByteRange{n, nn}, nil
}
+
+func parseSequence(lex *lexer) (int, error) {
+ re := regexp.MustCompile(`#EXT-X-MEDIA-SEQUENCE:(\d+)`)
+
+ match := re.FindStringSubmatch(lex.input)
+ if len(match) > 1 {
+ return strconv.Atoi(match[1])
+ }
+
+ return 0, fmt.Errorf("invalid sequence number")
+}
blob - 6bb8bfd37387985be64fc852d33b9ec94ea90fa6
blob + 8614b5d3dff6b87a4b67ccf09b7e89a9543f3348
--- m3u8/parse_test.go
+++ m3u8/parse_test.go
}
}
}
+
+func TestParseSequence(t *testing.T) {
+ f, err := os.Open("testdata/sequence.m3u8")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer f.Close()
+ plist, err := Decode(f)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if plist.Sequence != 91240 {
+ t.Errorf("want %d, got %d", 91240, plist.Sequence)
+ }
+}
blob - /dev/null
blob + 91a14211a3b092ea9087af322cac7f159a7be05e (mode 644)
--- /dev/null
+++ m3u8/testdata/sequence.m3u8
+#EXTM3U
+#EXT-X-VERSION:3
+#EXT-X-TARGETDURATION:3
+#EXT-X-MEDIA-SEQUENCE:91240
+#EXT-X-DISCONTINUITY-SEQUENCE:0
+#EXTINF:2.002,
+media-seg_91240.ts
+#EXTINF:2.002,
+media-seg_91241.ts
+#EXTINF:2.002,
+media-seg_91242.ts