streaming

Media streaming and broadcast systems in Go
Log | Files | Refs | README | LICENSE

commit 598fdad5e83b6942731dd84ef231c3f8e605e5fe
parent 52ca0d40aee46b2fdb156b73c5c16509f3e3505e
Author: Oliver Lowe <o@olowe.co>
Date:   Wed, 22 May 2024 13:52:32 +1000

m3u8: correctly parse resolution and byte range

The lexer wasn't emitting the expected tokens to our parser. Now we
handle the cases where numbers are split by "x" and "@" as in
resolutions and byte range strings.

Diffstat:
Mm3u8/lex.go | 9+++++----
Mm3u8/parse_test.go | 21++++++++++++++-------
2 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/m3u8/lex.go b/m3u8/lex.go @@ -232,9 +232,6 @@ func lexAttrValue(l *lexer) stateFn { return lexNumber(l) case '"': return lexQString(l) - case '@': - // we're lexing a byte range, e.g. 69@420 - return lexRawString(l) } if isTagNameChar(r) { return lexRawString(l) @@ -245,6 +242,10 @@ func lexAttrValue(l *lexer) stateFn { func lexNumber(l *lexer) stateFn { for { switch r := l.peek(); r { + case 'x', '@': + // are we lexing a resolution? e.g. 640x480 + // or a byte range? e.g. 69@3000 + return lexRawString(l) case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.': l.next() continue @@ -269,7 +270,7 @@ func lexQString(l *lexer) stateFn { func lexRawString(l *lexer) stateFn { for { - if !isTagNameChar(l.peek()) { + if l.peek() == ',' || l.peek() == '\n' { break } l.next() diff --git a/m3u8/parse_test.go b/m3u8/parse_test.go @@ -1,23 +1,30 @@ package m3u8 import ( - "fmt" "os" + "path" + "path/filepath" "testing" "time" ) func TestParse(t *testing.T) { - f, err := os.Open("testdata/bbb.m3u8") + names, err := filepath.Glob("testdata/*.m3u8") if err != nil { t.Fatal(err) } - defer f.Close() - p, err := ParsePlaylist(f) - if err != nil { - t.Fatal(err) + for _, name := range names { + t.Run(path.Base(name), func(t *testing.T) { + f, err := os.Open(name) + if err != nil { + t.Fatal(err) + } + defer f.Close() + if _, err := ParsePlaylist(f); err != nil { + t.Fatal(err) + } + }) } - fmt.Println(p.Segments[0]) } func TestParseDuration(t *testing.T) {