segmento/internal/playlist/playlist.go

73 lines
1.5 KiB
Go

package playlist
import (
"segmento/internal/segment"
"time"
)
const DefaultPlaylistDuration = 20 * time.Second
type Playlist interface {
// These could be moved to an interface?
Duration() time.Duration
TargetDuration() time.Duration
AddSegment(s *segment.Segment) error
}
type MediaPlaylist struct {
Segments []*segment.Segment
}
func NewMediaPlaylist() *MediaPlaylist {
return &MediaPlaylist{
Segments: make([]*segment.Segment, 0, 10),
}
}
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.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.Segment) time.Duration {
var t time.Duration
for _, s := range ss {
t += s.Duration()
}
return t
}
func (p *MediaPlaylist) Run() error {
for {
// TODO block here and listen to the channel of incoming segments.
// As the reader is Read and segments are produced, update the Playlist
// struct and possibly notify consumers.
// 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
}