@ -34,7 +34,7 @@ namespace MediaBrowser.Controller.SyncPlay
/// </summary>
public WaitingGroupState ( ILogger logger ) : base ( logger )
{
// Do nothing
// Do nothing .
}
/// <inheritdoc />
@ -46,7 +46,7 @@ namespace MediaBrowser.Controller.SyncPlay
/// <inheritdoc />
public override void SessionJoined ( ISyncPlayStateContext context , GroupState prevState , SessionInfo session , CancellationToken cancellationToken )
{
// Save state if first event
// Save state if first event .
if ( ! InitialStateSet )
{
InitialState = prevState ;
@ -55,23 +55,23 @@ namespace MediaBrowser.Controller.SyncPlay
if ( prevState . Equals ( GroupState . Playing ) ) {
ResumePlaying = true ;
// Pause group and compute the media playback position
// Pause group and compute the media playback position .
var currentTime = DateTime . UtcNow ;
var elapsedTime = currentTime - context . LastActivity ;
context . LastActivity = currentTime ;
// Seek only if playback actually started
// Event may happen during the delay added to account for latency
// Seek only if playback actually started .
// Event may happen during the delay added to account for latency .
context . PositionTicks + = elapsedTime . Ticks > 0 ? elapsedTime . Ticks : 0 ;
}
// Prepare new session
// Prepare new session .
var playQueueUpdate = context . GetPlayQueueUpdate ( PlayQueueUpdateReason . NewPlaylist ) ;
var update = context . NewSyncPlayGroupUpdate ( GroupUpdateType . PlayQueue , playQueueUpdate ) ;
context . SendGroupUpdate ( session , SyncPlayBroadcastType . CurrentSession , update , cancellationToken ) ;
context . SetBuffering ( session , true ) ;
// Send pause command to all non-buffering sessions
// Send pause command to all non-buffering sessions .
var command = context . NewSyncPlayCommand ( SendCommandType . Pause ) ;
context . SendCommand ( session , SyncPlayBroadcastType . AllReady , command , cancellationToken ) ;
}
@ -79,7 +79,7 @@ namespace MediaBrowser.Controller.SyncPlay
/// <inheritdoc />
public override void SessionLeaving ( ISyncPlayStateContext context , GroupState prevState , SessionInfo session , CancellationToken cancellationToken )
{
// Save state if first event
// Save state if first event .
if ( ! InitialStateSet )
{
InitialState = prevState ;
@ -92,7 +92,7 @@ namespace MediaBrowser.Controller.SyncPlay
{
if ( ResumePlaying )
{
// Client, that was buffering, left the group
// Client, that was buffering, left the group .
var playingState = new PlayingGroupState ( _logger ) ;
context . SetState ( playingState ) ;
var unpauseRequest = new UnpauseGroupRequest ( ) ;
@ -102,7 +102,7 @@ namespace MediaBrowser.Controller.SyncPlay
}
else
{
// Group is ready, returning to previous state
// Group is ready, returning to previous state .
var pausedState = new PausedGroupState ( _logger ) ;
context . SetState ( pausedState ) ;
@ -114,7 +114,7 @@ namespace MediaBrowser.Controller.SyncPlay
/// <inheritdoc />
public override void HandleRequest ( ISyncPlayStateContext context , GroupState prevState , PlayGroupRequest request , SessionInfo session , CancellationToken cancellationToken )
{
// Save state if first event
// Save state if first event .
if ( ! InitialStateSet )
{
InitialState = prevState ;
@ -128,7 +128,7 @@ namespace MediaBrowser.Controller.SyncPlay
{
_logger . LogError ( "HandleRequest: {0} in group {1}, unable to set playing queue." , request . GetRequestType ( ) , context . GroupId . ToString ( ) ) ;
// Ignore request and return to previous state
// Ignore request and return to previous state .
ISyncPlayState newState ;
switch ( prevState )
{
@ -151,7 +151,7 @@ namespace MediaBrowser.Controller.SyncPlay
var update = context . NewSyncPlayGroupUpdate ( GroupUpdateType . PlayQueue , playQueueUpdate ) ;
context . SendGroupUpdate ( session , SyncPlayBroadcastType . AllGroup , update , cancellationToken ) ;
// Reset status of sessions and await for all Ready events before sending Play command
// Reset status of sessions and await for all Ready events before sending Play command .
context . SetAllBuffering ( true ) ;
_logger . LogDebug ( "HandleRequest: {0} in group {1}, {2} set a new play queue." , request . GetRequestType ( ) , context . GroupId . ToString ( ) , session . Id . ToString ( ) ) ;
@ -160,7 +160,7 @@ namespace MediaBrowser.Controller.SyncPlay
/// <inheritdoc />
public override void HandleRequest ( ISyncPlayStateContext context , GroupState prevState , SetPlaylistItemGroupRequest request , SessionInfo session , CancellationToken cancellationToken )
{
// Save state if first event
// Save state if first event .
if ( ! InitialStateSet )
{
InitialState = prevState ;
@ -176,12 +176,12 @@ namespace MediaBrowser.Controller.SyncPlay
var update = context . NewSyncPlayGroupUpdate ( GroupUpdateType . PlayQueue , playQueueUpdate ) ;
context . SendGroupUpdate ( session , SyncPlayBroadcastType . AllGroup , update , cancellationToken ) ;
// Reset status of sessions and await for all Ready events before sending Play command
// Reset status of sessions and await for all Ready events before sending Play command .
context . SetAllBuffering ( true ) ;
}
else
{
// Return to old state
// Return to old state .
ISyncPlayState newState ;
switch ( prevState )
{
@ -205,7 +205,7 @@ namespace MediaBrowser.Controller.SyncPlay
/// <inheritdoc />
public override void HandleRequest ( ISyncPlayStateContext context , GroupState prevState , UnpauseGroupRequest request , SessionInfo session , CancellationToken cancellationToken )
{
// Save state if first event
// Save state if first event .
if ( ! InitialStateSet )
{
InitialState = prevState ;
@ -221,7 +221,7 @@ namespace MediaBrowser.Controller.SyncPlay
var update = context . NewSyncPlayGroupUpdate ( GroupUpdateType . PlayQueue , playQueueUpdate ) ;
context . SendGroupUpdate ( session , SyncPlayBroadcastType . AllGroup , update , cancellationToken ) ;
// Reset status of sessions and await for all Ready events before sending Play command
// Reset status of sessions and await for all Ready events before sending Play command .
context . SetAllBuffering ( true ) ;
_logger . LogDebug ( "HandleRequest: {0} in group {1}, waiting for all ready events." , request . GetRequestType ( ) , context . GroupId . ToString ( ) ) ;
@ -232,10 +232,10 @@ namespace MediaBrowser.Controller.SyncPlay
{
_logger . LogDebug ( "HandleRequest: {0} in group {1}, ignoring sessions that are not ready and forcing the playback to start." , request . GetRequestType ( ) , context . GroupId . ToString ( ) ) ;
// An Unpause request is forcing the playback to start, ignoring sessions that are not ready
// An Unpause request is forcing the playback to start, ignoring sessions that are not ready .
context . SetAllBuffering ( false ) ;
// Change state
// Change state .
var playingState = new PlayingGroupState ( _logger ) ;
playingState . IgnoreBuffering = true ;
context . SetState ( playingState ) ;
@ -243,10 +243,10 @@ namespace MediaBrowser.Controller.SyncPlay
}
else
{
// Group would have gone to paused state, now will go to playing state when ready
// Group would have gone to paused state, now will go to playing state when ready .
ResumePlaying = true ;
// Notify relevant state change event
// Notify relevant state change event .
SendGroupStateUpdate ( context , request , session , cancellationToken ) ;
}
}
@ -255,31 +255,31 @@ namespace MediaBrowser.Controller.SyncPlay
/// <inheritdoc />
public override void HandleRequest ( ISyncPlayStateContext context , GroupState prevState , PauseGroupRequest request , SessionInfo session , CancellationToken cancellationToken )
{
// Save state if first event
// Save state if first event .
if ( ! InitialStateSet )
{
InitialState = prevState ;
InitialStateSet = true ;
}
// Wait for sessions to be ready, then switch to paused state
// Wait for sessions to be ready, then switch to paused state .
ResumePlaying = false ;
// Notify relevant state change event
// Notify relevant state change event .
SendGroupStateUpdate ( context , request , session , cancellationToken ) ;
}
/// <inheritdoc />
public override void HandleRequest ( ISyncPlayStateContext context , GroupState prevState , StopGroupRequest request , SessionInfo session , CancellationToken cancellationToken )
{
// Save state if first event
// Save state if first event .
if ( ! InitialStateSet )
{
InitialState = prevState ;
InitialStateSet = true ;
}
// Change state
// Change state .
var idleState = new IdleGroupState ( _logger ) ;
context . SetState ( idleState ) ;
idleState . HandleRequest ( context , GetGroupState ( ) , request , session , cancellationToken ) ;
@ -288,7 +288,7 @@ namespace MediaBrowser.Controller.SyncPlay
/// <inheritdoc />
public override void HandleRequest ( ISyncPlayStateContext context , GroupState prevState , SeekGroupRequest request , SessionInfo session , CancellationToken cancellationToken )
{
// Save state if first event
// Save state if first event .
if ( ! InitialStateSet )
{
InitialState = prevState ;
@ -304,34 +304,34 @@ namespace MediaBrowser.Controller.SyncPlay
ResumePlaying = false ;
}
// Sanitize PositionTicks
// Sanitize PositionTicks .
var ticks = context . SanitizePositionTicks ( request . PositionTicks ) ;
// Seek
// Seek .
context . PositionTicks = ticks ;
context . LastActivity = DateTime . UtcNow ;
var command = context . NewSyncPlayCommand ( SendCommandType . Seek ) ;
context . SendCommand ( session , SyncPlayBroadcastType . AllGroup , command , cancellationToken ) ;
// Reset status of sessions and await for all Ready events before sending Play command
// Reset status of sessions and await for all Ready events before sending Play command .
context . SetAllBuffering ( true ) ;
// Notify relevant state change event
// Notify relevant state change event .
SendGroupStateUpdate ( context , request , session , cancellationToken ) ;
}
/// <inheritdoc />
public override void HandleRequest ( ISyncPlayStateContext context , GroupState prevState , BufferGroupRequest request , SessionInfo session , CancellationToken cancellationToken )
{
// Save state if first event
// Save state if first event .
if ( ! InitialStateSet )
{
InitialState = prevState ;
InitialStateSet = true ;
}
// Make sure the client is playing the correct item
// Make sure the client is playing the correct item .
if ( ! request . PlaylistItemId . Equals ( context . PlayQueue . GetPlayingItemPlaylistId ( ) ) )
{
_logger . LogDebug ( "HandleRequest: {0} in group {1}, {2} has wrong playlist item." , request . GetRequestType ( ) , context . GroupId . ToString ( ) , session . Id . ToString ( ) ) ;
@ -346,60 +346,60 @@ namespace MediaBrowser.Controller.SyncPlay
if ( prevState . Equals ( GroupState . Playing ) )
{
// Resume playback when all ready
// Resume playback when all ready .
ResumePlaying = true ;
context . SetBuffering ( session , true ) ;
// Pause group and compute the media playback position
// Pause group and compute the media playback position .
var currentTime = DateTime . UtcNow ;
var elapsedTime = currentTime - context . LastActivity ;
context . LastActivity = currentTime ;
context . PositionTicks + = elapsedTime . Ticks > 0 ? elapsedTime . Ticks : 0 ;
// Send pause command to all non-buffering sessions
// Send pause command to all non-buffering sessions .
var command = context . NewSyncPlayCommand ( SendCommandType . Pause ) ;
context . SendCommand ( session , SyncPlayBroadcastType . AllReady , command , cancellationToken ) ;
}
else if ( prevState . Equals ( GroupState . Paused ) )
{
// Don't resume playback when all ready
// Don't resume playback when all ready .
ResumePlaying = false ;
context . SetBuffering ( session , true ) ;
// Send pause command to buffering session
// Send pause command to buffering session .
var command = context . NewSyncPlayCommand ( SendCommandType . Pause ) ;
context . SendCommand ( session , SyncPlayBroadcastType . CurrentSession , command , cancellationToken ) ;
}
else if ( prevState . Equals ( GroupState . Waiting ) )
{
// Another session is now buffering
// Another session is now buffering .
context . SetBuffering ( session , true ) ;
if ( ! ResumePlaying )
{
// Force update for this session that should be paused
// Force update for this session that should be paused .
var command = context . NewSyncPlayCommand ( SendCommandType . Pause ) ;
context . SendCommand ( session , SyncPlayBroadcastType . CurrentSession , command , cancellationToken ) ;
}
}
// Notify relevant state change event
// Notify relevant state change event .
SendGroupStateUpdate ( context , request , session , cancellationToken ) ;
}
/// <inheritdoc />
public override void HandleRequest ( ISyncPlayStateContext context , GroupState prevState , ReadyGroupRequest request , SessionInfo session , CancellationToken cancellationToken )
{
// Save state if first event
// Save state if first event .
if ( ! InitialStateSet )
{
InitialState = prevState ;
InitialStateSet = true ;
}
// Make sure the client is playing the correct item
// Make sure the client is playing the correct item .
if ( ! request . PlaylistItemId . Equals ( context . PlayQueue . GetPlayingItemPlaylistId ( ) ) )
{
_logger . LogDebug ( "HandleRequest: {0} in group {1}, {2} has wrong playlist item." , request . GetRequestType ( ) , context . GroupId . ToString ( ) , session . Id . ToString ( ) ) ;
@ -432,28 +432,28 @@ namespace MediaBrowser.Controller.SyncPlay
if ( ResumePlaying )
{
// Handle case where session reported as ready but in reality
// it has no clue of the real position nor the playback state
// it has no clue of the real position nor the playback state .
if ( ! request . IsPlaying & & Math . Abs ( context . PositionTicks - requestTicks ) > TimeSpan . FromSeconds ( 0.5 ) . Ticks ) {
// Session not ready at all
// Session not ready at all .
context . SetBuffering ( session , true ) ;
// Correcting session's position
// Correcting session's position .
var command = context . NewSyncPlayCommand ( SendCommandType . Seek ) ;
context . SendCommand ( session , SyncPlayBroadcastType . CurrentSession , command , cancellationToken ) ;
// Notify relevant state change event
// Notify relevant state change event .
SendGroupStateUpdate ( context , request , session , cancellationToken ) ;
_logger . LogDebug ( "HandleRequest: {0} in group {1}, {2} got lost in time, correcting." , request . GetRequestType ( ) , context . GroupId . ToString ( ) , session . Id . ToString ( ) ) ;
return ;
}
// Session is ready
// Session is ready .
context . SetBuffering ( session , false ) ;
if ( context . IsBuffering ( ) )
{
// Others are still buffering, tell this client to pause when ready
// Others are still buffering, tell this client to pause when ready .
var command = context . NewSyncPlayCommand ( SendCommandType . Pause ) ;
var pauseAtTime = currentTime . AddTicks ( delayTicks ) ;
command . When = context . DateToUTCString ( pauseAtTime ) ;
@ -463,11 +463,11 @@ namespace MediaBrowser.Controller.SyncPlay
}
else
{
// If all ready, then start playback
// Let other clients resume as soon as the buffering client catches up
// If all ready, then start playback .
// Let other clients resume as soon as the buffering client catches up .
if ( delayTicks > context . GetHighestPing ( ) * 2 * TimeSpan . TicksPerMillisecond )
{
// Client that was buffering is recovering, notifying others to resume
// Client that was buffering is recovering, notifying others to resume .
context . LastActivity = currentTime . AddTicks ( delayTicks ) ;
var command = context . NewSyncPlayCommand ( SendCommandType . Unpause ) ;
var filter = SyncPlayBroadcastType . AllExceptCurrentSession ;
@ -482,7 +482,7 @@ namespace MediaBrowser.Controller.SyncPlay
}
else
{
// Client, that was buffering, resumed playback but did not update others in time
// Client, that was buffering, resumed playback but did not update others in time .
delayTicks = context . GetHighestPing ( ) * 2 * TimeSpan . TicksPerMillisecond ;
delayTicks = delayTicks < context . DefaultPing ? context . DefaultPing : delayTicks ;
@ -494,7 +494,7 @@ namespace MediaBrowser.Controller.SyncPlay
_logger . LogDebug ( "HandleRequest: {0} in group {1}, {2} resumed playback but did not update others in time." , request . GetRequestType ( ) , context . GroupId . ToString ( ) , session . Id . ToString ( ) ) ;
}
// Change state
// Change state .
var playingState = new PlayingGroupState ( _logger ) ;
context . SetState ( playingState ) ;
playingState . HandleRequest ( context , GetGroupState ( ) , request , session , cancellationToken ) ;
@ -502,35 +502,35 @@ namespace MediaBrowser.Controller.SyncPlay
}
else
{
// Check that session is really ready, tollerate half second difference to account for player imperfections
// Check that session is really ready, tollerate half second difference to account for player imperfections .
if ( Math . Abs ( context . PositionTicks - requestTicks ) > TimeSpan . FromSeconds ( 0.5 ) . Ticks )
{
// Session still not ready
// Session still not ready .
context . SetBuffering ( session , true ) ;
// Session is seeking to wrong position, correcting
// Session is seeking to wrong position, correcting .
var command = context . NewSyncPlayCommand ( SendCommandType . Seek ) ;
context . SendCommand ( session , SyncPlayBroadcastType . CurrentSession , command , cancellationToken ) ;
// Notify relevant state change event
// Notify relevant state change event .
SendGroupStateUpdate ( context , request , session , cancellationToken ) ;
_logger . LogDebug ( "HandleRequest: {0} in group {1}, {2} was seeking to wrong position, correcting." , request . GetRequestType ( ) , context . GroupId . ToString ( ) , session . Id . ToString ( ) ) ;
return ;
} else {
// Session is ready
// Session is ready .
context . SetBuffering ( session , false ) ;
}
if ( ! context . IsBuffering ( ) )
{
// Group is ready, returning to previous state
// Group is ready, returning to previous state .
var pausedState = new PausedGroupState ( _logger ) ;
context . SetState ( pausedState ) ;
if ( InitialState . Equals ( GroupState . Playing ) )
{
// Group went from playing to waiting state and a pause request occured while waiting
// Group went from playing to waiting state and a pause request occured while waiting .
var pauserequest = new PauseGroupRequest ( ) ;
pausedState . HandleRequest ( context , GetGroupState ( ) , pauserequest , session , cancellationToken ) ;
}
@ -547,7 +547,7 @@ namespace MediaBrowser.Controller.SyncPlay
/// <inheritdoc />
public override void HandleRequest ( ISyncPlayStateContext context , GroupState prevState , NextTrackGroupRequest request , SessionInfo session , CancellationToken cancellationToken )
{
// Save state if first event
// Save state if first event .
if ( ! InitialStateSet )
{
InitialState = prevState ;
@ -556,7 +556,7 @@ namespace MediaBrowser.Controller.SyncPlay
ResumePlaying = true ;
// Make sure the client knows the playing item, to avoid duplicate requests
// Make sure the client knows the playing item, to avoid duplicate requests .
if ( ! request . PlaylistItemId . Equals ( context . PlayQueue . GetPlayingItemPlaylistId ( ) ) )
{
_logger . LogDebug ( "HandleRequest: {0} in group {1}, client provided the wrong playlist id." , request . GetRequestType ( ) , context . GroupId . ToString ( ) ) ;
@ -566,17 +566,17 @@ namespace MediaBrowser.Controller.SyncPlay
var newItem = context . NextItemInQueue ( ) ;
if ( newItem )
{
// Send playing-queue update
// Send playing-queue update .
var playQueueUpdate = context . GetPlayQueueUpdate ( PlayQueueUpdateReason . NextTrack ) ;
var update = context . NewSyncPlayGroupUpdate ( GroupUpdateType . PlayQueue , playQueueUpdate ) ;
context . SendGroupUpdate ( session , SyncPlayBroadcastType . AllGroup , update , cancellationToken ) ;
// Reset status of sessions and await for all Ready events before sending Play command
// Reset status of sessions and await for all Ready events before sending Play command .
context . SetAllBuffering ( true ) ;
}
else
{
// Return to old state
// Return to old state .
ISyncPlayState newState ;
switch ( prevState )
{
@ -600,7 +600,7 @@ namespace MediaBrowser.Controller.SyncPlay
/// <inheritdoc />
public override void HandleRequest ( ISyncPlayStateContext context , GroupState prevState , PreviousTrackGroupRequest request , SessionInfo session , CancellationToken cancellationToken )
{
// Save state if first event
// Save state if first event .
if ( ! InitialStateSet )
{
InitialState = prevState ;
@ -609,7 +609,7 @@ namespace MediaBrowser.Controller.SyncPlay
ResumePlaying = true ;
// Make sure the client knows the playing item, to avoid duplicate requests
// Make sure the client knows the playing item, to avoid duplicate requests .
if ( ! request . PlaylistItemId . Equals ( context . PlayQueue . GetPlayingItemPlaylistId ( ) ) )
{
_logger . LogDebug ( "HandleRequest: {0} in group {1}, client provided the wrong playlist id." , request . GetRequestType ( ) , context . GroupId . ToString ( ) ) ;
@ -619,17 +619,17 @@ namespace MediaBrowser.Controller.SyncPlay
var newItem = context . PreviousItemInQueue ( ) ;
if ( newItem )
{
// Send playing-queue update
// Send playing-queue update .
var playQueueUpdate = context . GetPlayQueueUpdate ( PlayQueueUpdateReason . PreviousTrack ) ;
var update = context . NewSyncPlayGroupUpdate ( GroupUpdateType . PlayQueue , playQueueUpdate ) ;
context . SendGroupUpdate ( session , SyncPlayBroadcastType . AllGroup , update , cancellationToken ) ;
// Reset status of sessions and await for all Ready events before sending Play command
// Reset status of sessions and await for all Ready events before sending Play command .
context . SetAllBuffering ( true ) ;
}
else
{
// Return to old state
// Return to old state .
ISyncPlayState newState ;
switch ( prevState )
{