|  | @@ -194,26 +194,24 @@ namespace Emby.Server.Implementations.SyncPlay
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <inheritdoc />
 | 
	
		
			
				|  |  | -        public void InitGroup(SessionInfo session, CancellationToken cancellationToken)
 | 
	
		
			
				|  |  | +        public void CreateGroup(SessionInfo session, CancellationToken cancellationToken)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              _group.AddSession(session);
 | 
	
		
			
				|  |  |              _syncPlayManager.AddSessionToGroup(session, this);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              _group.PlayingItem = session.FullNowPlayingItem;
 | 
	
		
			
				|  |  | -            _group.IsPaused = true;
 | 
	
		
			
				|  |  | +            _group.IsPaused = session.PlayState.IsPaused;
 | 
	
		
			
				|  |  |              _group.PositionTicks = session.PlayState.PositionTicks ?? 0;
 | 
	
		
			
				|  |  |              _group.LastActivity = DateTime.UtcNow;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              var updateSession = NewSyncPlayGroupUpdate(GroupUpdateType.GroupJoined, DateToUTCString(DateTime.UtcNow));
 | 
	
		
			
				|  |  |              SendGroupUpdate(session, BroadcastType.CurrentSession, updateSession, cancellationToken);
 | 
	
		
			
				|  |  | -            var pauseCommand = NewSyncPlayCommand(SendCommandType.Pause);
 | 
	
		
			
				|  |  | -            SendCommand(session, BroadcastType.CurrentSession, pauseCommand, cancellationToken);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <inheritdoc />
 | 
	
		
			
				|  |  |          public void SessionJoin(SessionInfo session, JoinGroupRequest request, CancellationToken cancellationToken)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            if (session.NowPlayingItem?.Id == _group.PlayingItem.Id && request.PlayingItemId == _group.PlayingItem.Id)
 | 
	
		
			
				|  |  | +            if (session.NowPlayingItem?.Id == _group.PlayingItem.Id)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  _group.AddSession(session);
 | 
	
		
			
				|  |  |                  _syncPlayManager.AddSessionToGroup(session, this);
 | 
	
	
		
			
				|  | @@ -224,7 +222,7 @@ namespace Emby.Server.Implementations.SyncPlay
 | 
	
		
			
				|  |  |                  var updateOthers = NewSyncPlayGroupUpdate(GroupUpdateType.UserJoined, session.UserName);
 | 
	
		
			
				|  |  |                  SendGroupUpdate(session, BroadcastType.AllExceptCurrentSession, updateOthers, cancellationToken);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                // Client join and play, syncing will happen client side
 | 
	
		
			
				|  |  | +                // syncing will happen client side
 | 
	
		
			
				|  |  |                  if (!_group.IsPaused)
 | 
	
		
			
				|  |  |                  {
 | 
	
		
			
				|  |  |                      var playCommand = NewSyncPlayCommand(SendCommandType.Play);
 | 
	
	
		
			
				|  | @@ -262,10 +260,9 @@ namespace Emby.Server.Implementations.SyncPlay
 | 
	
		
			
				|  |  |          /// <inheritdoc />
 | 
	
		
			
				|  |  |          public void HandleRequest(SessionInfo session, PlaybackRequest request, CancellationToken cancellationToken)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            // The server's job is to mantain a consistent state to which clients refer to,
 | 
	
		
			
				|  |  | -            // as also to notify clients of state changes.
 | 
	
		
			
				|  |  | -            // The actual syncing of media playback happens client side.
 | 
	
		
			
				|  |  | -            // Clients are aware of the server's time and use it to sync.
 | 
	
		
			
				|  |  | +            // The server's job is to maintain a consistent state for clients to reference
 | 
	
		
			
				|  |  | +            // and notify clients of state changes. The actual syncing of media playback
 | 
	
		
			
				|  |  | +            // happens client side. Clients are aware of the server's time and use it to sync.
 | 
	
		
			
				|  |  |              switch (request.Type)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  case PlaybackRequestType.Play:
 | 
	
	
		
			
				|  | @@ -277,13 +274,13 @@ namespace Emby.Server.Implementations.SyncPlay
 | 
	
		
			
				|  |  |                  case PlaybackRequestType.Seek:
 | 
	
		
			
				|  |  |                      HandleSeekRequest(session, request, cancellationToken);
 | 
	
		
			
				|  |  |                      break;
 | 
	
		
			
				|  |  | -                case PlaybackRequestType.Buffering:
 | 
	
		
			
				|  |  | +                case PlaybackRequestType.Buffer:
 | 
	
		
			
				|  |  |                      HandleBufferingRequest(session, request, cancellationToken);
 | 
	
		
			
				|  |  |                      break;
 | 
	
		
			
				|  |  | -                case PlaybackRequestType.BufferingDone:
 | 
	
		
			
				|  |  | +                case PlaybackRequestType.Ready:
 | 
	
		
			
				|  |  |                      HandleBufferingDoneRequest(session, request, cancellationToken);
 | 
	
		
			
				|  |  |                      break;
 | 
	
		
			
				|  |  | -                case PlaybackRequestType.UpdatePing:
 | 
	
		
			
				|  |  | +                case PlaybackRequestType.Ping:
 | 
	
		
			
				|  |  |                      HandlePingUpdateRequest(session, request);
 | 
	
		
			
				|  |  |                      break;
 | 
	
		
			
				|  |  |              }
 | 
	
	
		
			
				|  | @@ -301,7 +298,7 @@ namespace Emby.Server.Implementations.SyncPlay
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  // Pick a suitable time that accounts for latency
 | 
	
		
			
				|  |  |                  var delay = _group.GetHighestPing() * 2;
 | 
	
		
			
				|  |  | -                delay = delay < _group.DefaulPing ? _group.DefaulPing : delay;
 | 
	
		
			
				|  |  | +                delay = delay < _group.DefaultPing ? _group.DefaultPing : delay;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                  // Unpause group and set starting point in future
 | 
	
		
			
				|  |  |                  // Clients will start playback at LastActivity (datetime) from PositionTicks (playback position)
 | 
	
	
		
			
				|  | @@ -337,8 +334,9 @@ namespace Emby.Server.Implementations.SyncPlay
 | 
	
		
			
				|  |  |                  var currentTime = DateTime.UtcNow;
 | 
	
		
			
				|  |  |                  var elapsedTime = currentTime - _group.LastActivity;
 | 
	
		
			
				|  |  |                  _group.LastActivity = currentTime;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |                  // Seek only if playback actually started
 | 
	
		
			
				|  |  | -                // (a pause request may be issued during the delay added to account for latency)
 | 
	
		
			
				|  |  | +                // Pause request may be issued during the delay added to account for latency
 | 
	
		
			
				|  |  |                  _group.PositionTicks += elapsedTime.Ticks > 0 ? elapsedTime.Ticks : 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                  var command = NewSyncPlayCommand(SendCommandType.Pause);
 | 
	
	
		
			
				|  | @@ -451,7 +449,7 @@ namespace Emby.Server.Implementations.SyncPlay
 | 
	
		
			
				|  |  |                      {
 | 
	
		
			
				|  |  |                          // Client, that was buffering, resumed playback but did not update others in time
 | 
	
		
			
				|  |  |                          delay = _group.GetHighestPing() * 2;
 | 
	
		
			
				|  |  | -                        delay = delay < _group.DefaulPing ? _group.DefaulPing : delay;
 | 
	
		
			
				|  |  | +                        delay = delay < _group.DefaultPing ? _group.DefaultPing : delay;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                          _group.LastActivity = currentTime.AddMilliseconds(
 | 
	
		
			
				|  |  |                              delay);
 | 
	
	
		
			
				|  | @@ -495,7 +493,7 @@ namespace Emby.Server.Implementations.SyncPlay
 | 
	
		
			
				|  |  |          private void HandlePingUpdateRequest(SessionInfo session, PlaybackRequest request)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              // Collected pings are used to account for network latency when unpausing playback
 | 
	
		
			
				|  |  | -            _group.UpdatePing(session, request.Ping ?? _group.DefaulPing);
 | 
	
		
			
				|  |  | +            _group.UpdatePing(session, request.Ping ?? _group.DefaultPing);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <inheritdoc />
 |