77 lines
1.6 KiB
Go
77 lines
1.6 KiB
Go
package playback
|
|
|
|
import "fmt"
|
|
|
|
type SessionTopology uint8
|
|
|
|
const (
|
|
TopologyIdle SessionTopology = iota
|
|
TopologyIndependent
|
|
TopologySynchronized
|
|
)
|
|
|
|
type SyncPredicate func(video, audio FeedConfig) bool
|
|
|
|
type SessionPlan struct {
|
|
Topology SessionTopology
|
|
|
|
// Desired states for independent slots.
|
|
Video FeedConfig
|
|
Audio FeedConfig
|
|
|
|
// Desired state for the synchronized slot.
|
|
Sync SyncPairConfig
|
|
}
|
|
|
|
func BuildSessionPlan(
|
|
desired SessionConfig,
|
|
canSync SyncPredicate,
|
|
) (SessionPlan, error) {
|
|
if err := desired.Validate(); err != nil {
|
|
return SessionPlan{}, fmt.Errorf("validate desired session: %w", err)
|
|
}
|
|
|
|
if desired.SyncRequested &&
|
|
desired.Video.Active &&
|
|
desired.Audio.Active &&
|
|
canSync != nil &&
|
|
canSync(desired.Video, desired.Audio) {
|
|
return SessionPlan{
|
|
Topology: TopologySynchronized,
|
|
Video: stoppedFeed(desired.Video),
|
|
Audio: stoppedFeed(desired.Audio),
|
|
Sync: SyncPairConfig{
|
|
Video: desired.Video,
|
|
Audio: desired.Audio,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
if desired.Video.Active || desired.Audio.Active {
|
|
return SessionPlan{
|
|
Topology: TopologyIndependent,
|
|
Video: desired.Video,
|
|
Audio: desired.Audio,
|
|
Sync: SyncPairConfig{
|
|
Video: stoppedFeed(desired.Video),
|
|
Audio: stoppedFeed(desired.Audio),
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
return SessionPlan{
|
|
Topology: TopologyIdle,
|
|
Video: stoppedFeed(desired.Video),
|
|
Audio: stoppedFeed(desired.Audio),
|
|
Sync: SyncPairConfig{
|
|
Video: stoppedFeed(desired.Video),
|
|
Audio: stoppedFeed(desired.Audio),
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func stoppedFeed(config FeedConfig) FeedConfig {
|
|
config.Active = false
|
|
return config
|
|
}
|