Skip to content

Commit

Permalink
Fixed problem with incorrect media playlist generation when winsize =…
Browse files Browse the repository at this point in the history
…= capacity.
  • Loading branch information
grafov committed Nov 17, 2013
1 parent fa5e644 commit b5ae3cd
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 16 deletions.
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
M3U8
====

The library for parsing and generation of M3U8 playlists. M3U8 playlist format used in HTTP Live Streaming (Apple HLS) for internet video translations.
Also the library may be useful for common M3U format parsing and generation.
This is a most complete opensource library for parsing and generation of M3U8 playlists.
M3U8 playlist format used in HTTP Live Streaming (Apple HLS) for internet video translations.

Features are:

Expand Down Expand Up @@ -47,7 +47,6 @@ Parse playlist:
masterpl := p.(*MasterPlaylist)
fmt.Printf("%+v\n", masterpl)
}

```

Then you get filled with parsed data structures. For master playlists you get ``Master`` struct with slice consists of pointers to ``Variant`` structures (which represent playlists to each bitrate).
Expand Down
20 changes: 7 additions & 13 deletions writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ package m3u8
import (
"bytes"
"errors"
"fmt"
"math"
"strconv"
)
Expand Down Expand Up @@ -174,7 +173,6 @@ func NewMediaPlaylist(winsize uint, capacity uint) (*MediaPlaylist, error) {
p.winsize = winsize
p.capacity = capacity
p.Segments = make([]*MediaSegment, capacity)
p.SeqNo = 1
return p, nil
}

Expand Down Expand Up @@ -217,8 +215,10 @@ func (p *MediaPlaylist) Append(uri string, duration float64, title string) error
// next chunk. Secondly it appends one chunk to the tail of chunk slice. Useful for sliding playlists.
// This operation does reset cache.
func (p *MediaPlaylist) Slide(uri string, duration float64, title string) {
if !p.Closed && p.count > p.winsize {
if !p.Closed && p.count >= p.winsize {
p.Remove()
} else if !p.Closed {
p.SeqNo++
}
p.Append(uri, duration, title)
}
Expand All @@ -236,6 +236,9 @@ func (p *MediaPlaylist) Encode() *bytes.Buffer {
return &p.buf
}

if p.SeqNo == 0 {
p.SeqNo = 1
}
p.buf.WriteString("#EXTM3U\n#EXT-X-VERSION:")
p.buf.WriteString(strver(p.ver))
p.buf.WriteRune('\n')
Expand Down Expand Up @@ -333,7 +336,7 @@ func (p *MediaPlaylist) Encode() *bytes.Buffer {

head := p.head
count := p.count
for i := uint(0); i <= p.winsize && count > 0; count-- {
for i := uint(0); i < p.winsize && count > 0; count-- {
seg = p.Segments[head]
head = (head + 1) % p.capacity
if seg == nil { // protection from badly filled chunklists
Expand Down Expand Up @@ -411,12 +414,3 @@ func (p *MediaPlaylist) SetKey(method, uri, iv, keyformat, keyformatversions str
p.Segments[(p.tail-1)%p.capacity].Key = &Key{method, uri, iv, keyformat, keyformatversions}
return nil
}

// Helper. Dumper function for debug.
func dd(vars ...interface{}) {
print("DEBUG: ")
for _, msg := range vars {
fmt.Printf("%v ", msg)
}
print("\n")
}
12 changes: 12 additions & 0 deletions writer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,18 @@ func TestMediaPlaylistWithEmptyMedia(t *testing.T) {
} // TODO add check for buffers equality
}

// Create new media playlist with winsize == capacity
func TestMediaPlaylistWinsize(t *testing.T) {
p, e := NewMediaPlaylist(6, 6)
if e != nil {
panic(fmt.Sprintf("Create media playlist failed: %s", e))
}
for i := 1; i < 10; i++ {
p.Slide(fmt.Sprintf("test%d.ts", i), 5.6, "")
fmt.Println(p.Encode().String()) // TODO check playlist sizes and mediasequence values
}
}

// Create new media playlist as sliding playlist.
// Close it.
func TestClosedMediaPlaylist(t *testing.T) {
Expand Down

0 comments on commit b5ae3cd

Please sign in to comment.