Feat livestream support (#180)
* experimental livestrea support * test livestream * update wait time detection * update livestream functions * persist and restore livestreams monitor session * fan-in logging * deps update * added live time display * livestream monitor prototype * changed to default logger instead of passing *slog.Logger everywhere * code refactoring, comments
This commit is contained in:
118
server/internal/livestream/monitor.go
Normal file
118
server/internal/livestream/monitor.go
Normal file
@@ -0,0 +1,118 @@
|
||||
package livestream
|
||||
|
||||
import (
|
||||
"encoding/gob"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/config"
|
||||
)
|
||||
|
||||
type Monitor struct {
|
||||
streams map[string]*LiveStream // keeps track of the livestreams
|
||||
done chan *LiveStream // to signal individual processes completition
|
||||
logs chan []byte // to signal individual processes completition
|
||||
}
|
||||
|
||||
func NewMonitor() *Monitor {
|
||||
return &Monitor{
|
||||
streams: make(map[string]*LiveStream),
|
||||
done: make(chan *LiveStream),
|
||||
}
|
||||
}
|
||||
|
||||
// Detect each livestream completition, if done remove it from the monitor.
|
||||
func (m *Monitor) Schedule() {
|
||||
for l := range m.done {
|
||||
delete(m.streams, l.url)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Monitor) Add(url string) {
|
||||
ls := New(url, m.logs, m.done)
|
||||
|
||||
go ls.Start()
|
||||
m.streams[url] = ls
|
||||
}
|
||||
|
||||
func (m *Monitor) Remove(url string) error {
|
||||
return m.streams[url].Kill()
|
||||
}
|
||||
|
||||
func (m *Monitor) RemoveAll() error {
|
||||
for _, v := range m.streams {
|
||||
if err := v.Kill(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Monitor) Status() LiveStreamStatus {
|
||||
status := make(LiveStreamStatus)
|
||||
|
||||
for k, v := range m.streams {
|
||||
// wt, ok := <-v.WaitTime()
|
||||
// if !ok {
|
||||
// continue
|
||||
// }
|
||||
|
||||
status[k] = struct {
|
||||
Status int
|
||||
WaitTime time.Duration
|
||||
LiveDate time.Time
|
||||
}{
|
||||
Status: v.status,
|
||||
WaitTime: v.waitTime,
|
||||
LiveDate: v.liveDate,
|
||||
}
|
||||
}
|
||||
|
||||
return status
|
||||
}
|
||||
|
||||
// Persist the monitor current state to a file.
|
||||
// The file is located in the configured config directory
|
||||
func (m *Monitor) Persist() error {
|
||||
fd, err := os.Create(filepath.Join(config.Instance().Dir(), "livestreams.dat"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer fd.Close()
|
||||
|
||||
slog.Debug("persisting livestream monitor state")
|
||||
|
||||
return gob.NewEncoder(fd).Encode(m.streams)
|
||||
}
|
||||
|
||||
// Restore a saved state and resume the monitored livestreams
|
||||
func (m *Monitor) Restore() error {
|
||||
fd, err := os.Open(filepath.Join(config.Instance().Dir(), "livestreams.dat"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer fd.Close()
|
||||
|
||||
restored := make(map[string]*LiveStream)
|
||||
|
||||
if err := gob.NewDecoder(fd).Decode(&restored); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for k := range restored {
|
||||
m.Add(k)
|
||||
}
|
||||
|
||||
slog.Debug("restored livestream monitor state")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Return a fan-in logs channel
|
||||
func (m *Monitor) Logs() <-chan []byte {
|
||||
return m.logs
|
||||
}
|
||||
Reference in New Issue
Block a user