Files
2026-09-01 01:22:03 +03:00

119 lines
2.6 KiB
Go

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
}