package playback import "time" type PlaylistTimingState struct { Revision uint64 Duration time.Duration Ready bool Started bool Paused bool Expired bool Remaining time.Duration Deadline time.Time } func NewPlaylistTiming( revision uint64, duration time.Duration, ) PlaylistTimingState { return PlaylistTimingState{ Revision: revision, Duration: duration, Remaining: duration, } } func StartPlaylistTiming( current PlaylistTimingState, revision uint64, now time.Time, ) (PlaylistTimingState, bool) { if revision != current.Revision || current.Duration <= 0 || current.Started || current.Paused || current.Expired { return current, false } next := current if next.Remaining <= 0 { next.Remaining = next.Duration } next.Ready = true next.Started = true next.Deadline = now.Add(next.Remaining) return next, true } func PausePlaylistTiming( current PlaylistTimingState, revision uint64, now time.Time, ) (PlaylistTimingState, bool) { if revision != current.Revision || current.Duration <= 0 || current.Paused || current.Expired { return current, false } next := current if next.Started { next.Remaining = next.Deadline.Sub(now) if next.Remaining < 0 { next.Remaining = 0 } if next.Remaining > next.Duration { next.Remaining = next.Duration } next.Started = false next.Deadline = time.Time{} } next.Paused = true return next, true } func ResumePlaylistTiming( current PlaylistTimingState, revision uint64, now time.Time, ) (PlaylistTimingState, bool) { if revision != current.Revision || current.Duration <= 0 || !current.Paused || current.Expired { return current, false } next := current next.Paused = false if next.Ready { next.Started = true next.Deadline = now.Add(next.Remaining) } return next, true } func ExpirePlaylistTiming( current PlaylistTimingState, revision uint64, now time.Time, ) (PlaylistTimingState, bool) { if revision != current.Revision || !current.Started || now.Before(current.Deadline) { return current, false } next := current next.Started = false next.Paused = false next.Deadline = time.Time{} next.Expired = true next.Remaining = 0 return next, true }