Pruning
parent
a094c37fb5
commit
d466a1b7b8
|
@ -68,6 +68,11 @@ func NewManager(c *Config, path string, id string, close chan string) (*Manager,
|
||||||
bitrate: int(float64(highest) * 1.5),
|
bitrate: int(float64(highest) * 1.5),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start all streams
|
||||||
|
for _, stream := range m.streams {
|
||||||
|
go stream.Run()
|
||||||
|
}
|
||||||
|
|
||||||
log.Printf("%s: new manager for %s", m.id, m.path)
|
log.Printf("%s: new manager for %s", m.id, m.path)
|
||||||
|
|
||||||
return m, nil
|
return m, nil
|
||||||
|
|
69
stream.go
69
stream.go
|
@ -43,6 +43,56 @@ type Stream struct {
|
||||||
chunks map[int]*Chunk
|
chunks map[int]*Chunk
|
||||||
|
|
||||||
coder *exec.Cmd
|
coder *exec.Cmd
|
||||||
|
|
||||||
|
inactive int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stream) Run() {
|
||||||
|
// run every 5s
|
||||||
|
t := time.NewTicker(5 * time.Second)
|
||||||
|
defer t.Stop()
|
||||||
|
|
||||||
|
for {
|
||||||
|
<-t.C
|
||||||
|
s.mutex.Lock()
|
||||||
|
// Prune chunks
|
||||||
|
for id := range s.chunks {
|
||||||
|
if id < s.goal-s.c.goalBufferMax {
|
||||||
|
s.pruneChunk(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.inactive++
|
||||||
|
if s.inactive >= 4 {
|
||||||
|
t.Stop()
|
||||||
|
s.Stop()
|
||||||
|
s.mutex.Unlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.mutex.Unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stream) Stop() {
|
||||||
|
log.Printf("%s-%s: stopping stream", s.m.id, s.quality)
|
||||||
|
|
||||||
|
for _, chunk := range s.chunks {
|
||||||
|
// Delete files
|
||||||
|
s.pruneChunk(chunk.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.chunks = make(map[int]*Chunk)
|
||||||
|
s.goal = 0
|
||||||
|
|
||||||
|
if s.coder != nil {
|
||||||
|
s.coder.Process.Kill()
|
||||||
|
s.coder = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stream) StopWithLock() {
|
||||||
|
s.mutex.Lock()
|
||||||
|
defer s.mutex.Unlock()
|
||||||
|
s.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Stream) ServeList(w http.ResponseWriter) error {
|
func (s *Stream) ServeList(w http.ResponseWriter) error {
|
||||||
|
@ -77,6 +127,7 @@ func (s *Stream) ServeChunk(w http.ResponseWriter, id int) error {
|
||||||
s.mutex.Lock()
|
s.mutex.Lock()
|
||||||
defer s.mutex.Unlock()
|
defer s.mutex.Unlock()
|
||||||
|
|
||||||
|
s.inactive = 0
|
||||||
s.checkGoal(id)
|
s.checkGoal(id)
|
||||||
|
|
||||||
// Already have this chunk
|
// Already have this chunk
|
||||||
|
@ -122,6 +173,14 @@ func (s *Stream) createChunk(id int) *Chunk {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Stream) pruneChunk(id int) {
|
||||||
|
delete(s.chunks, id)
|
||||||
|
|
||||||
|
// Remove file
|
||||||
|
filename := s.getTsPath(id)
|
||||||
|
os.Remove(filename)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Stream) returnChunk(w http.ResponseWriter, chunk *Chunk) {
|
func (s *Stream) returnChunk(w http.ResponseWriter, chunk *Chunk) {
|
||||||
// This function is called with lock, but we don't need it
|
// This function is called with lock, but we don't need it
|
||||||
s.mutex.Unlock()
|
s.mutex.Unlock()
|
||||||
|
@ -177,13 +236,7 @@ func (s *Stream) waitForChunk(w http.ResponseWriter, chunk *Chunk) {
|
||||||
|
|
||||||
func (s *Stream) restartAtChunk(w http.ResponseWriter, id int) {
|
func (s *Stream) restartAtChunk(w http.ResponseWriter, id int) {
|
||||||
// Stop current transcoder
|
// Stop current transcoder
|
||||||
if s.coder != nil {
|
s.Stop()
|
||||||
s.coder.Process.Kill()
|
|
||||||
s.coder = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear everything
|
|
||||||
s.chunks = make(map[int]*Chunk)
|
|
||||||
|
|
||||||
chunk := s.createChunk(id) // create first chunk
|
chunk := s.createChunk(id) // create first chunk
|
||||||
|
|
||||||
|
@ -278,7 +331,7 @@ func (s *Stream) transcode(startId int) {
|
||||||
}...)
|
}...)
|
||||||
|
|
||||||
s.coder = exec.Command(s.c.ffmpeg, args...)
|
s.coder = exec.Command(s.c.ffmpeg, args...)
|
||||||
log.Printf("%s-%s: %s", strings.Join(s.coder.Args[:], " "))
|
log.Printf("%s-%s: %s", s.m.id, s.quality, strings.Join(s.coder.Args[:], " "))
|
||||||
|
|
||||||
cmdStdOut, err := s.coder.StdoutPipe()
|
cmdStdOut, err := s.coder.StdoutPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in New Issue