mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-11-16 02:18:54 -07:00
Review logging and minor changes in SyncPlay
This commit is contained in:
parent
c7e53bce2f
commit
a3ca36cb54
@ -28,7 +28,12 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The logger.
|
/// The logger.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger<GroupController> _logger;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The logger factory.
|
||||||
|
/// </summary>
|
||||||
|
private readonly ILoggerFactory _loggerFactory;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The user manager.
|
/// The user manager.
|
||||||
@ -45,6 +50,12 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The participants, or members of the group.
|
||||||
|
/// </summary>
|
||||||
|
private readonly Dictionary<string, GroupMember> _participants =
|
||||||
|
new Dictionary<string, GroupMember>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Internal group state.
|
/// Internal group state.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -54,37 +65,41 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="GroupController" /> class.
|
/// Initializes a new instance of the <see cref="GroupController" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="logger">The logger.</param>
|
/// <param name="loggerFactory">The logger factory.</param>
|
||||||
/// <param name="userManager">The user manager.</param>
|
/// <param name="userManager">The user manager.</param>
|
||||||
/// <param name="sessionManager">The session manager.</param>
|
/// <param name="sessionManager">The session manager.</param>
|
||||||
/// <param name="libraryManager">The library manager.</param>
|
/// <param name="libraryManager">The library manager.</param>
|
||||||
public GroupController(
|
public GroupController(
|
||||||
ILogger logger,
|
ILoggerFactory loggerFactory,
|
||||||
IUserManager userManager,
|
IUserManager userManager,
|
||||||
ISessionManager sessionManager,
|
ISessionManager sessionManager,
|
||||||
ILibraryManager libraryManager)
|
ILibraryManager libraryManager)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_loggerFactory = loggerFactory;
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_sessionManager = sessionManager;
|
_sessionManager = sessionManager;
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
|
_logger = loggerFactory.CreateLogger<GroupController>();
|
||||||
|
|
||||||
_state = new IdleGroupState(_logger);
|
_state = new IdleGroupState(loggerFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the default ping value used for sessions.
|
/// Gets the default ping value used for sessions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <value>The default ping.</value>
|
||||||
public long DefaultPing { get; } = 500;
|
public long DefaultPing { get; } = 500;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the maximum time offset error accepted for dates reported by clients, in milliseconds.
|
/// Gets the maximum time offset error accepted for dates reported by clients, in milliseconds.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <value>The maximum time offset error.</value>
|
||||||
public long TimeSyncOffset { get; } = 2000;
|
public long TimeSyncOffset { get; } = 2000;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the maximum offset error accepted for position reported by clients, in milliseconds.
|
/// Gets the maximum offset error accepted for position reported by clients, in milliseconds.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <value>The maximum offset error.</value>
|
||||||
public long MaxPlaybackOffset { get; } = 500;
|
public long MaxPlaybackOffset { get; } = 500;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -123,24 +138,16 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
/// <value>The last activity.</value>
|
/// <value>The last activity.</value>
|
||||||
public DateTime LastActivity { get; set; }
|
public DateTime LastActivity { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the participants.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The participants, or members of the group.</value>
|
|
||||||
public Dictionary<string, GroupMember> Participants { get; } =
|
|
||||||
new Dictionary<string, GroupMember>(StringComparer.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds the session to the group.
|
/// Adds the session to the group.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="session">The session.</param>
|
/// <param name="session">The session.</param>
|
||||||
private void AddSession(SessionInfo session)
|
private void AddSession(SessionInfo session)
|
||||||
{
|
{
|
||||||
Participants.TryAdd(
|
_participants.TryAdd(
|
||||||
session.Id,
|
session.Id,
|
||||||
new GroupMember
|
new GroupMember(session)
|
||||||
{
|
{
|
||||||
Session = session,
|
|
||||||
Ping = DefaultPing,
|
Ping = DefaultPing,
|
||||||
IsBuffering = false
|
IsBuffering = false
|
||||||
});
|
});
|
||||||
@ -152,7 +159,7 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
/// <param name="session">The session.</param>
|
/// <param name="session">The session.</param>
|
||||||
private void RemoveSession(SessionInfo session)
|
private void RemoveSession(SessionInfo session)
|
||||||
{
|
{
|
||||||
Participants.Remove(session.Id);
|
_participants.Remove(session.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -166,14 +173,14 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
return type switch
|
return type switch
|
||||||
{
|
{
|
||||||
SyncPlayBroadcastType.CurrentSession => new SessionInfo[] { from },
|
SyncPlayBroadcastType.CurrentSession => new SessionInfo[] { from },
|
||||||
SyncPlayBroadcastType.AllGroup => Participants
|
SyncPlayBroadcastType.AllGroup => _participants
|
||||||
.Values
|
.Values
|
||||||
.Select(session => session.Session),
|
.Select(session => session.Session),
|
||||||
SyncPlayBroadcastType.AllExceptCurrentSession => Participants
|
SyncPlayBroadcastType.AllExceptCurrentSession => _participants
|
||||||
.Values
|
.Values
|
||||||
.Select(session => session.Session)
|
.Select(session => session.Session)
|
||||||
.Where(session => !session.Id.Equals(from.Id, StringComparison.OrdinalIgnoreCase)),
|
.Where(session => !session.Id.Equals(from.Id, StringComparison.OrdinalIgnoreCase)),
|
||||||
SyncPlayBroadcastType.AllReady => Participants
|
SyncPlayBroadcastType.AllReady => _participants
|
||||||
.Values
|
.Values
|
||||||
.Where(session => !session.IsBuffering)
|
.Where(session => !session.IsBuffering)
|
||||||
.Select(session => session.Session),
|
.Select(session => session.Session),
|
||||||
@ -204,7 +211,7 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
private bool HasAccessToQueue(User user, IReadOnlyList<Guid> queue)
|
private bool HasAccessToQueue(User user, IReadOnlyList<Guid> queue)
|
||||||
{
|
{
|
||||||
// Check if queue is empty.
|
// Check if queue is empty.
|
||||||
if (!queue?.Any() ?? true)
|
if (queue == null || queue.Count == 0)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -229,13 +236,13 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
private bool AllUsersHaveAccessToQueue(IReadOnlyList<Guid> queue)
|
private bool AllUsersHaveAccessToQueue(IReadOnlyList<Guid> queue)
|
||||||
{
|
{
|
||||||
// Check if queue is empty.
|
// Check if queue is empty.
|
||||||
if (!queue?.Any() ?? true)
|
if (queue == null || queue.Count == 0)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.Session.UserId));
|
||||||
|
|
||||||
@ -247,7 +254,7 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool IsGroupEmpty() => Participants.Count == 0;
|
public bool IsGroupEmpty() => _participants.Count == 0;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void CreateGroup(SessionInfo session, NewGroupRequest request, CancellationToken cancellationToken)
|
public void CreateGroup(SessionInfo session, NewGroupRequest request, CancellationToken cancellationToken)
|
||||||
@ -268,8 +275,8 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
RunTimeTicks = session.FullNowPlayingItem.RunTimeTicks ?? 0;
|
RunTimeTicks = session.FullNowPlayingItem.RunTimeTicks ?? 0;
|
||||||
PositionTicks = session.PlayState.PositionTicks ?? 0;
|
PositionTicks = session.PlayState.PositionTicks ?? 0;
|
||||||
|
|
||||||
// Mantain playstate.
|
// Maintain playstate.
|
||||||
var waitingState = new WaitingGroupState(_logger)
|
var waitingState = new WaitingGroupState(_loggerFactory)
|
||||||
{
|
{
|
||||||
ResumePlaying = !session.PlayState.IsPaused
|
ResumePlaying = !session.PlayState.IsPaused
|
||||||
};
|
};
|
||||||
@ -281,7 +288,7 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
|
|
||||||
_state.SessionJoined(this, _state.Type, session, cancellationToken);
|
_state.SessionJoined(this, _state.Type, session, cancellationToken);
|
||||||
|
|
||||||
_logger.LogInformation("InitGroup: {SessionId} created group {GroupId}.", session.Id, GroupId.ToString());
|
_logger.LogInformation("Session {SessionId} created group {GroupId}.", session.Id, GroupId.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -297,7 +304,7 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
|
|
||||||
_state.SessionJoined(this, _state.Type, session, cancellationToken);
|
_state.SessionJoined(this, _state.Type, session, cancellationToken);
|
||||||
|
|
||||||
_logger.LogInformation("SessionJoin: {SessionId} joined group {GroupId}.", session.Id, GroupId.ToString());
|
_logger.LogInformation("Session {SessionId} joined group {GroupId}.", session.Id, GroupId.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -311,7 +318,7 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
|
|
||||||
_state.SessionJoined(this, _state.Type, session, cancellationToken);
|
_state.SessionJoined(this, _state.Type, session, cancellationToken);
|
||||||
|
|
||||||
_logger.LogInformation("SessionRestore: {SessionId} re-joined group {GroupId}.", session.Id, GroupId.ToString());
|
_logger.LogInformation("Session {SessionId} re-joined group {GroupId}.", session.Id, GroupId.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -327,7 +334,7 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
var updateOthers = NewSyncPlayGroupUpdate(GroupUpdateType.UserLeft, session.UserName);
|
var updateOthers = NewSyncPlayGroupUpdate(GroupUpdateType.UserLeft, session.UserName);
|
||||||
SendGroupUpdate(session, SyncPlayBroadcastType.AllExceptCurrentSession, updateOthers, cancellationToken);
|
SendGroupUpdate(session, SyncPlayBroadcastType.AllExceptCurrentSession, updateOthers, cancellationToken);
|
||||||
|
|
||||||
_logger.LogInformation("SessionLeave: {SessionId} left group {GroupId}.", session.Id, GroupId.ToString());
|
_logger.LogInformation("Session {SessionId} left group {GroupId}.", session.Id, GroupId.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -336,14 +343,14 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
// The server's job is to maintain a consistent state for clients to reference
|
// 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
|
// 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.
|
// happens client side. Clients are aware of the server's time and use it to sync.
|
||||||
_logger.LogInformation("HandleRequest: {SessionId} requested {RequestType}, group {GroupId} is {StateType}.", session.Id, request.Type, GroupId.ToString(), _state.Type);
|
_logger.LogInformation("Session {SessionId} requested {RequestType} in group {GroupId} that is {StateType}.", session.Id, request.Type, GroupId.ToString(), _state.Type);
|
||||||
request.Apply(this, _state, session, cancellationToken);
|
request.Apply(this, _state, session, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public GroupInfoDto GetInfo()
|
public GroupInfoDto GetInfo()
|
||||||
{
|
{
|
||||||
var participants = Participants.Values.Select(session => session.Session.UserName).Distinct().ToList();
|
var participants = _participants.Values.Select(session => 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,7 +364,7 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void SetIgnoreGroupWait(SessionInfo session, bool ignoreGroupWait)
|
public void SetIgnoreGroupWait(SessionInfo session, bool ignoreGroupWait)
|
||||||
{
|
{
|
||||||
if (Participants.TryGetValue(session.Id, out GroupMember value))
|
if (_participants.TryGetValue(session.Id, out GroupMember value))
|
||||||
{
|
{
|
||||||
value.IgnoreGroupWait = ignoreGroupWait;
|
value.IgnoreGroupWait = ignoreGroupWait;
|
||||||
}
|
}
|
||||||
@ -366,7 +373,7 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void SetState(IGroupState state)
|
public void SetState(IGroupState state)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("SetState: {GroupId} switching from {FromStateType} to {ToStateType}.", GroupId.ToString(), _state.Type, state.Type);
|
_logger.LogInformation("Group {GroupId} switching from {FromStateType} to {ToStateType}.", GroupId.ToString(), _state.Type, state.Type);
|
||||||
this._state = state;
|
this._state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,7 +433,7 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void UpdatePing(SessionInfo session, long ping)
|
public void UpdatePing(SessionInfo session, long ping)
|
||||||
{
|
{
|
||||||
if (Participants.TryGetValue(session.Id, out GroupMember value))
|
if (_participants.TryGetValue(session.Id, out GroupMember value))
|
||||||
{
|
{
|
||||||
value.Ping = ping;
|
value.Ping = ping;
|
||||||
}
|
}
|
||||||
@ -436,7 +443,7 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
public long GetHighestPing()
|
public long GetHighestPing()
|
||||||
{
|
{
|
||||||
long max = long.MinValue;
|
long max = long.MinValue;
|
||||||
foreach (var session in Participants.Values)
|
foreach (var session in _participants.Values)
|
||||||
{
|
{
|
||||||
max = Math.Max(max, session.Ping);
|
max = Math.Max(max, session.Ping);
|
||||||
}
|
}
|
||||||
@ -447,7 +454,7 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void SetBuffering(SessionInfo session, bool isBuffering)
|
public void SetBuffering(SessionInfo session, bool isBuffering)
|
||||||
{
|
{
|
||||||
if (Participants.TryGetValue(session.Id, out GroupMember value))
|
if (_participants.TryGetValue(session.Id, out GroupMember value))
|
||||||
{
|
{
|
||||||
value.IsBuffering = isBuffering;
|
value.IsBuffering = isBuffering;
|
||||||
}
|
}
|
||||||
@ -456,7 +463,7 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void SetAllBuffering(bool isBuffering)
|
public void SetAllBuffering(bool isBuffering)
|
||||||
{
|
{
|
||||||
foreach (var session in Participants.Values)
|
foreach (var session in _participants.Values)
|
||||||
{
|
{
|
||||||
session.IsBuffering = isBuffering;
|
session.IsBuffering = isBuffering;
|
||||||
}
|
}
|
||||||
@ -465,7 +472,7 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool IsBuffering()
|
public bool IsBuffering()
|
||||||
{
|
{
|
||||||
foreach (var session in Participants.Values)
|
foreach (var session in _participants.Values)
|
||||||
{
|
{
|
||||||
if (session.IsBuffering && !session.IgnoreGroupWait)
|
if (session.IsBuffering && !session.IgnoreGroupWait)
|
||||||
{
|
{
|
||||||
|
@ -21,6 +21,11 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILogger<SyncPlayManager> _logger;
|
private readonly ILogger<SyncPlayManager> _logger;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The logger factory.
|
||||||
|
/// </summary>
|
||||||
|
private readonly ILoggerFactory _loggerFactory;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The user manager.
|
/// The user manager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -58,20 +63,21 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="SyncPlayManager" /> class.
|
/// Initializes a new instance of the <see cref="SyncPlayManager" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="logger">The logger.</param>
|
/// <param name="loggerFactory">The logger factory.</param>
|
||||||
/// <param name="userManager">The user manager.</param>
|
/// <param name="userManager">The user manager.</param>
|
||||||
/// <param name="sessionManager">The session manager.</param>
|
/// <param name="sessionManager">The session manager.</param>
|
||||||
/// <param name="libraryManager">The library manager.</param>
|
/// <param name="libraryManager">The library manager.</param>
|
||||||
public SyncPlayManager(
|
public SyncPlayManager(
|
||||||
ILogger<SyncPlayManager> logger,
|
ILoggerFactory loggerFactory,
|
||||||
IUserManager userManager,
|
IUserManager userManager,
|
||||||
ISessionManager sessionManager,
|
ISessionManager sessionManager,
|
||||||
ILibraryManager libraryManager)
|
ILibraryManager libraryManager)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_loggerFactory = loggerFactory;
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_sessionManager = sessionManager;
|
_sessionManager = sessionManager;
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
|
_logger = loggerFactory.CreateLogger<SyncPlayManager>();
|
||||||
_sessionManager.SessionStarted += OnSessionManagerSessionStarted;
|
_sessionManager.SessionStarted += OnSessionManagerSessionStarted;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +104,7 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
LeaveGroup(session, cancellationToken);
|
LeaveGroup(session, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
var group = new GroupController(_logger, _userManager, _sessionManager, _libraryManager);
|
var group = new GroupController(_loggerFactory, _userManager, _sessionManager, _libraryManager);
|
||||||
_groups[group.GroupId] = group;
|
_groups[group.GroupId] = group;
|
||||||
|
|
||||||
AddSessionToGroup(session, group);
|
AddSessionToGroup(session, group);
|
||||||
@ -123,7 +129,7 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
|
|
||||||
if (group == null)
|
if (group == null)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("JoinGroup: {SessionId} tried to join group {GroupId} that does not exist.", session.Id, groupId);
|
_logger.LogWarning("Session {SessionId} tried to join group {GroupId} that does not exist.", session.Id, 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, error, CancellationToken.None);
|
||||||
@ -132,7 +138,7 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
|
|
||||||
if (!group.HasAccessToPlayQueue(user))
|
if (!group.HasAccessToPlayQueue(user))
|
||||||
{
|
{
|
||||||
_logger.LogWarning("JoinGroup: {SessionId} does not have access to some content from the playing queue of group {GroupId}.", 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, error, CancellationToken.None);
|
||||||
@ -171,7 +177,7 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
|
|
||||||
if (group == null)
|
if (group == null)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("LeaveGroup: {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, error, CancellationToken.None);
|
||||||
@ -183,7 +189,7 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
|
|
||||||
if (group.IsGroupEmpty())
|
if (group.IsGroupEmpty())
|
||||||
{
|
{
|
||||||
_logger.LogInformation("LeaveGroup: removing empty group {GroupId}.", group.GroupId);
|
_logger.LogInformation("Group {GroupId} is empty, removing it.", group.GroupId);
|
||||||
_groups.Remove(group.GroupId, out _);
|
_groups.Remove(group.GroupId, out _);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -225,7 +231,7 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
|
|
||||||
if (group == null)
|
if (group == null)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("HandleRequest: {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, error, CancellationToken.None);
|
||||||
@ -370,7 +376,7 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
|
|
||||||
if (user.SyncPlayAccess == SyncPlayAccess.None)
|
if (user.SyncPlayAccess == SyncPlayAccess.None)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("IsRequestValid: {SessionId} does not have access to SyncPlay. Requested {RequestType}.", session.Id, requestType);
|
_logger.LogWarning("Session {SessionId} requested {RequestType} but does not have access to SyncPlay.", session.Id, requestType);
|
||||||
|
|
||||||
// TODO: rename to a more generic error. Next PR will fix this.
|
// TODO: rename to a more generic error. Next PR will fix this.
|
||||||
var error = new GroupUpdate<string>(Guid.Empty, GroupUpdateType.JoinGroupDenied, string.Empty);
|
var error = new GroupUpdate<string>(Guid.Empty, GroupUpdateType.JoinGroupDenied, string.Empty);
|
||||||
@ -380,7 +386,7 @@ namespace Emby.Server.Implementations.SyncPlay
|
|||||||
|
|
||||||
if (requestType.Equals(GroupRequestType.NewGroup) && user.SyncPlayAccess != SyncPlayAccess.CreateAndJoinGroups)
|
if (requestType.Equals(GroupRequestType.NewGroup) && user.SyncPlayAccess != SyncPlayAccess.CreateAndJoinGroups)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("IsRequestValid: {SessionId} does not have permission to create groups.", session.Id);
|
_logger.LogWarning("Session {SessionId} does not have permission to create groups.", session.Id);
|
||||||
|
|
||||||
var error = new GroupUpdate<string>(Guid.Empty, GroupUpdateType.CreateGroupDenied, string.Empty);
|
var error = new GroupUpdate<string>(Guid.Empty, GroupUpdateType.CreateGroupDenied, string.Empty);
|
||||||
_sessionManager.SendSyncPlayGroupUpdate(session, error, CancellationToken.None);
|
_sessionManager.SendSyncPlayGroupUpdate(session, error, CancellationToken.None);
|
||||||
|
@ -8,10 +8,19 @@ namespace MediaBrowser.Controller.SyncPlay
|
|||||||
public class GroupMember
|
public class GroupMember
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the session.
|
/// Initializes a new instance of the <see cref="GroupMember"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="session">The session.</param>
|
||||||
|
public GroupMember(SessionInfo session)
|
||||||
|
{
|
||||||
|
Session = session;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the session.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The session.</value>
|
/// <value>The session.</value>
|
||||||
public SessionInfo Session { get; set; }
|
public SessionInfo Session { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the ping, in milliseconds.
|
/// Gets or sets the ping, in milliseconds.
|
||||||
|
@ -14,22 +14,28 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
public abstract class AbstractGroupState : IGroupState
|
public abstract class AbstractGroupState : IGroupState
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The logger.
|
||||||
|
/// </summary>
|
||||||
|
private readonly ILogger<AbstractGroupState> _logger;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="AbstractGroupState"/> class.
|
/// Initializes a new instance of the <see cref="AbstractGroupState"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="logger">Instance of the <see cref="ILogger"/> interface.</param>
|
/// <param name="loggerFactory">Instance of the <see cref="ILoggerFactory"/> interface.</param>
|
||||||
protected AbstractGroupState(ILogger logger)
|
protected AbstractGroupState(ILoggerFactory loggerFactory)
|
||||||
{
|
{
|
||||||
Logger = logger;
|
LoggerFactory = loggerFactory;
|
||||||
|
_logger = loggerFactory.CreateLogger<AbstractGroupState>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public abstract GroupStateType Type { get; }
|
public abstract GroupStateType Type { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the logger.
|
/// Gets the logger factory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected ILogger Logger { get; }
|
protected ILoggerFactory LoggerFactory { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public abstract void SessionJoined(IGroupStateContext context, GroupStateType prevState, SessionInfo session, CancellationToken cancellationToken);
|
public abstract void SessionJoined(IGroupStateContext context, GroupStateType prevState, SessionInfo session, CancellationToken cancellationToken);
|
||||||
@ -52,7 +58,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public virtual void HandleRequest(IGroupStateContext context, GroupStateType prevState, SetPlaylistItemGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
public virtual void HandleRequest(IGroupStateContext context, GroupStateType prevState, SetPlaylistItemGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var waitingState = new WaitingGroupState(Logger);
|
var waitingState = new WaitingGroupState(LoggerFactory);
|
||||||
context.SetState(waitingState);
|
context.SetState(waitingState);
|
||||||
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
||||||
}
|
}
|
||||||
@ -68,9 +74,9 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
|
|
||||||
if (playingItemRemoved && !context.PlayQueue.IsItemPlaying())
|
if (playingItemRemoved && !context.PlayQueue.IsItemPlaying())
|
||||||
{
|
{
|
||||||
Logger.LogDebug("HandleRequest: {RequestType} in group {GroupId}, play queue is empty.", request.Type, context.GroupId.ToString());
|
_logger.LogDebug("Play queue in group {GroupId} is now empty.", context.GroupId.ToString());
|
||||||
|
|
||||||
IGroupState idleState = new IdleGroupState(Logger);
|
IGroupState idleState = new IdleGroupState(LoggerFactory);
|
||||||
context.SetState(idleState);
|
context.SetState(idleState);
|
||||||
var stopRequest = new StopGroupRequest();
|
var stopRequest = new StopGroupRequest();
|
||||||
idleState.HandleRequest(context, Type, stopRequest, session, cancellationToken);
|
idleState.HandleRequest(context, Type, stopRequest, session, cancellationToken);
|
||||||
@ -84,7 +90,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
Logger.LogError("HandleRequest: {RequestType} in group {GroupId}, unable to move item in play queue.", request.Type, context.GroupId.ToString());
|
_logger.LogError("Unable to move item in group {GroupId}.", context.GroupId.ToString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +106,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
Logger.LogError("HandleRequest: {RequestType} in group {GroupId}, unable to add items to play queue.", request.Type, context.GroupId.ToString());
|
_logger.LogError("Unable to add items to play queue in group {GroupId}.", context.GroupId.ToString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +216,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
|
|
||||||
private void UnhandledRequest(IGroupPlaybackRequest request)
|
private void UnhandledRequest(IGroupPlaybackRequest request)
|
||||||
{
|
{
|
||||||
Logger.LogWarning("HandleRequest: unhandled {RequestType} request in {StateType} state.", request.Type, Type);
|
_logger.LogWarning("Unhandled request of type {RequestType} in {StateType} state.", request.Type, Type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,14 +14,19 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
public class IdleGroupState : AbstractGroupState
|
public class IdleGroupState : AbstractGroupState
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The logger.
|
||||||
|
/// </summary>
|
||||||
|
private readonly ILogger<IdleGroupState> _logger;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="IdleGroupState"/> class.
|
/// Initializes a new instance of the <see cref="IdleGroupState"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="logger">Instance of the <see cref="ILogger"/> interface.</param>
|
/// <param name="loggerFactory">Instance of the <see cref="ILoggerFactory"/> interface.</param>
|
||||||
public IdleGroupState(ILogger logger)
|
public IdleGroupState(ILoggerFactory loggerFactory)
|
||||||
: base(logger)
|
: base(loggerFactory)
|
||||||
{
|
{
|
||||||
// Do nothing.
|
_logger = LoggerFactory.CreateLogger<IdleGroupState>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -43,7 +48,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, PlayGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, PlayGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Change state.
|
// Change state.
|
||||||
var waitingState = new WaitingGroupState(Logger);
|
var waitingState = new WaitingGroupState(LoggerFactory);
|
||||||
context.SetState(waitingState);
|
context.SetState(waitingState);
|
||||||
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
||||||
}
|
}
|
||||||
@ -52,7 +57,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, UnpauseGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, UnpauseGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Change state.
|
// Change state.
|
||||||
var waitingState = new WaitingGroupState(Logger);
|
var waitingState = new WaitingGroupState(LoggerFactory);
|
||||||
context.SetState(waitingState);
|
context.SetState(waitingState);
|
||||||
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
||||||
}
|
}
|
||||||
@ -91,7 +96,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, NextTrackGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, NextTrackGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Change state.
|
// Change state.
|
||||||
var waitingState = new WaitingGroupState(Logger);
|
var waitingState = new WaitingGroupState(LoggerFactory);
|
||||||
context.SetState(waitingState);
|
context.SetState(waitingState);
|
||||||
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
||||||
}
|
}
|
||||||
@ -100,7 +105,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, PreviousTrackGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, PreviousTrackGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Change state.
|
// Change state.
|
||||||
var waitingState = new WaitingGroupState(Logger);
|
var waitingState = new WaitingGroupState(LoggerFactory);
|
||||||
context.SetState(waitingState);
|
context.SetState(waitingState);
|
||||||
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
||||||
}
|
}
|
||||||
|
@ -15,14 +15,19 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
public class PausedGroupState : AbstractGroupState
|
public class PausedGroupState : AbstractGroupState
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The logger.
|
||||||
|
/// </summary>
|
||||||
|
private readonly ILogger<PausedGroupState> _logger;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="PausedGroupState"/> class.
|
/// Initializes a new instance of the <see cref="PausedGroupState"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="logger">Instance of the <see cref="ILogger"/> interface.</param>
|
/// <param name="loggerFactory">Instance of the <see cref="ILoggerFactory"/> interface.</param>
|
||||||
public PausedGroupState(ILogger logger)
|
public PausedGroupState(ILoggerFactory loggerFactory)
|
||||||
: base(logger)
|
: base(loggerFactory)
|
||||||
{
|
{
|
||||||
// Do nothing.
|
_logger = LoggerFactory.CreateLogger<PausedGroupState>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -32,7 +37,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
public override void SessionJoined(IGroupStateContext context, GroupStateType prevState, SessionInfo session, CancellationToken cancellationToken)
|
public override void SessionJoined(IGroupStateContext context, GroupStateType prevState, SessionInfo session, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Wait for session to be ready.
|
// Wait for session to be ready.
|
||||||
var waitingState = new WaitingGroupState(Logger);
|
var waitingState = new WaitingGroupState(LoggerFactory);
|
||||||
context.SetState(waitingState);
|
context.SetState(waitingState);
|
||||||
waitingState.SessionJoined(context, Type, session, cancellationToken);
|
waitingState.SessionJoined(context, Type, session, cancellationToken);
|
||||||
}
|
}
|
||||||
@ -47,7 +52,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, PlayGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, PlayGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Change state.
|
// Change state.
|
||||||
var waitingState = new WaitingGroupState(Logger);
|
var waitingState = new WaitingGroupState(LoggerFactory);
|
||||||
context.SetState(waitingState);
|
context.SetState(waitingState);
|
||||||
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
||||||
}
|
}
|
||||||
@ -56,7 +61,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, UnpauseGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, UnpauseGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Change state.
|
// Change state.
|
||||||
var playingState = new PlayingGroupState(Logger);
|
var playingState = new PlayingGroupState(LoggerFactory);
|
||||||
context.SetState(playingState);
|
context.SetState(playingState);
|
||||||
playingState.HandleRequest(context, Type, request, session, cancellationToken);
|
playingState.HandleRequest(context, Type, request, session, cancellationToken);
|
||||||
}
|
}
|
||||||
@ -96,7 +101,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, StopGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, StopGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Change state.
|
// Change state.
|
||||||
var idleState = new IdleGroupState(Logger);
|
var idleState = new IdleGroupState(LoggerFactory);
|
||||||
context.SetState(idleState);
|
context.SetState(idleState);
|
||||||
idleState.HandleRequest(context, Type, request, session, cancellationToken);
|
idleState.HandleRequest(context, Type, request, session, cancellationToken);
|
||||||
}
|
}
|
||||||
@ -105,7 +110,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, SeekGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, SeekGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Change state.
|
// Change state.
|
||||||
var waitingState = new WaitingGroupState(Logger);
|
var waitingState = new WaitingGroupState(LoggerFactory);
|
||||||
context.SetState(waitingState);
|
context.SetState(waitingState);
|
||||||
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
||||||
}
|
}
|
||||||
@ -114,7 +119,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, BufferGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, BufferGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Change state.
|
// Change state.
|
||||||
var waitingState = new WaitingGroupState(Logger);
|
var waitingState = new WaitingGroupState(LoggerFactory);
|
||||||
context.SetState(waitingState);
|
context.SetState(waitingState);
|
||||||
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
||||||
}
|
}
|
||||||
@ -143,7 +148,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, NextTrackGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, NextTrackGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Change state.
|
// Change state.
|
||||||
var waitingState = new WaitingGroupState(Logger);
|
var waitingState = new WaitingGroupState(LoggerFactory);
|
||||||
context.SetState(waitingState);
|
context.SetState(waitingState);
|
||||||
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
||||||
}
|
}
|
||||||
@ -152,7 +157,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, PreviousTrackGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, PreviousTrackGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Change state.
|
// Change state.
|
||||||
var waitingState = new WaitingGroupState(Logger);
|
var waitingState = new WaitingGroupState(LoggerFactory);
|
||||||
context.SetState(waitingState);
|
context.SetState(waitingState);
|
||||||
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
||||||
}
|
}
|
||||||
|
@ -15,14 +15,19 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
public class PlayingGroupState : AbstractGroupState
|
public class PlayingGroupState : AbstractGroupState
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The logger.
|
||||||
|
/// </summary>
|
||||||
|
private readonly ILogger<PlayingGroupState> _logger;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="PlayingGroupState"/> class.
|
/// Initializes a new instance of the <see cref="PlayingGroupState"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="logger">Instance of the <see cref="ILogger"/> interface.</param>
|
/// <param name="loggerFactory">Instance of the <see cref="ILoggerFactory"/> interface.</param>
|
||||||
public PlayingGroupState(ILogger logger)
|
public PlayingGroupState(ILoggerFactory loggerFactory)
|
||||||
: base(logger)
|
: base(loggerFactory)
|
||||||
{
|
{
|
||||||
// Do nothing.
|
_logger = LoggerFactory.CreateLogger<PlayingGroupState>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -37,7 +42,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
public override void SessionJoined(IGroupStateContext context, GroupStateType prevState, SessionInfo session, CancellationToken cancellationToken)
|
public override void SessionJoined(IGroupStateContext context, GroupStateType prevState, SessionInfo session, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Wait for session to be ready.
|
// Wait for session to be ready.
|
||||||
var waitingState = new WaitingGroupState(Logger);
|
var waitingState = new WaitingGroupState(LoggerFactory);
|
||||||
context.SetState(waitingState);
|
context.SetState(waitingState);
|
||||||
waitingState.SessionJoined(context, Type, session, cancellationToken);
|
waitingState.SessionJoined(context, Type, session, cancellationToken);
|
||||||
}
|
}
|
||||||
@ -52,7 +57,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, PlayGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, PlayGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Change state.
|
// Change state.
|
||||||
var waitingState = new WaitingGroupState(Logger);
|
var waitingState = new WaitingGroupState(LoggerFactory);
|
||||||
context.SetState(waitingState);
|
context.SetState(waitingState);
|
||||||
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
||||||
}
|
}
|
||||||
@ -89,7 +94,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, PauseGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, PauseGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Change state.
|
// Change state.
|
||||||
var pausedState = new PausedGroupState(Logger);
|
var pausedState = new PausedGroupState(LoggerFactory);
|
||||||
context.SetState(pausedState);
|
context.SetState(pausedState);
|
||||||
pausedState.HandleRequest(context, Type, request, session, cancellationToken);
|
pausedState.HandleRequest(context, Type, request, session, cancellationToken);
|
||||||
}
|
}
|
||||||
@ -98,7 +103,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, StopGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, StopGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Change state.
|
// Change state.
|
||||||
var idleState = new IdleGroupState(Logger);
|
var idleState = new IdleGroupState(LoggerFactory);
|
||||||
context.SetState(idleState);
|
context.SetState(idleState);
|
||||||
idleState.HandleRequest(context, Type, request, session, cancellationToken);
|
idleState.HandleRequest(context, Type, request, session, cancellationToken);
|
||||||
}
|
}
|
||||||
@ -107,7 +112,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, SeekGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, SeekGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Change state.
|
// Change state.
|
||||||
var waitingState = new WaitingGroupState(Logger);
|
var waitingState = new WaitingGroupState(LoggerFactory);
|
||||||
context.SetState(waitingState);
|
context.SetState(waitingState);
|
||||||
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
||||||
}
|
}
|
||||||
@ -121,7 +126,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Change state.
|
// Change state.
|
||||||
var waitingState = new WaitingGroupState(Logger);
|
var waitingState = new WaitingGroupState(LoggerFactory);
|
||||||
context.SetState(waitingState);
|
context.SetState(waitingState);
|
||||||
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
||||||
}
|
}
|
||||||
@ -146,7 +151,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, NextTrackGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, NextTrackGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Change state.
|
// Change state.
|
||||||
var waitingState = new WaitingGroupState(Logger);
|
var waitingState = new WaitingGroupState(LoggerFactory);
|
||||||
context.SetState(waitingState);
|
context.SetState(waitingState);
|
||||||
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
||||||
}
|
}
|
||||||
@ -155,7 +160,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, PreviousTrackGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
public override void HandleRequest(IGroupStateContext context, GroupStateType prevState, PreviousTrackGroupRequest request, SessionInfo session, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Change state.
|
// Change state.
|
||||||
var waitingState = new WaitingGroupState(Logger);
|
var waitingState = new WaitingGroupState(LoggerFactory);
|
||||||
context.SetState(waitingState);
|
context.SetState(waitingState);
|
||||||
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
waitingState.HandleRequest(context, Type, request, session, cancellationToken);
|
||||||
}
|
}
|
||||||
|
@ -15,14 +15,19 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
public class WaitingGroupState : AbstractGroupState
|
public class WaitingGroupState : AbstractGroupState
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The logger.
|
||||||
|
/// </summary>
|
||||||
|
private readonly ILogger<WaitingGroupState> _logger;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="WaitingGroupState"/> class.
|
/// Initializes a new instance of the <see cref="WaitingGroupState"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="logger">Instance of the <see cref="ILogger"/> interface.</param>
|
/// <param name="loggerFactory">Instance of the <see cref="ILoggerFactory"/> interface.</param>
|
||||||
public WaitingGroupState(ILogger logger)
|
public WaitingGroupState(ILoggerFactory loggerFactory)
|
||||||
: base(logger)
|
: base(loggerFactory)
|
||||||
{
|
{
|
||||||
// Do nothing.
|
_logger = LoggerFactory.CreateLogger<WaitingGroupState>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -97,21 +102,21 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
{
|
{
|
||||||
if (ResumePlaying)
|
if (ResumePlaying)
|
||||||
{
|
{
|
||||||
|
_logger.LogDebug("Session {SessionId} left group {GroupId}, notifying others to resume.", session.Id, context.GroupId.ToString());
|
||||||
|
|
||||||
// Client, that was buffering, left the group.
|
// Client, that was buffering, left the group.
|
||||||
var playingState = new PlayingGroupState(Logger);
|
var playingState = new PlayingGroupState(LoggerFactory);
|
||||||
context.SetState(playingState);
|
context.SetState(playingState);
|
||||||
var unpauseRequest = new UnpauseGroupRequest();
|
var unpauseRequest = new UnpauseGroupRequest();
|
||||||
playingState.HandleRequest(context, Type, unpauseRequest, session, cancellationToken);
|
playingState.HandleRequest(context, Type, unpauseRequest, session, cancellationToken);
|
||||||
|
|
||||||
Logger.LogDebug("SessionLeaving: {SessionId} left group {GroupId}, notifying others to resume.", session.Id, context.GroupId.ToString());
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Group is ready, returning to previous state.
|
_logger.LogDebug("Session {SessionId} left group {GroupId}, returning to previous state.", session.Id, context.GroupId.ToString());
|
||||||
var pausedState = new PausedGroupState(Logger);
|
|
||||||
context.SetState(pausedState);
|
|
||||||
|
|
||||||
Logger.LogDebug("SessionLeaving: {SessionId} left group {GroupId}, returning to previous state.", session.Id, context.GroupId.ToString());
|
// Group is ready, returning to previous state.
|
||||||
|
var pausedState = new PausedGroupState(LoggerFactory);
|
||||||
|
context.SetState(pausedState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,13 +136,13 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
var setQueueStatus = context.SetPlayQueue(request.PlayingQueue, request.PlayingItemPosition, request.StartPositionTicks);
|
var setQueueStatus = context.SetPlayQueue(request.PlayingQueue, request.PlayingItemPosition, request.StartPositionTicks);
|
||||||
if (!setQueueStatus)
|
if (!setQueueStatus)
|
||||||
{
|
{
|
||||||
Logger.LogError("HandleRequest: {RequestType} in group {GroupId}, unable to set playing queue.", request.Type, context.GroupId.ToString());
|
_logger.LogError("Unable to set playing queue in group {GroupId}.", context.GroupId.ToString());
|
||||||
|
|
||||||
// Ignore request and return to previous state.
|
// Ignore request and return to previous state.
|
||||||
IGroupState newState = prevState switch {
|
IGroupState newState = prevState switch {
|
||||||
GroupStateType.Playing => new PlayingGroupState(Logger),
|
GroupStateType.Playing => new PlayingGroupState(LoggerFactory),
|
||||||
GroupStateType.Paused => new PausedGroupState(Logger),
|
GroupStateType.Paused => new PausedGroupState(LoggerFactory),
|
||||||
_ => new IdleGroupState(Logger)
|
_ => new IdleGroupState(LoggerFactory)
|
||||||
};
|
};
|
||||||
|
|
||||||
context.SetState(newState);
|
context.SetState(newState);
|
||||||
@ -151,7 +156,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
// Reset status of sessions and await for all Ready events.
|
// Reset status of sessions and await for all Ready events.
|
||||||
context.SetAllBuffering(true);
|
context.SetAllBuffering(true);
|
||||||
|
|
||||||
Logger.LogDebug("HandleRequest: {RequestType} in group {GroupId}, {SessionId} set a new play queue.", request.Type, context.GroupId.ToString(), session.Id);
|
_logger.LogDebug("Session {SessionId} set a new play queue in group {GroupId}.", session.Id, context.GroupId.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -181,14 +186,14 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
// Return to old state.
|
// Return to old state.
|
||||||
IGroupState newState = prevState switch
|
IGroupState newState = prevState switch
|
||||||
{
|
{
|
||||||
GroupStateType.Playing => new PlayingGroupState(Logger),
|
GroupStateType.Playing => new PlayingGroupState(LoggerFactory),
|
||||||
GroupStateType.Paused => new PausedGroupState(Logger),
|
GroupStateType.Paused => new PausedGroupState(LoggerFactory),
|
||||||
_ => new IdleGroupState(Logger)
|
_ => new IdleGroupState(LoggerFactory)
|
||||||
};
|
};
|
||||||
|
|
||||||
context.SetState(newState);
|
context.SetState(newState);
|
||||||
|
|
||||||
Logger.LogDebug("HandleRequest: {RequestType} in group {GroupId}, unable to change current playing item.", request.Type, context.GroupId.ToString());
|
_logger.LogDebug("Unable to change current playing item in group {GroupId}.", context.GroupId.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,19 +219,19 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
// Reset status of sessions and await for all Ready events.
|
// Reset status of sessions and await for all Ready events.
|
||||||
context.SetAllBuffering(true);
|
context.SetAllBuffering(true);
|
||||||
|
|
||||||
Logger.LogDebug("HandleRequest: {RequestType} in group {GroupId}, waiting for all ready events.", request.Type, context.GroupId.ToString());
|
_logger.LogDebug("Group {GroupId} is waiting for all ready events.", context.GroupId.ToString());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ResumePlaying)
|
if (ResumePlaying)
|
||||||
{
|
{
|
||||||
Logger.LogDebug("HandleRequest: {RequestType} in group {GroupId}, ignoring sessions that are not ready and forcing the playback to start.", request.Type, context.GroupId.ToString());
|
_logger.LogDebug("Forcing the playback to start in group {GroupId}. Group-wait is disabled until next state change.", 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);
|
context.SetAllBuffering(false);
|
||||||
|
|
||||||
// Change state.
|
// Change state.
|
||||||
var playingState = new PlayingGroupState(Logger)
|
var playingState = new PlayingGroupState(LoggerFactory)
|
||||||
{
|
{
|
||||||
IgnoreBuffering = true
|
IgnoreBuffering = true
|
||||||
};
|
};
|
||||||
@ -272,7 +277,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Change state.
|
// Change state.
|
||||||
var idleState = new IdleGroupState(Logger);
|
var idleState = new IdleGroupState(LoggerFactory);
|
||||||
context.SetState(idleState);
|
context.SetState(idleState);
|
||||||
idleState.HandleRequest(context, Type, request, session, cancellationToken);
|
idleState.HandleRequest(context, Type, request, session, cancellationToken);
|
||||||
}
|
}
|
||||||
@ -326,7 +331,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
// 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(), StringComparison.OrdinalIgnoreCase))
|
if (!request.PlaylistItemId.Equals(context.PlayQueue.GetPlayingItemPlaylistId(), StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
Logger.LogDebug("HandleRequest: {RequestType} in group {GroupId}, {SessionId} has wrong playlist item.", request.Type, context.GroupId.ToString(), session.Id);
|
_logger.LogDebug("Session {SessionId} reported wrong playlist item in group {GroupId}.", session.Id, context.GroupId.ToString());
|
||||||
|
|
||||||
var playQueueUpdate = context.GetPlayQueueUpdate(PlayQueueUpdateReason.SetCurrentItem);
|
var playQueueUpdate = context.GetPlayQueueUpdate(PlayQueueUpdateReason.SetCurrentItem);
|
||||||
var updateSession = context.NewSyncPlayGroupUpdate(GroupUpdateType.PlayQueue, playQueueUpdate);
|
var updateSession = context.NewSyncPlayGroupUpdate(GroupUpdateType.PlayQueue, playQueueUpdate);
|
||||||
@ -400,7 +405,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
// 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(), StringComparison.OrdinalIgnoreCase))
|
if (!request.PlaylistItemId.Equals(context.PlayQueue.GetPlayingItemPlaylistId(), StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
Logger.LogDebug("HandleRequest: {RequestType} in group {GroupId}, {SessionId} has wrong playlist item.", request.Type, context.GroupId.ToString(), session.Id);
|
_logger.LogDebug("Session {SessionId} reported wrong playlist item in group {GroupId}.", session.Id, context.GroupId.ToString());
|
||||||
|
|
||||||
var playQueueUpdate = context.GetPlayQueueUpdate(PlayQueueUpdateReason.SetCurrentItem);
|
var playQueueUpdate = context.GetPlayQueueUpdate(PlayQueueUpdateReason.SetCurrentItem);
|
||||||
var update = context.NewSyncPlayGroupUpdate(GroupUpdateType.PlayQueue, playQueueUpdate);
|
var update = context.NewSyncPlayGroupUpdate(GroupUpdateType.PlayQueue, playQueueUpdate);
|
||||||
@ -420,7 +425,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
var timeSyncThresholdTicks = TimeSpan.FromMilliseconds(context.TimeSyncOffset).Ticks;
|
var timeSyncThresholdTicks = TimeSpan.FromMilliseconds(context.TimeSyncOffset).Ticks;
|
||||||
if (Math.Abs(elapsedTime.Ticks) > timeSyncThresholdTicks)
|
if (Math.Abs(elapsedTime.Ticks) > timeSyncThresholdTicks)
|
||||||
{
|
{
|
||||||
Logger.LogWarning("HandleRequest: {RequestType} in group {GroupId}, {SessionId} is not time syncing properly. Ignoring elapsed time.", request.Type, context.GroupId.ToString(), session.Id);
|
_logger.LogWarning("Session {SessionId} is not time syncing properly. Ignoring elapsed time.", session.Id);
|
||||||
|
|
||||||
elapsedTime = TimeSpan.Zero;
|
elapsedTime = TimeSpan.Zero;
|
||||||
}
|
}
|
||||||
@ -436,7 +441,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
var delayTicks = context.PositionTicks - clientPosition.Ticks;
|
var delayTicks = context.PositionTicks - clientPosition.Ticks;
|
||||||
var maxPlaybackOffsetTicks = TimeSpan.FromMilliseconds(context.MaxPlaybackOffset).Ticks;
|
var maxPlaybackOffsetTicks = TimeSpan.FromMilliseconds(context.MaxPlaybackOffset).Ticks;
|
||||||
|
|
||||||
Logger.LogDebug("HandleRequest: {RequestType} in group {GroupId}, {SessionId} at {PositionTicks} (delay of {Delay} seconds).", request.Type, context.GroupId.ToString(), session.Id, clientPosition, TimeSpan.FromTicks(delayTicks).TotalSeconds);
|
_logger.LogDebug("Session {SessionId} is at {PositionTicks} (delay of {Delay} seconds) in group {GroupId}.", session.Id, clientPosition, TimeSpan.FromTicks(delayTicks).TotalSeconds, context.GroupId.ToString());
|
||||||
|
|
||||||
if (ResumePlaying)
|
if (ResumePlaying)
|
||||||
{
|
{
|
||||||
@ -454,7 +459,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
// Notify relevant state change event.
|
// Notify relevant state change event.
|
||||||
SendGroupStateUpdate(context, request, session, cancellationToken);
|
SendGroupStateUpdate(context, request, session, cancellationToken);
|
||||||
|
|
||||||
Logger.LogWarning("HandleRequest: {RequestType} in group {GroupId}, {SessionId} got lost in time, correcting.", request.Type, context.GroupId.ToString(), session.Id);
|
_logger.LogWarning("Session {SessionId} got lost in time, correcting.", session.Id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,7 +473,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
command.When = currentTime.AddTicks(delayTicks);
|
command.When = currentTime.AddTicks(delayTicks);
|
||||||
context.SendCommand(session, SyncPlayBroadcastType.CurrentSession, command, cancellationToken);
|
context.SendCommand(session, SyncPlayBroadcastType.CurrentSession, command, cancellationToken);
|
||||||
|
|
||||||
Logger.LogInformation("HandleRequest: {RequestType} in group {GroupId}, others still buffering, {SessionId} will pause when ready in {Delay} seconds.", request.Type, context.GroupId.ToString(), session.Id, TimeSpan.FromTicks(delayTicks).TotalSeconds);
|
_logger.LogInformation("Session {SessionId} will pause when ready in {Delay} seconds. Group {GroupId} is waiting for all ready events.", session.Id, TimeSpan.FromTicks(delayTicks).TotalSeconds, context.GroupId.ToString());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -487,7 +492,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
|
|
||||||
context.SendCommand(session, filter, command, cancellationToken);
|
context.SendCommand(session, filter, command, cancellationToken);
|
||||||
|
|
||||||
Logger.LogInformation("HandleRequest: {RequestType} in group {GroupId}, {SessionId} is recovering, notifying others to resume in {Delay} seconds.", request.Type, context.GroupId.ToString(), session.Id, TimeSpan.FromTicks(delayTicks).TotalSeconds);
|
_logger.LogInformation("Session {SessionId} is recovering, group {GroupId} will resume in {Delay} seconds.", session.Id, context.GroupId.ToString(), TimeSpan.FromTicks(delayTicks).TotalSeconds);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -500,11 +505,11 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
var command = context.NewSyncPlayCommand(SendCommandType.Unpause);
|
var command = context.NewSyncPlayCommand(SendCommandType.Unpause);
|
||||||
context.SendCommand(session, SyncPlayBroadcastType.AllGroup, command, cancellationToken);
|
context.SendCommand(session, SyncPlayBroadcastType.AllGroup, command, cancellationToken);
|
||||||
|
|
||||||
Logger.LogWarning("HandleRequest: {RequestType} in group {GroupId}, {SessionId} resumed playback but did not update others in time. {Delay} seconds to recover.", request.Type, context.GroupId.ToString(), session.Id, TimeSpan.FromTicks(delayTicks).TotalSeconds);
|
_logger.LogWarning("Session {SessionId} resumed playback, group {GroupId} has {Delay} seconds to recover.", session.Id, context.GroupId.ToString(), TimeSpan.FromTicks(delayTicks).TotalSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change state.
|
// Change state.
|
||||||
var playingState = new PlayingGroupState(Logger);
|
var playingState = new PlayingGroupState(LoggerFactory);
|
||||||
context.SetState(playingState);
|
context.SetState(playingState);
|
||||||
playingState.HandleRequest(context, Type, request, session, cancellationToken);
|
playingState.HandleRequest(context, Type, request, session, cancellationToken);
|
||||||
}
|
}
|
||||||
@ -523,7 +528,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
// Notify relevant state change event.
|
// Notify relevant state change event.
|
||||||
SendGroupStateUpdate(context, request, session, cancellationToken);
|
SendGroupStateUpdate(context, request, session, cancellationToken);
|
||||||
|
|
||||||
Logger.LogWarning("HandleRequest: {RequestType} in group {GroupId}, {SessionId} is seeking to wrong position, correcting.", request.Type, context.GroupId.ToString(), session.Id);
|
_logger.LogWarning("Session {SessionId} is seeking to wrong position, correcting.", session.Id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -534,8 +539,10 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
|
|
||||||
if (!context.IsBuffering())
|
if (!context.IsBuffering())
|
||||||
{
|
{
|
||||||
|
_logger.LogDebug("Session {SessionId} is ready, group {GroupId} is ready.", session.Id, context.GroupId.ToString());
|
||||||
|
|
||||||
// Group is ready, returning to previous state.
|
// Group is ready, returning to previous state.
|
||||||
var pausedState = new PausedGroupState(Logger);
|
var pausedState = new PausedGroupState(LoggerFactory);
|
||||||
context.SetState(pausedState);
|
context.SetState(pausedState);
|
||||||
|
|
||||||
if (InitialState.Equals(GroupStateType.Playing))
|
if (InitialState.Equals(GroupStateType.Playing))
|
||||||
@ -548,8 +555,6 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
{
|
{
|
||||||
pausedState.HandleRequest(context, Type, request, session, cancellationToken);
|
pausedState.HandleRequest(context, Type, request, session, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.LogDebug("HandleRequest: {RequestType} in group {GroupId}, {SessionId} is ready, returning to previous state.", request.Type, context.GroupId.ToString(), session.Id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -569,7 +574,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
// 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(), StringComparison.OrdinalIgnoreCase))
|
if (!request.PlaylistItemId.Equals(context.PlayQueue.GetPlayingItemPlaylistId(), StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
Logger.LogDebug("HandleRequest: {RequestType} in group {GroupId}, {SessionId} provided the wrong playlist identifier.", request.Type, context.GroupId.ToString(), session.Id);
|
_logger.LogDebug("Session {SessionId} provided the wrong playlist item for group {GroupId}.", session.Id, context.GroupId.ToString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,14 +594,14 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
// Return to old state.
|
// Return to old state.
|
||||||
IGroupState newState = prevState switch
|
IGroupState newState = prevState switch
|
||||||
{
|
{
|
||||||
GroupStateType.Playing => new PlayingGroupState(Logger),
|
GroupStateType.Playing => new PlayingGroupState(LoggerFactory),
|
||||||
GroupStateType.Paused => new PausedGroupState(Logger),
|
GroupStateType.Paused => new PausedGroupState(LoggerFactory),
|
||||||
_ => new IdleGroupState(Logger)
|
_ => new IdleGroupState(LoggerFactory)
|
||||||
};
|
};
|
||||||
|
|
||||||
context.SetState(newState);
|
context.SetState(newState);
|
||||||
|
|
||||||
Logger.LogDebug("HandleRequest: {RequestType} in group {GroupId}, no next track available.", request.Type, context.GroupId.ToString());
|
_logger.LogDebug("No next track available in group {GroupId}.", context.GroupId.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -615,7 +620,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
// 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(), StringComparison.OrdinalIgnoreCase))
|
if (!request.PlaylistItemId.Equals(context.PlayQueue.GetPlayingItemPlaylistId(), StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
Logger.LogDebug("HandleRequest: {RequestType} in group {GroupId}, {SessionId} provided the wrong playlist identifier.", request.Type, context.GroupId.ToString(), session.Id);
|
_logger.LogDebug("Session {SessionId} provided the wrong playlist item for group {GroupId}.", session.Id, context.GroupId.ToString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -635,14 +640,14 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
// Return to old state.
|
// Return to old state.
|
||||||
IGroupState newState = prevState switch
|
IGroupState newState = prevState switch
|
||||||
{
|
{
|
||||||
GroupStateType.Playing => new PlayingGroupState(Logger),
|
GroupStateType.Playing => new PlayingGroupState(LoggerFactory),
|
||||||
GroupStateType.Paused => new PausedGroupState(Logger),
|
GroupStateType.Paused => new PausedGroupState(LoggerFactory),
|
||||||
_ => new IdleGroupState(Logger)
|
_ => new IdleGroupState(LoggerFactory)
|
||||||
};
|
};
|
||||||
|
|
||||||
context.SetState(newState);
|
context.SetState(newState);
|
||||||
|
|
||||||
Logger.LogDebug("HandleRequest: {RequestType} in group {GroupId}, no previous track available.", request.Type, context.GroupId.ToString());
|
_logger.LogDebug("No previous track available in group {GroupId}.", context.GroupId.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,12 +658,12 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
|
|
||||||
if (!context.IsBuffering())
|
if (!context.IsBuffering())
|
||||||
{
|
{
|
||||||
Logger.LogDebug("HandleRequest: {RequestType} in group {GroupId}, returning to previous state.", request.Type, context.GroupId.ToString());
|
_logger.LogDebug("Ignoring session {SessionId}, group {GroupId} is ready.", session.Id, context.GroupId.ToString());
|
||||||
|
|
||||||
if (ResumePlaying)
|
if (ResumePlaying)
|
||||||
{
|
{
|
||||||
// Client, that was buffering, stopped following playback.
|
// Client, that was buffering, stopped following playback.
|
||||||
var playingState = new PlayingGroupState(Logger);
|
var playingState = new PlayingGroupState(LoggerFactory);
|
||||||
context.SetState(playingState);
|
context.SetState(playingState);
|
||||||
var unpauseRequest = new UnpauseGroupRequest();
|
var unpauseRequest = new UnpauseGroupRequest();
|
||||||
playingState.HandleRequest(context, Type, unpauseRequest, session, cancellationToken);
|
playingState.HandleRequest(context, Type, unpauseRequest, session, cancellationToken);
|
||||||
@ -666,7 +671,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Group is ready, returning to previous state.
|
// Group is ready, returning to previous state.
|
||||||
var pausedState = new PausedGroupState(Logger);
|
var pausedState = new PausedGroupState(LoggerFactory);
|
||||||
context.SetState(pausedState);
|
context.SetState(pausedState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ namespace MediaBrowser.Controller.SyncPlay.Queue
|
|||||||
/// Random number generator used to shuffle lists.
|
/// Random number generator used to shuffle lists.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The random number generator.</value>
|
/// <value>The random number generator.</value>
|
||||||
private readonly Random randomNumberGenerator = new Random();
|
private readonly Random _randomNumberGenerator = new Random();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="PlayQueueManager" /> class.
|
/// Initializes a new instance of the <see cref="PlayQueueManager" /> class.
|
||||||
@ -102,7 +102,7 @@ namespace MediaBrowser.Controller.SyncPlay.Queue
|
|||||||
SortedPlaylist = CreateQueueItemsFromArray(items);
|
SortedPlaylist = CreateQueueItemsFromArray(items);
|
||||||
if (ShuffleMode.Equals(GroupShuffleMode.Shuffle))
|
if (ShuffleMode.Equals(GroupShuffleMode.Shuffle))
|
||||||
{
|
{
|
||||||
ShuffledPlaylist = SortedPlaylist.ToList();
|
ShuffledPlaylist = new List<QueueItem>(SortedPlaylist);
|
||||||
Shuffle(ShuffledPlaylist);
|
Shuffle(ShuffledPlaylist);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,17 +134,17 @@ namespace MediaBrowser.Controller.SyncPlay.Queue
|
|||||||
{
|
{
|
||||||
if (PlayingItemIndex == NoPlayingItemIndex)
|
if (PlayingItemIndex == NoPlayingItemIndex)
|
||||||
{
|
{
|
||||||
ShuffledPlaylist = SortedPlaylist.ToList();
|
ShuffledPlaylist = new List<QueueItem>(SortedPlaylist);
|
||||||
Shuffle(ShuffledPlaylist);
|
Shuffle(ShuffledPlaylist);
|
||||||
}
|
}
|
||||||
else if (ShuffleMode.Equals(GroupShuffleMode.Sorted))
|
else if (ShuffleMode.Equals(GroupShuffleMode.Sorted))
|
||||||
{
|
{
|
||||||
// First time shuffle.
|
// First time shuffle.
|
||||||
var playingItem = SortedPlaylist[PlayingItemIndex];
|
var playingItem = SortedPlaylist[PlayingItemIndex];
|
||||||
ShuffledPlaylist = SortedPlaylist.ToList();
|
ShuffledPlaylist = new List<QueueItem>(SortedPlaylist);
|
||||||
ShuffledPlaylist.RemoveAt(PlayingItemIndex);
|
ShuffledPlaylist.RemoveAt(PlayingItemIndex);
|
||||||
Shuffle(ShuffledPlaylist);
|
Shuffle(ShuffledPlaylist);
|
||||||
ShuffledPlaylist = ShuffledPlaylist.Prepend(playingItem).ToList();
|
ShuffledPlaylist.Insert(0, playingItem);
|
||||||
PlayingItemIndex = 0;
|
PlayingItemIndex = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -153,7 +153,7 @@ namespace MediaBrowser.Controller.SyncPlay.Queue
|
|||||||
var playingItem = ShuffledPlaylist[PlayingItemIndex];
|
var playingItem = ShuffledPlaylist[PlayingItemIndex];
|
||||||
ShuffledPlaylist.RemoveAt(PlayingItemIndex);
|
ShuffledPlaylist.RemoveAt(PlayingItemIndex);
|
||||||
Shuffle(ShuffledPlaylist);
|
Shuffle(ShuffledPlaylist);
|
||||||
ShuffledPlaylist = ShuffledPlaylist.Prepend(playingItem).ToList();
|
ShuffledPlaylist.Insert(0, playingItem);
|
||||||
PlayingItemIndex = 0;
|
PlayingItemIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,14 +236,7 @@ namespace MediaBrowser.Controller.SyncPlay.Queue
|
|||||||
public string GetPlayingItemPlaylistId()
|
public string GetPlayingItemPlaylistId()
|
||||||
{
|
{
|
||||||
var playingItem = GetPlayingItem();
|
var playingItem = GetPlayingItem();
|
||||||
if (playingItem != null)
|
return playingItem?.PlaylistItemId;
|
||||||
{
|
|
||||||
return playingItem.PlaylistItemId;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -253,14 +246,7 @@ namespace MediaBrowser.Controller.SyncPlay.Queue
|
|||||||
public Guid GetPlayingItemId()
|
public Guid GetPlayingItemId()
|
||||||
{
|
{
|
||||||
var playingItem = GetPlayingItem();
|
var playingItem = GetPlayingItem();
|
||||||
if (playingItem != null)
|
return playingItem?.ItemId ?? Guid.Empty;
|
||||||
{
|
|
||||||
return playingItem.ItemId;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Guid.Empty;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -536,7 +522,7 @@ namespace MediaBrowser.Controller.SyncPlay.Queue
|
|||||||
while (n > 1)
|
while (n > 1)
|
||||||
{
|
{
|
||||||
n--;
|
n--;
|
||||||
int k = randomNumberGenerator.Next(n + 1);
|
int k = _randomNumberGenerator.Next(n + 1);
|
||||||
T value = list[k];
|
T value = list[k];
|
||||||
list[k] = list[n];
|
list[k] = list[n];
|
||||||
list[n] = value;
|
list[n] = value;
|
||||||
|
Loading…
Reference in New Issue
Block a user