Implement basic Playlist rendering

This commit is contained in:
Rob Watson 2020-07-07 17:19:17 +02:00
parent e836b44941
commit afbe654de0
2 changed files with 44 additions and 6 deletions

View File

@ -1,17 +1,24 @@
package playlist package playlist
import ( import (
"fmt"
"segmento/internal/segment" "segmento/internal/segment"
"time" "time"
) )
const DefaultPlaylistDuration = 20 * time.Second const DefaultPlaylistDuration = 20 * time.Second
type PlaylistListener interface {
OnUpdate(p *Playlist)
}
type Playlist interface { type Playlist interface {
// These could be moved to an interface? // These could be moved to an interface?
Duration() time.Duration Duration() time.Duration
TargetDuration() time.Duration TargetDuration() time.Duration
AddSegment(s *segment.Segment) error AddSegment(s *segment.Segment) error
Render() string
//AddListener(l PlaylistListener)
} }
type MediaPlaylist struct { type MediaPlaylist struct {
@ -57,6 +64,19 @@ func (p *MediaPlaylist) durationOf(ss []*segment.Segment) time.Duration {
return t return t
} }
func (p *MediaPlaylist) Render() string {
var r string
r += "#EXTM3U\n"
r += "#EXT-X-VERSION:3\n"
r += "#EXT-X-TARGETDURATION:3\n" // TODO
for _, s := range p.Segments {
r += fmt.Sprintf("#EXTINF:%.05f\n", float32(s.Duration())/float32(time.Second))
r += "http://www.example.com/x.mp3\n"
}
r += "#EXT-X-ENDLIST"
return r
}
func (p *MediaPlaylist) Run() error { func (p *MediaPlaylist) Run() error {
for { for {
// TODO block here and listen to the channel of incoming segments. // TODO block here and listen to the channel of incoming segments.
@ -65,8 +85,3 @@ func (p *MediaPlaylist) Run() error {
// What would actually be a useful API and/or Go best practices? // What would actually be a useful API and/or Go best practices?
} }
} }
type PlaylistListener interface {
SegmentAdded(s *segment.Segment) error
SegmentRemoved(s *segment.Segment) error
}

View File

@ -3,6 +3,7 @@ package playlist_test
import ( import (
"segmento/internal/playlist" "segmento/internal/playlist"
"segmento/internal/segment" "segmento/internal/segment"
"strings"
"testing" "testing"
"time" "time"
@ -17,9 +18,31 @@ func TestMediaPlaylist(t *testing.T) {
playlist := playlist.NewMediaPlaylist() playlist := playlist.NewMediaPlaylist()
for i := 0; i < 8; i++ { for i := 0; i < 8; i++ {
s := segment.NewSegment(10*time.Second, 0) s := segment.NewSegment(3*time.Second, 0)
s.IncrementDuration(3 * time.Second) s.IncrementDuration(3 * time.Second)
playlist.AddSegment(s) playlist.AddSegment(s)
} }
require.Equal(t, 21*time.Second, playlist.Duration()) require.Equal(t, 21*time.Second, playlist.Duration())
} }
func TestMediaPlaylistRender(t *testing.T) {
playlist := playlist.NewMediaPlaylist()
s := segment.NewSegment(3*time.Second, 0)
s.IncrementDuration(3 * time.Second)
playlist.AddSegment(s)
s = segment.NewSegment(3*time.Second, 0)
s.IncrementDuration(2700 * time.Millisecond)
playlist.AddSegment(s)
lines := strings.Split(playlist.Render(), "\n")
require.Equal(t, "#EXTM3U", lines[0])
require.Equal(t, "#EXT-X-VERSION:3", lines[1])
require.Equal(t, "#EXT-X-TARGETDURATION:3", lines[2])
require.Equal(t, "#EXTINF:3.00000", lines[3])
require.Equal(t, "http://www.example.com/x.mp3", lines[4])
require.Equal(t, "#EXTINF:2.70000", lines[5])
require.Equal(t, "http://www.example.com/x.mp3", lines[6])
}