package playback import ( "errors" "fmt" ) type SessionCommandKind uint8 const ( CommandSetVideo SessionCommandKind = iota + 1 CommandSetAudio CommandStopVideo CommandStopAudio CommandStopAll CommandResumeVideo CommandResumeAudio CommandResumeAll CommandRemoveVideo CommandRemoveAudio CommandEnableSync CommandDisableSync CommandSetSession ) type SessionCommand struct { Kind SessionCommandKind Config FeedConfig // Used only by SetVideo and SetAudio. Session SessionConfig // Used only by SetSession. } var ( ErrUnknownSessionCommand = errors.New("unknown session command") ErrVideoNotConfigured = errors.New("video feed is not configured") ErrAudioNotConfigured = errors.New("audio feed is not configured") ) func ApplySessionCommand( current SessionConfig, command SessionCommand, ) (SessionConfig, error) { next := current switch command.Kind { case CommandSetVideo: if !command.Config.IsConfigured() { return current, ErrVideoNotConfigured } if err := command.Config.Validate(); err != nil { return current, fmt.Errorf("validate video command: %w", err) } next.Video = command.Config case CommandSetAudio: if !command.Config.IsConfigured() { return current, ErrAudioNotConfigured } if err := command.Config.Validate(); err != nil { return current, fmt.Errorf("validate audio command: %w", err) } next.Audio = command.Config case CommandStopVideo: next.Video.Active = false next.SyncRequested = false case CommandStopAudio: next.Audio.Active = false next.SyncRequested = false case CommandStopAll: next.Video.Active = false next.Audio.Active = false case CommandResumeVideo: if !next.Video.IsConfigured() { return current, ErrVideoNotConfigured } next.Video.Active = true case CommandResumeAudio: if !next.Audio.IsConfigured() { return current, ErrAudioNotConfigured } next.Audio.Active = true case CommandResumeAll: next.Video.Active = next.Video.IsConfigured() next.Audio.Active = next.Audio.IsConfigured() case CommandRemoveVideo: next.Video = FeedConfig{} next.SyncRequested = false case CommandRemoveAudio: next.Audio = FeedConfig{} next.SyncRequested = false case CommandEnableSync: next.SyncRequested = true case CommandDisableSync: next.SyncRequested = false case CommandSetSession: next = command.Session // Retry policy belongs to the running controller configuration, not to // GUI or playlist session selections. next.Retry = current.Retry default: return current, ErrUnknownSessionCommand } if err := next.Validate(); err != nil { return current, fmt.Errorf("validate desired session: %w", err) } return next, nil }