package store import ( "errors" "ffmpeg-playout/playout" "log" "sync" "time" ) type Store struct { Playouts map[int]*playout.Job DefaultDuration time.Duration Outputs []string *playout.Config sync.RWMutex } func NewStore(o []string, defaultDuration string, playoutScriptPath string, playoutScript string, tmpDir string, prometheus string) (*Store, error) { playouts := make(map[int]*playout.Job) var d time.Duration var err error if d, err = time.ParseDuration(defaultDuration); err != nil { log.Fatal("Failed to set Default Duration: ", err) } pcfg := playout.Config{ PlayoutScriptPath: playoutScriptPath, PlayoutScript: playoutScript, ProgressDir: tmpDir, PrometheusPushGateway: prometheus, } store := &Store{Playouts: playouts, DefaultDuration: d, Outputs: o, Config: &pcfg} return store, nil } func (s *Store) AddPlayout(p *playout.Job) (string, error) { outputs := s.Outputs for _, value := range s.Playouts { if len(outputs) != 0 && (value.StartAt.After(p.StartAt) && value.StartAt.Before(p.StopAt) || value.StopAt.After(p.StartAt) && value.StopAt.Before(p.StopAt) || p.StartAt.After(value.StartAt) && p.StartAt.Before(value.StopAt) || p.StopAt.After(value.StartAt) && p.StopAt.Before(value.StopAt)) { inSlice, index := stringInSlice(value.Output, outputs) if inSlice { outputs = remove(outputs, index) } } } var output string if len(outputs) != 0 { output = outputs[0] } else { return "", errors.New("no output available") } p.Output = output s.Playouts[p.ID] = p return output, nil } func (s *Store) DeletePlayout(id int) { s.Lock() delete(s.Playouts, id) s.Unlock() } //https://stackoverflow.com/a/15323988/10997297 func stringInSlice(a string, list []string) (bool, int) { for index, b := range list { if b == a { return true, index } } return false, 0 } func remove(s []string, i int) []string { s[i] = s[len(s)-1] // We do not need to put s[i] at the end, as it will be discarded anyway return s[:len(s)-1] }