diff options
Diffstat (limited to 'MediaBrowser.Controller/SyncPlay/GroupStates/PausedGroupState.cs')
| -rw-r--r-- | MediaBrowser.Controller/SyncPlay/GroupStates/PausedGroupState.cs | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/MediaBrowser.Controller/SyncPlay/GroupStates/PausedGroupState.cs b/MediaBrowser.Controller/SyncPlay/GroupStates/PausedGroupState.cs new file mode 100644 index 0000000000..fba8ba9e2e --- /dev/null +++ b/MediaBrowser.Controller/SyncPlay/GroupStates/PausedGroupState.cs @@ -0,0 +1,165 @@ +using System; +using System.Threading; +using MediaBrowser.Controller.Session; +using MediaBrowser.Controller.SyncPlay.PlaybackRequests; +using MediaBrowser.Model.SyncPlay; +using Microsoft.Extensions.Logging; + +namespace MediaBrowser.Controller.SyncPlay.GroupStates +{ + /// <summary> + /// Class PausedGroupState. + /// </summary> + /// <remarks> + /// Class is not thread-safe, external locking is required when accessing methods. + /// </remarks> + public class PausedGroupState : AbstractGroupState + { + /// <summary> + /// The logger. + /// </summary> + private readonly ILogger<PausedGroupState> _logger; + + /// <summary> + /// Initializes a new instance of the <see cref="PausedGroupState"/> class. + /// </summary> + /// <param name="loggerFactory">Instance of the <see cref="ILoggerFactory"/> interface.</param> + public PausedGroupState(ILoggerFactory loggerFactory) + : base(loggerFactory) + { + _logger = LoggerFactory.CreateLogger<PausedGroupState>(); + } + + /// <inheritdoc /> + public override GroupStateType Type { get; } = GroupStateType.Paused; + + /// <inheritdoc /> + public override void SessionJoined(IGroupStateContext context, GroupStateType prevState, SessionInfo session, CancellationToken cancellationToken) + { + // Wait for session to be ready. + var waitingState = new WaitingGroupState(LoggerFactory); + context.SetState(waitingState); + waitingState.SessionJoined(context, Type, session, cancellationToken); + } + + /// <inheritdoc /> + public override void SessionLeaving(IGroupStateContext context, GroupStateType prevState, SessionInfo session, CancellationToken cancellationToken) + { + // Do nothing. + } + + /// <inheritdoc /> + public override void HandleRequest(PlayGroupRequest request, IGroupStateContext context, GroupStateType prevState, SessionInfo session, CancellationToken cancellationToken) + { + // Change state. + var waitingState = new WaitingGroupState(LoggerFactory); + context.SetState(waitingState); + waitingState.HandleRequest(request, context, Type, session, cancellationToken); + } + + /// <inheritdoc /> + public override void HandleRequest(UnpauseGroupRequest request, IGroupStateContext context, GroupStateType prevState, SessionInfo session, CancellationToken cancellationToken) + { + // Change state. + var playingState = new PlayingGroupState(LoggerFactory); + context.SetState(playingState); + playingState.HandleRequest(request, context, Type, session, cancellationToken); + } + + /// <inheritdoc /> + public override void HandleRequest(PauseGroupRequest request, IGroupStateContext context, GroupStateType prevState, SessionInfo session, CancellationToken cancellationToken) + { + if (!prevState.Equals(Type)) + { + // Pause group and compute the media playback position. + var currentTime = DateTime.UtcNow; + var elapsedTime = currentTime - context.LastActivity; + context.LastActivity = currentTime; + // Elapsed time is negative if event happens + // during the delay added to account for latency. + // In this phase clients haven't started the playback yet. + // In other words, LastActivity is in the future, + // when playback unpause is supposed to happen. + // Seek only if playback actually started. + context.PositionTicks += Math.Max(elapsedTime.Ticks, 0); + + var command = context.NewSyncPlayCommand(SendCommandType.Pause); + context.SendCommand(session, SyncPlayBroadcastType.AllGroup, command, cancellationToken); + + // Notify relevant state change event. + SendGroupStateUpdate(context, request, session, cancellationToken); + } + else + { + // Client got lost, sending current state. + var command = context.NewSyncPlayCommand(SendCommandType.Pause); + context.SendCommand(session, SyncPlayBroadcastType.CurrentSession, command, cancellationToken); + } + } + + /// <inheritdoc /> + public override void HandleRequest(StopGroupRequest request, IGroupStateContext context, GroupStateType prevState, SessionInfo session, CancellationToken cancellationToken) + { + // Change state. + var idleState = new IdleGroupState(LoggerFactory); + context.SetState(idleState); + idleState.HandleRequest(request, context, Type, session, cancellationToken); + } + + /// <inheritdoc /> + public override void HandleRequest(SeekGroupRequest request, IGroupStateContext context, GroupStateType prevState, SessionInfo session, CancellationToken cancellationToken) + { + // Change state. + var waitingState = new WaitingGroupState(LoggerFactory); + context.SetState(waitingState); + waitingState.HandleRequest(request, context, Type, session, cancellationToken); + } + + /// <inheritdoc /> + public override void HandleRequest(BufferGroupRequest request, IGroupStateContext context, GroupStateType prevState, SessionInfo session, CancellationToken cancellationToken) + { + // Change state. + var waitingState = new WaitingGroupState(LoggerFactory); + context.SetState(waitingState); + waitingState.HandleRequest(request, context, Type, session, cancellationToken); + } + + /// <inheritdoc /> + public override void HandleRequest(ReadyGroupRequest request, IGroupStateContext context, GroupStateType prevState, SessionInfo session, CancellationToken cancellationToken) + { + if (prevState.Equals(Type)) + { + // Client got lost, sending current state. + var command = context.NewSyncPlayCommand(SendCommandType.Pause); + context.SendCommand(session, SyncPlayBroadcastType.CurrentSession, command, cancellationToken); + } + else if (prevState.Equals(GroupStateType.Waiting)) + { + // Sending current state to all clients. + var command = context.NewSyncPlayCommand(SendCommandType.Pause); + context.SendCommand(session, SyncPlayBroadcastType.AllGroup, command, cancellationToken); + + // Notify relevant state change event. + SendGroupStateUpdate(context, request, session, cancellationToken); + } + } + + /// <inheritdoc /> + public override void HandleRequest(NextItemGroupRequest request, IGroupStateContext context, GroupStateType prevState, SessionInfo session, CancellationToken cancellationToken) + { + // Change state. + var waitingState = new WaitingGroupState(LoggerFactory); + context.SetState(waitingState); + waitingState.HandleRequest(request, context, Type, session, cancellationToken); + } + + /// <inheritdoc /> + public override void HandleRequest(PreviousItemGroupRequest request, IGroupStateContext context, GroupStateType prevState, SessionInfo session, CancellationToken cancellationToken) + { + // Change state. + var waitingState = new WaitingGroupState(LoggerFactory); + context.SetState(waitingState); + waitingState.HandleRequest(request, context, Type, session, cancellationToken); + } + } +} |
