Merge pull request #5648 from OancaAndrei/syncplay-sessions-fix

Fix session references in SyncPlay
This commit is contained in:
Claus Vium 2021-09-10 17:44:44 +02:00 committed by GitHub
commit 00f7f68e53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 58 additions and 31 deletions

View File

@ -1199,16 +1199,18 @@ namespace Emby.Server.Implementations.Session
} }
/// <inheritdoc /> /// <inheritdoc />
public async Task SendSyncPlayCommand(SessionInfo session, SendCommand command, CancellationToken cancellationToken) public async Task SendSyncPlayCommand(string sessionId, SendCommand command, CancellationToken cancellationToken)
{ {
CheckDisposed(); CheckDisposed();
var session = GetSession(sessionId);
await SendMessageToSession(session, SessionMessageType.SyncPlayCommand, command, cancellationToken).ConfigureAwait(false); await SendMessageToSession(session, SessionMessageType.SyncPlayCommand, command, cancellationToken).ConfigureAwait(false);
} }
/// <inheritdoc /> /// <inheritdoc />
public async Task SendSyncPlayGroupUpdate<T>(SessionInfo session, GroupUpdate<T> command, CancellationToken cancellationToken) public async Task SendSyncPlayGroupUpdate<T>(string sessionId, GroupUpdate<T> command, CancellationToken cancellationToken)
{ {
CheckDisposed(); CheckDisposed();
var session = GetSession(sessionId);
await SendMessageToSession(session, SessionMessageType.SyncPlayGroupUpdate, command, cancellationToken).ConfigureAwait(false); await SendMessageToSession(session, SessionMessageType.SyncPlayGroupUpdate, command, cancellationToken).ConfigureAwait(false);
} }

View File

@ -164,26 +164,26 @@ namespace Emby.Server.Implementations.SyncPlay
/// <summary> /// <summary>
/// Filters sessions of this group. /// Filters sessions of this group.
/// </summary> /// </summary>
/// <param name="from">The current session.</param> /// <param name="fromId">The current session identifier.</param>
/// <param name="type">The filtering type.</param> /// <param name="type">The filtering type.</param>
/// <returns>The list of sessions matching the filter.</returns> /// <returns>The list of sessions matching the filter.</returns>
private IEnumerable<SessionInfo> FilterSessions(SessionInfo from, SyncPlayBroadcastType type) private IEnumerable<string> FilterSessions(string fromId, SyncPlayBroadcastType type)
{ {
return type switch return type switch
{ {
SyncPlayBroadcastType.CurrentSession => new SessionInfo[] { from }, SyncPlayBroadcastType.CurrentSession => new string[] { fromId },
SyncPlayBroadcastType.AllGroup => _participants SyncPlayBroadcastType.AllGroup => _participants
.Values .Values
.Select(session => session.Session), .Select(member => member.SessionId),
SyncPlayBroadcastType.AllExceptCurrentSession => _participants SyncPlayBroadcastType.AllExceptCurrentSession => _participants
.Values .Values
.Select(session => session.Session) .Select(member => member.SessionId)
.Where(session => !session.Id.Equals(from.Id, StringComparison.OrdinalIgnoreCase)), .Where(sessionId => !sessionId.Equals(fromId, StringComparison.OrdinalIgnoreCase)),
SyncPlayBroadcastType.AllReady => _participants SyncPlayBroadcastType.AllReady => _participants
.Values .Values
.Where(session => !session.IsBuffering) .Where(member => !member.IsBuffering)
.Select(session => session.Session), .Select(member => member.SessionId),
_ => Enumerable.Empty<SessionInfo>() _ => Enumerable.Empty<string>()
}; };
} }
@ -225,7 +225,7 @@ namespace Emby.Server.Implementations.SyncPlay
// Get list of users. // Get list of users.
var users = _participants var users = _participants
.Values .Values
.Select(participant => _userManager.GetUserById(participant.Session.UserId)); .Select(participant => _userManager.GetUserById(participant.UserId));
// Find problematic users. // Find problematic users.
var usersWithNoAccess = users.Where(user => !HasAccessToQueue(user, queue)); var usersWithNoAccess = users.Where(user => !HasAccessToQueue(user, queue));
@ -353,7 +353,7 @@ namespace Emby.Server.Implementations.SyncPlay
/// <returns>The group info for the clients.</returns> /// <returns>The group info for the clients.</returns>
public GroupInfoDto GetInfo() public GroupInfoDto GetInfo()
{ {
var participants = _participants.Values.Select(session => session.Session.UserName).Distinct().ToList(); var participants = _participants.Values.Select(session => session.UserName).Distinct().ToList();
return new GroupInfoDto(GroupId, GroupName, _state.Type, participants, DateTime.UtcNow); return new GroupInfoDto(GroupId, GroupName, _state.Type, participants, DateTime.UtcNow);
} }
@ -389,9 +389,9 @@ namespace Emby.Server.Implementations.SyncPlay
{ {
IEnumerable<Task> GetTasks() IEnumerable<Task> GetTasks()
{ {
foreach (var session in FilterSessions(from, type)) foreach (var sessionId in FilterSessions(from.Id, type))
{ {
yield return _sessionManager.SendSyncPlayGroupUpdate(session, message, cancellationToken); yield return _sessionManager.SendSyncPlayGroupUpdate(sessionId, message, cancellationToken);
} }
} }
@ -403,9 +403,9 @@ namespace Emby.Server.Implementations.SyncPlay
{ {
IEnumerable<Task> GetTasks() IEnumerable<Task> GetTasks()
{ {
foreach (var session in FilterSessions(from, type)) foreach (var sessionId in FilterSessions(from.Id, type))
{ {
yield return _sessionManager.SendSyncPlayCommand(session, message, cancellationToken); yield return _sessionManager.SendSyncPlayCommand(sessionId, message, cancellationToken);
} }
} }
@ -659,8 +659,9 @@ namespace Emby.Server.Implementations.SyncPlay
public PlayQueueUpdate GetPlayQueueUpdate(PlayQueueUpdateReason reason) public PlayQueueUpdate GetPlayQueueUpdate(PlayQueueUpdateReason reason)
{ {
var startPositionTicks = PositionTicks; var startPositionTicks = PositionTicks;
var isPlaying = _state.Type.Equals(GroupStateType.Playing);
if (_state.Type.Equals(GroupStateType.Playing)) if (isPlaying)
{ {
var currentTime = DateTime.UtcNow; var currentTime = DateTime.UtcNow;
var elapsedTime = currentTime - LastActivity; var elapsedTime = currentTime - LastActivity;
@ -679,6 +680,7 @@ namespace Emby.Server.Implementations.SyncPlay
PlayQueue.GetPlaylist(), PlayQueue.GetPlaylist(),
PlayQueue.PlayingItemIndex, PlayQueue.PlayingItemIndex,
startPositionTicks, startPositionTicks,
isPlaying,
PlayQueue.ShuffleMode, PlayQueue.ShuffleMode,
PlayQueue.RepeatMode); PlayQueue.RepeatMode);
} }

View File

@ -160,7 +160,7 @@ namespace Emby.Server.Implementations.SyncPlay
_logger.LogWarning("Session {SessionId} tried to join group {GroupId} that does not exist.", session.Id, request.GroupId); _logger.LogWarning("Session {SessionId} tried to join group {GroupId} that does not exist.", session.Id, request.GroupId);
var error = new GroupUpdate<string>(Guid.Empty, GroupUpdateType.GroupDoesNotExist, string.Empty); var error = new GroupUpdate<string>(Guid.Empty, GroupUpdateType.GroupDoesNotExist, string.Empty);
_sessionManager.SendSyncPlayGroupUpdate(session, error, CancellationToken.None); _sessionManager.SendSyncPlayGroupUpdate(session.Id, error, CancellationToken.None);
return; return;
} }
@ -172,7 +172,7 @@ namespace Emby.Server.Implementations.SyncPlay
_logger.LogWarning("Session {SessionId} tried to join group {GroupId} but does not have access to some content of the playing queue.", session.Id, group.GroupId.ToString()); _logger.LogWarning("Session {SessionId} tried to join group {GroupId} but does not have access to some content of the playing queue.", session.Id, group.GroupId.ToString());
var error = new GroupUpdate<string>(group.GroupId, GroupUpdateType.LibraryAccessDenied, string.Empty); var error = new GroupUpdate<string>(group.GroupId, GroupUpdateType.LibraryAccessDenied, string.Empty);
_sessionManager.SendSyncPlayGroupUpdate(session, error, CancellationToken.None); _sessionManager.SendSyncPlayGroupUpdate(session.Id, error, CancellationToken.None);
return; return;
} }
@ -249,7 +249,7 @@ namespace Emby.Server.Implementations.SyncPlay
_logger.LogWarning("Session {SessionId} does not belong to any group.", session.Id); _logger.LogWarning("Session {SessionId} does not belong to any group.", session.Id);
var error = new GroupUpdate<string>(Guid.Empty, GroupUpdateType.NotInGroup, string.Empty); var error = new GroupUpdate<string>(Guid.Empty, GroupUpdateType.NotInGroup, string.Empty);
_sessionManager.SendSyncPlayGroupUpdate(session, error, CancellationToken.None); _sessionManager.SendSyncPlayGroupUpdate(session.Id, error, CancellationToken.None);
return; return;
} }
} }
@ -329,7 +329,7 @@ namespace Emby.Server.Implementations.SyncPlay
_logger.LogWarning("Session {SessionId} does not belong to any group.", session.Id); _logger.LogWarning("Session {SessionId} does not belong to any group.", session.Id);
var error = new GroupUpdate<string>(Guid.Empty, GroupUpdateType.NotInGroup, string.Empty); var error = new GroupUpdate<string>(Guid.Empty, GroupUpdateType.NotInGroup, string.Empty);
_sessionManager.SendSyncPlayGroupUpdate(session, error, CancellationToken.None); _sessionManager.SendSyncPlayGroupUpdate(session.Id, error, CancellationToken.None);
} }
} }

View File

@ -157,21 +157,21 @@ namespace MediaBrowser.Controller.Session
/// <summary> /// <summary>
/// Sends a SyncPlayCommand to a session. /// Sends a SyncPlayCommand to a session.
/// </summary> /// </summary>
/// <param name="session">The session.</param> /// <param name="sessionId">The identifier of the session.</param>
/// <param name="command">The command.</param> /// <param name="command">The command.</param>
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns> /// <returns>Task.</returns>
Task SendSyncPlayCommand(SessionInfo session, SendCommand command, CancellationToken cancellationToken); Task SendSyncPlayCommand(string sessionId, SendCommand command, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Sends a SyncPlayGroupUpdate to a session. /// Sends a SyncPlayGroupUpdate to a session.
/// </summary> /// </summary>
/// <param name="session">The session.</param> /// <param name="sessionId">The identifier of the session.</param>
/// <param name="command">The group update.</param> /// <param name="command">The group update.</param>
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <typeparam name="T">Type of group.</typeparam> /// <typeparam name="T">Type of group.</typeparam>
/// <returns>Task.</returns> /// <returns>Task.</returns>
Task SendSyncPlayGroupUpdate<T>(SessionInfo session, GroupUpdate<T> command, CancellationToken cancellationToken); Task SendSyncPlayGroupUpdate<T>(string sessionId, GroupUpdate<T> command, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Sends the browse command. /// Sends the browse command.

View File

@ -1,5 +1,6 @@
#nullable disable #nullable disable
using System;
using MediaBrowser.Controller.Session; using MediaBrowser.Controller.Session;
namespace MediaBrowser.Controller.SyncPlay namespace MediaBrowser.Controller.SyncPlay
@ -15,14 +16,28 @@ namespace MediaBrowser.Controller.SyncPlay
/// <param name="session">The session.</param> /// <param name="session">The session.</param>
public GroupMember(SessionInfo session) public GroupMember(SessionInfo session)
{ {
Session = session; SessionId = session.Id;
UserId = session.UserId;
UserName = session.UserName;
} }
/// <summary> /// <summary>
/// Gets the session. /// Gets the identifier of the session.
/// </summary> /// </summary>
/// <value>The session.</value> /// <value>The session identifier.</value>
public SessionInfo Session { get; } public string SessionId { get; }
/// <summary>
/// Gets the identifier of the user.
/// </summary>
/// <value>The user identifier.</value>
public Guid UserId { get; }
/// <summary>
/// Gets the username.
/// </summary>
/// <value>The username.</value>
public string UserName { get; }
/// <summary> /// <summary>
/// Gets or sets the ping, in milliseconds. /// Gets or sets the ping, in milliseconds.

View File

@ -16,15 +16,17 @@ namespace MediaBrowser.Model.SyncPlay
/// <param name="playlist">The playlist.</param> /// <param name="playlist">The playlist.</param>
/// <param name="playingItemIndex">The playing item index in the playlist.</param> /// <param name="playingItemIndex">The playing item index in the playlist.</param>
/// <param name="startPositionTicks">The start position ticks.</param> /// <param name="startPositionTicks">The start position ticks.</param>
/// <param name="isPlaying">The playing item status.</param>
/// <param name="shuffleMode">The shuffle mode.</param> /// <param name="shuffleMode">The shuffle mode.</param>
/// <param name="repeatMode">The repeat mode.</param> /// <param name="repeatMode">The repeat mode.</param>
public PlayQueueUpdate(PlayQueueUpdateReason reason, DateTime lastUpdate, IReadOnlyList<QueueItem> playlist, int playingItemIndex, long startPositionTicks, GroupShuffleMode shuffleMode, GroupRepeatMode repeatMode) public PlayQueueUpdate(PlayQueueUpdateReason reason, DateTime lastUpdate, IReadOnlyList<QueueItem> playlist, int playingItemIndex, long startPositionTicks, bool isPlaying, GroupShuffleMode shuffleMode, GroupRepeatMode repeatMode)
{ {
Reason = reason; Reason = reason;
LastUpdate = lastUpdate; LastUpdate = lastUpdate;
Playlist = playlist; Playlist = playlist;
PlayingItemIndex = playingItemIndex; PlayingItemIndex = playingItemIndex;
StartPositionTicks = startPositionTicks; StartPositionTicks = startPositionTicks;
IsPlaying = isPlaying;
ShuffleMode = shuffleMode; ShuffleMode = shuffleMode;
RepeatMode = repeatMode; RepeatMode = repeatMode;
} }
@ -59,6 +61,12 @@ namespace MediaBrowser.Model.SyncPlay
/// <value>The start position ticks.</value> /// <value>The start position ticks.</value>
public long StartPositionTicks { get; } public long StartPositionTicks { get; }
/// <summary>
/// Gets a value indicating whether the current item is playing.
/// </summary>
/// <value>The playing item status.</value>
public bool IsPlaying { get; }
/// <summary> /// <summary>
/// Gets the shuffle mode. /// Gets the shuffle mode.
/// </summary> /// </summary>