73 lines
1.5 KiB
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
|
|
}
|