PausedGroupState.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. using System;
  2. using System.Threading;
  3. using MediaBrowser.Controller.Session;
  4. using MediaBrowser.Model.SyncPlay;
  5. using Microsoft.Extensions.Logging;
  6. namespace MediaBrowser.Controller.SyncPlay
  7. {
  8. /// <summary>
  9. /// Class PausedGroupState.
  10. /// </summary>
  11. /// <remarks>
  12. /// Class is not thread-safe, external locking is required when accessing methods.
  13. /// </remarks>
  14. public class PausedGroupState : AbstractGroupState
  15. {
  16. /// <summary>
  17. /// Initializes a new instance of the <see cref="PausedGroupState"/> class.
  18. /// </summary>
  19. /// <param name="logger">Instance of the <see cref="ILogger"/> interface.</param>
  20. public PausedGroupState(ILogger logger)
  21. : base(logger)
  22. {
  23. // Do nothing.
  24. }
  25. /// <inheritdoc />
  26. public override GroupStateType Type
  27. {
  28. get
  29. {
  30. return GroupStateType.Paused;
  31. }
  32. }
  33. /// <inheritdoc />
  34. public override void SessionJoined(IGroupStateContext context, GroupStateType prevState, SessionInfo session, CancellationToken cancellationToken)
  35. {
  36. // Wait for session to be ready.
  37. var waitingState = new WaitingGroupState(Logger);
  38. context.SetState(waitingState);
  39. waitingState.SessionJoined(context, Type, session, cancellationToken);
  40. }
  41. /// <inheritdoc />
  42. public override void SessionLeaving(IGroupStateContext context, GroupStateType prevState, SessionInfo session, CancellationToken cancellationToken)
  43. {
  44. // Do nothing.
  45. }
  46. /// <inheritdoc />
  47. public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, PlayGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
  48. {
  49. // Change state.
  50. var waitingState = new WaitingGroupState(Logger);
  51. context.SetState(waitingState);
  52. waitingState.HandleRequest(context, Type, request, session, cancellationToken);
  53. }
  54. /// <inheritdoc />
  55. public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, UnpauseGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
  56. {
  57. // Change state.
  58. var playingState = new PlayingGroupState(Logger);
  59. context.SetState(playingState);
  60. playingState.HandleRequest(context, Type, request, session, cancellationToken);
  61. }
  62. /// <inheritdoc />
  63. public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, PauseGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
  64. {
  65. if (!prevState.Equals(Type))
  66. {
  67. // Pause group and compute the media playback position.
  68. var currentTime = DateTime.UtcNow;
  69. var elapsedTime = currentTime - context.LastActivity;
  70. context.LastActivity = currentTime;
  71. // Elapsed time is negative if event happens
  72. // during the delay added to account for latency.
  73. // In this phase clients haven't started the playback yet.
  74. // In other words, LastActivity is in the future,
  75. // when playback unpause is supposed to happen.
  76. // Seek only if playback actually started.
  77. context.PositionTicks += Math.Max(elapsedTime.Ticks, 0);
  78. var command = context.NewSyncPlayCommand(SendCommandType.Pause);
  79. context.SendCommand(session, SyncPlayBroadcastType.AllGroup, command, cancellationToken);
  80. // Notify relevant state change event.
  81. SendGroupStateUpdate(context, request, session, cancellationToken);
  82. }
  83. else
  84. {
  85. // Client got lost, sending current state.
  86. var command = context.NewSyncPlayCommand(SendCommandType.Pause);
  87. context.SendCommand(session, SyncPlayBroadcastType.CurrentSession, command, cancellationToken);
  88. }
  89. }
  90. /// <inheritdoc />
  91. public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, StopGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
  92. {
  93. // Change state.
  94. var idleState = new IdleGroupState(Logger);
  95. context.SetState(idleState);
  96. idleState.HandleRequest(context, Type, request, session, cancellationToken);
  97. }
  98. /// <inheritdoc />
  99. public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, SeekGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
  100. {
  101. // Change state.
  102. var waitingState = new WaitingGroupState(Logger);
  103. context.SetState(waitingState);
  104. waitingState.HandleRequest(context, Type, request, session, cancellationToken);
  105. }
  106. /// <inheritdoc />
  107. public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, BufferGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
  108. {
  109. // Change state.
  110. var waitingState = new WaitingGroupState(Logger);
  111. context.SetState(waitingState);
  112. waitingState.HandleRequest(context, Type, request, session, cancellationToken);
  113. }
  114. /// <inheritdoc />
  115. public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, ReadyGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
  116. {
  117. if (prevState.Equals(Type))
  118. {
  119. // Client got lost, sending current state.
  120. var command = context.NewSyncPlayCommand(SendCommandType.Pause);
  121. context.SendCommand(session, SyncPlayBroadcastType.CurrentSession, command, cancellationToken);
  122. }
  123. else if (prevState.Equals(GroupStateType.Waiting))
  124. {
  125. // Sending current state to all clients.
  126. var command = context.NewSyncPlayCommand(SendCommandType.Pause);
  127. context.SendCommand(session, SyncPlayBroadcastType.AllGroup, command, cancellationToken);
  128. // Notify relevant state change event.
  129. SendGroupStateUpdate(context, request, session, cancellationToken);
  130. }
  131. }
  132. /// <inheritdoc />
  133. public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, NextTrackGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
  134. {
  135. // Change state.
  136. var waitingState = new WaitingGroupState(Logger);
  137. context.SetState(waitingState);
  138. waitingState.HandleRequest(context, Type, request, session, cancellationToken);
  139. }
  140. /// <inheritdoc />
  141. public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, PreviousTrackGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
  142. {
  143. // Change state.
  144. var waitingState = new WaitingGroupState(Logger);
  145. context.SetState(waitingState);
  146. waitingState.HandleRequest(context, Type, request, session, cancellationToken);
  147. }
  148. }
  149. }