Self review #1
36
main.go
36
main.go
|
@ -13,6 +13,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const DefaultTargetDuration = 3 * time.Second
|
const DefaultTargetDuration = 3 * time.Second
|
||||||
|
const DefaultPlaylistDuration = 20 * time.Second
|
||||||
|
|
||||||
type Segment struct {
|
type Segment struct {
|
||||||
targetDuration time.Duration
|
targetDuration time.Duration
|
||||||
|
@ -96,7 +97,7 @@ func (s *MP3HTTPSegmenter) Segment(r io.Reader) (chan *Segment, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if n != int64(v.Size()) {
|
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)
|
log.Fatal("unexpeced frame size, want = ", v.Size(), "got = ", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +116,7 @@ type Playlist interface {
|
||||||
// These could be moved to an interface?
|
// These could be moved to an interface?
|
||||||
Duration() time.Duration
|
Duration() time.Duration
|
||||||
TargetDuration() time.Duration
|
TargetDuration() time.Duration
|
||||||
|
AddSegment(s *Segment) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type MediaPlaylist struct {
|
type MediaPlaylist struct {
|
||||||
|
@ -128,8 +130,33 @@ func newMediaPlaylist() *MediaPlaylist {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *MediaPlaylist) Duration() time.Duration {
|
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
|
var t time.Duration
|
||||||
for _, s := range p.Segments {
|
for _, s := range ss {
|
||||||
t += s.Duration()
|
t += s.Duration()
|
||||||
}
|
}
|
||||||
return t
|
return t
|
||||||
|
@ -144,6 +171,11 @@ func (p *MediaPlaylist) Run() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PlaylistListener interface {
|
||||||
|
SegmentAdded(s *Segment) error
|
||||||
|
SegmentRemoved(s *Segment) error
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// TODO accept some flags with:
|
// TODO accept some flags with:
|
||||||
// URL - source of stream
|
// URL - source of stream
|
||||||
|
|
15
main_test.go
15
main_test.go
|
@ -20,3 +20,18 @@ func TestSegment(t *testing.T) {
|
||||||
require.Equal(t, 10*time.Second, segment.Duration())
|
require.Equal(t, 10*time.Second, segment.Duration())
|
||||||
require.False(t, segment.CanWrite(1*time.Millisecond))
|
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())
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue