Extend playlist functionality

This commit is contained in:
Rob Watson 2020-07-06 23:17:01 +02:00
parent 86d01d3eff
commit 81b09338cc
2 changed files with 49 additions and 2 deletions

36
main.go
View File

@ -13,6 +13,7 @@ import (
) )
const DefaultTargetDuration = 3 * time.Second const DefaultTargetDuration = 3 * time.Second
const DefaultPlaylistDuration = 20 * time.Second
type Segment struct { type Segment struct {
targetDuration time.Duration targetDuration time.Duration
@ -96,7 +97,7 @@ func (s *MP3HTTPSegmenter) Segment(r io.Reader) (chan *Segment, error) {
} }
if n != int64(v.Size()) { if n != int64(v.Size()) {
// TODO would this ever happen? // TODO would this ever happen? What should IncrementDuration be called with?
log.Fatal("unexpeced frame size, want = ", v.Size(), "got = ", n) log.Fatal("unexpeced frame size, want = ", v.Size(), "got = ", n)
} }
@ -115,6 +116,7 @@ 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) error
} }
type MediaPlaylist struct { type MediaPlaylist struct {
@ -128,8 +130,33 @@ func newMediaPlaylist() *MediaPlaylist {
} }
func (p *MediaPlaylist) Duration() time.Duration { func (p *MediaPlaylist) Duration() time.Duration {
return p.durationOf(p.Segments)
}
func (p *MediaPlaylist) TargetDuration() time.Duration {
return DefaultPlaylistDuration
}
func (p *MediaPlaylist) AddSegment(s *Segment) error {
p.Segments = append(p.Segments, s)
if len(p.Segments) == 1 {
return nil
}
for {
if p.durationOf(p.Segments[1:]) > p.TargetDuration() {
p.Segments = p.Segments[1:]
}
break
}
return nil
}
func (p *MediaPlaylist) durationOf(ss []*Segment) time.Duration {
var t time.Duration var t time.Duration
for _, s := range p.Segments { for _, s := range ss {
t += s.Duration() t += s.Duration()
} }
return t return t
@ -144,6 +171,11 @@ func (p *MediaPlaylist) Run() error {
} }
} }
type PlaylistListener interface {
SegmentAdded(s *Segment) error
SegmentRemoved(s *Segment) error
}
func main() { func main() {
// TODO accept some flags with: // TODO accept some flags with:
// URL - source of stream // URL - source of stream

View File

@ -20,3 +20,18 @@ func TestSegment(t *testing.T) {
require.Equal(t, 10*time.Second, segment.Duration()) require.Equal(t, 10*time.Second, segment.Duration())
require.False(t, segment.CanWrite(1*time.Millisecond)) require.False(t, segment.CanWrite(1*time.Millisecond))
} }
func TestMediaPlaylistImplements(t *testing.T) {
require.Implements(t, (*Playlist)(nil), newMediaPlaylist())
}
func TestMediaPlaylist(t *testing.T) {
playlist := newMediaPlaylist()
for i := 0; i < 8; i++ {
s := newSegment(10*time.Second, 0)
s.IncrementDuration(3 * time.Second)
playlist.AddSegment(s)
}
require.Equal(t, 21*time.Second, playlist.Duration())
}