diff --git a/main.go b/main.go index ca4416d..3ae5dde 100644 --- a/main.go +++ b/main.go @@ -13,6 +13,7 @@ import ( ) const DefaultTargetDuration = 3 * time.Second +const DefaultPlaylistDuration = 20 * time.Second type Segment struct { targetDuration time.Duration @@ -96,7 +97,7 @@ func (s *MP3HTTPSegmenter) Segment(r io.Reader) (chan *Segment, error) { } 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) } @@ -115,6 +116,7 @@ type Playlist interface { // These could be moved to an interface? Duration() time.Duration TargetDuration() time.Duration + AddSegment(s *Segment) error } type MediaPlaylist struct { @@ -128,8 +130,33 @@ func newMediaPlaylist() *MediaPlaylist { } 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 - for _, s := range p.Segments { + for _, s := range ss { t += s.Duration() } return t @@ -144,6 +171,11 @@ func (p *MediaPlaylist) Run() error { } } +type PlaylistListener interface { + SegmentAdded(s *Segment) error + SegmentRemoved(s *Segment) error +} + func main() { // TODO accept some flags with: // URL - source of stream diff --git a/main_test.go b/main_test.go index a7f30fd..ff0fb2a 100644 --- a/main_test.go +++ b/main_test.go @@ -20,3 +20,18 @@ func TestSegment(t *testing.T) { require.Equal(t, 10*time.Second, segment.Duration()) 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()) +}