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 }