diff --git a/internal/playlist/playlist.go b/internal/playlist/playlist.go index 5997952..4e426c4 100644 --- a/internal/playlist/playlist.go +++ b/internal/playlist/playlist.go @@ -9,7 +9,7 @@ import ( const DefaultPlaylistDuration = 20 * time.Second type PlaylistListener interface { - OnUpdate(p *Playlist) + OnUpdate(p Playlist) } type Playlist interface { @@ -18,16 +18,18 @@ type Playlist interface { TargetDuration() time.Duration AddSegment(s *segment.Segment) error Render() string - //AddListener(l PlaylistListener) + AddListener(l PlaylistListener) } type MediaPlaylist struct { - Segments []*segment.Segment + Segments []*segment.Segment + Listeners []PlaylistListener } func NewMediaPlaylist() *MediaPlaylist { return &MediaPlaylist{ - Segments: make([]*segment.Segment, 0, 10), + Segments: make([]*segment.Segment, 0, 10), + Listeners: make([]PlaylistListener, 0), } } @@ -42,16 +44,16 @@ func (p *MediaPlaylist) TargetDuration() time.Duration { func (p *MediaPlaylist) AddSegment(s *segment.Segment) error { p.Segments = append(p.Segments, s) - if len(p.Segments) == 1 { - return nil + if len(p.Segments) > 1 { + for { + if p.durationOf(p.Segments[1:]) > p.TargetDuration() { + p.Segments = p.Segments[1:] + } + break + } } - for { - if p.durationOf(p.Segments[1:]) > p.TargetDuration() { - p.Segments = p.Segments[1:] - } - break - } + p.updateListeners() return nil } @@ -77,6 +79,18 @@ func (p *MediaPlaylist) Render() string { return r } +// Listeners + +func (p *MediaPlaylist) AddListener(l PlaylistListener) { + p.Listeners = append(p.Listeners, l) +} + +func (p *MediaPlaylist) updateListeners() { + for _, l := range p.Listeners { + l.OnUpdate(p) + } +} + func (p *MediaPlaylist) Run() error { for { // TODO block here and listen to the channel of incoming segments. diff --git a/internal/playlist/playlist_test.go b/internal/playlist/playlist_test.go index fe5092e..c4f46dd 100644 --- a/internal/playlist/playlist_test.go +++ b/internal/playlist/playlist_test.go @@ -46,3 +46,23 @@ func TestMediaPlaylistRender(t *testing.T) { require.Equal(t, "#EXTINF:2.70000", lines[5]) require.Equal(t, "http://www.example.com/x.mp3", lines[6]) } + +type listener struct { + count int +} + +func (l *listener) OnUpdate(p playlist.Playlist) { + l.count++ +} + +func TestMediaPlaylistListener(t *testing.T) { + playlist := playlist.NewMediaPlaylist() + l := &listener{} + playlist.AddListener(l) + + s := segment.NewSegment(3*time.Second, 0) + s.IncrementDuration(3 * time.Second) + playlist.AddSegment(s) + + require.Equal(t, 1, l.count) +}