Rewrite play queue logic of SyncPlay group

This commit is contained in:
Ionut Andrei Oanca 2020-10-22 15:49:37 +02:00
parent 0b4c751657
commit 1cabe82b59
2 changed files with 86 additions and 58 deletions

View File

@ -263,6 +263,7 @@ namespace Emby.Server.Implementations.SyncPlay
if (sessionIsPlayingAnItem) if (sessionIsPlayingAnItem)
{ {
var playlist = session.NowPlayingQueue.Select(item => item.Id).ToArray(); var playlist = session.NowPlayingQueue.Select(item => item.Id).ToArray();
PlayQueue.Reset();
PlayQueue.SetPlaylist(playlist); PlayQueue.SetPlaylist(playlist);
PlayQueue.SetPlayingItemById(session.FullNowPlayingItem.Id); PlayQueue.SetPlayingItemById(session.FullNowPlayingItem.Id);
RunTimeTicks = session.FullNowPlayingItem.RunTimeTicks ?? 0; RunTimeTicks = session.FullNowPlayingItem.RunTimeTicks ?? 0;
@ -515,6 +516,7 @@ namespace Emby.Server.Implementations.SyncPlay
return false; return false;
} }
PlayQueue.Reset();
PlayQueue.SetPlaylist(playQueue); PlayQueue.SetPlaylist(playQueue);
PlayQueue.SetPlayingItemByIndex(playingItemPosition); PlayQueue.SetPlayingItemByIndex(playingItemPosition);
var item = _libraryManager.GetItemById(PlayQueue.GetPlayingItemId()); var item = _libraryManager.GetItemById(PlayQueue.GetPlayingItemId());

View File

@ -69,7 +69,11 @@ namespace MediaBrowser.Controller.SyncPlay
/// <value>The progressive identifier.</value> /// <value>The progressive identifier.</value>
private int ProgressiveId { get; set; } = 0; private int ProgressiveId { get; set; } = 0;
private bool _disposed = false; /// <summary>
/// Placeholder index for when no item is playing.
/// </summary>
/// <value>The no-playing item index.</value>
private const int NoPlayingItemIndex = -1;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="PlayQueueManager" /> class. /// Initializes a new instance of the <see cref="PlayQueueManager" /> class.
@ -139,6 +143,26 @@ namespace MediaBrowser.Controller.SyncPlay
} }
} }
/// <summary>
/// Gets the current playing item, depending on the shuffle mode.
/// </summary>
/// <returns>The playing item.</returns>
private QueueItem GetPlayingItem()
{
if (PlayingItemIndex == NoPlayingItemIndex)
{
return null;
}
else if (ShuffleMode.Equals(GroupShuffleMode.Shuffle))
{
return ShuffledPlaylist[PlayingItemIndex];
}
else
{
return SortedPlaylist[PlayingItemIndex];
}
}
/// <summary> /// <summary>
/// Gets the current playlist as an array, depending on the shuffle mode. /// Gets the current playlist as an array, depending on the shuffle mode.
/// </summary> /// </summary>
@ -155,30 +179,36 @@ namespace MediaBrowser.Controller.SyncPlay
} }
/// <summary> /// <summary>
/// Sets a new playlist. Playing item is set to none. Resets shuffle mode and repeat mode as well. /// Sets a new playlist. Playing item is reset.
/// </summary> /// </summary>
/// <param name="items">The new items of the playlist.</param> /// <param name="items">The new items of the playlist.</param>
public void SetPlaylist(Guid[] items) public void SetPlaylist(Guid[] items)
{ {
SortedPlaylist.Clear();
ShuffledPlaylist.Clear();
SortedPlaylist = CreateQueueItemsFromArray(items); SortedPlaylist = CreateQueueItemsFromArray(items);
PlayingItemIndex = -1; if (ShuffleMode.Equals(GroupShuffleMode.Shuffle))
ShuffleMode = GroupShuffleMode.Sorted; {
RepeatMode = GroupRepeatMode.RepeatNone; ShuffledPlaylist = SortedPlaylist.ToList();
ShuffledPlaylist.Shuffle();
}
PlayingItemIndex = NoPlayingItemIndex;
LastChange = DateTime.UtcNow; LastChange = DateTime.UtcNow;
} }
/// <summary> /// <summary>
/// Appends new items to the playlist. The specified order is mantained for the sorted playlist, whereas items get shuffled for the shuffled playlist. /// Appends new items to the playlist. The specified order is mantained.
/// </summary> /// </summary>
/// <param name="items">The items to add to the playlist.</param> /// <param name="items">The items to add to the playlist.</param>
public void Queue(Guid[] items) public void Queue(Guid[] items)
{ {
var newItems = CreateQueueItemsFromArray(items); var newItems = CreateQueueItemsFromArray(items);
SortedPlaylist.AddRange(newItems);
SortedPlaylist.AddRange(newItems);
if (ShuffleMode.Equals(GroupShuffleMode.Shuffle)) if (ShuffleMode.Equals(GroupShuffleMode.Shuffle))
{ {
newItems.Shuffle();
ShuffledPlaylist.AddRange(newItems); ShuffledPlaylist.AddRange(newItems);
} }
@ -190,17 +220,13 @@ namespace MediaBrowser.Controller.SyncPlay
/// </summary> /// </summary>
public void ShufflePlaylist() public void ShufflePlaylist()
{ {
if (SortedPlaylist.Count() == 0) if (PlayingItemIndex == NoPlayingItemIndex) {
{
return;
}
if (PlayingItemIndex < 0) {
ShuffledPlaylist = SortedPlaylist.ToList(); ShuffledPlaylist = SortedPlaylist.ToList();
ShuffledPlaylist.Shuffle(); ShuffledPlaylist.Shuffle();
} }
else else if (ShuffleMode.Equals(GroupShuffleMode.Sorted))
{ {
// First time shuffle.
var playingItem = SortedPlaylist[PlayingItemIndex]; var playingItem = SortedPlaylist[PlayingItemIndex];
ShuffledPlaylist = SortedPlaylist.ToList(); ShuffledPlaylist = SortedPlaylist.ToList();
ShuffledPlaylist.RemoveAt(PlayingItemIndex); ShuffledPlaylist.RemoveAt(PlayingItemIndex);
@ -208,6 +234,15 @@ namespace MediaBrowser.Controller.SyncPlay
ShuffledPlaylist = ShuffledPlaylist.Prepend(playingItem).ToList(); ShuffledPlaylist = ShuffledPlaylist.Prepend(playingItem).ToList();
PlayingItemIndex = 0; PlayingItemIndex = 0;
} }
else
{
// Re-shuffle playlist.
var playingItem = ShuffledPlaylist[PlayingItemIndex];
ShuffledPlaylist.RemoveAt(PlayingItemIndex);
ShuffledPlaylist.Shuffle();
ShuffledPlaylist = ShuffledPlaylist.Prepend(playingItem).ToList();
PlayingItemIndex = 0;
}
ShuffleMode = GroupShuffleMode.Shuffle; ShuffleMode = GroupShuffleMode.Shuffle;
LastChange = DateTime.UtcNow; LastChange = DateTime.UtcNow;
@ -216,9 +251,9 @@ namespace MediaBrowser.Controller.SyncPlay
/// <summary> /// <summary>
/// Resets the playlist to sorted mode. Shuffle mode is changed. /// Resets the playlist to sorted mode. Shuffle mode is changed.
/// </summary> /// </summary>
public void SortShuffledPlaylist() public void RestoreSortedPlaylist()
{ {
if (PlayingItemIndex >= 0) if (PlayingItemIndex != NoPlayingItemIndex)
{ {
var playingItem = ShuffledPlaylist[PlayingItemIndex]; var playingItem = ShuffledPlaylist[PlayingItemIndex];
PlayingItemIndex = SortedPlaylist.IndexOf(playingItem); PlayingItemIndex = SortedPlaylist.IndexOf(playingItem);
@ -231,12 +266,12 @@ namespace MediaBrowser.Controller.SyncPlay
} }
/// <summary> /// <summary>
/// Clears the playlist. /// Clears the playlist. Shuffle mode is preserved.
/// </summary> /// </summary>
/// <param name="clearPlayingItem">Whether to remove the playing item as well.</param> /// <param name="clearPlayingItem">Whether to remove the playing item as well.</param>
public void ClearPlaylist(bool clearPlayingItem) public void ClearPlaylist(bool clearPlayingItem)
{ {
var playingItem = SortedPlaylist[PlayingItemIndex]; var playingItem = GetPlayingItem();
SortedPlaylist.Clear(); SortedPlaylist.Clear();
ShuffledPlaylist.Clear(); ShuffledPlaylist.Clear();
LastChange = DateTime.UtcNow; LastChange = DateTime.UtcNow;
@ -246,13 +281,18 @@ namespace MediaBrowser.Controller.SyncPlay
SortedPlaylist.Add(playingItem); SortedPlaylist.Add(playingItem);
if (ShuffleMode.Equals(GroupShuffleMode.Shuffle)) if (ShuffleMode.Equals(GroupShuffleMode.Shuffle))
{ {
SortedPlaylist.Add(playingItem); ShuffledPlaylist.Add(playingItem);
} }
PlayingItemIndex = 0;
}
else
{
PlayingItemIndex = NoPlayingItemIndex;
} }
} }
/// <summary> /// <summary>
/// Adds new items to the playlist right after the playing item. The specified order is mantained for the sorted playlist, whereas items get shuffled for the shuffled playlist. /// Adds new items to the playlist right after the playing item. The specified order is mantained.
/// </summary> /// </summary>
/// <param name="items">The items to add to the playlist.</param> /// <param name="items">The items to add to the playlist.</param>
public void QueueNext(Guid[] items) public void QueueNext(Guid[] items)
@ -261,10 +301,10 @@ namespace MediaBrowser.Controller.SyncPlay
if (ShuffleMode.Equals(GroupShuffleMode.Shuffle)) if (ShuffleMode.Equals(GroupShuffleMode.Shuffle))
{ {
// Append items to sorted playlist as they are. var playingItem = GetPlayingItem();
SortedPlaylist.AddRange(newItems); var sortedPlayingItemIndex = SortedPlaylist.IndexOf(playingItem);
// Shuffle items before adding to shuffled playlist. // Append items to sorted and shuffled playlist as they are.
newItems.Shuffle(); SortedPlaylist.InsertRange(sortedPlayingItemIndex + 1, newItems);
ShuffledPlaylist.InsertRange(PlayingItemIndex + 1, newItems); ShuffledPlaylist.InsertRange(PlayingItemIndex + 1, newItems);
} }
else else
@ -281,16 +321,10 @@ namespace MediaBrowser.Controller.SyncPlay
/// <returns>The playlist identifier of the playing item.</returns> /// <returns>The playlist identifier of the playing item.</returns>
public string GetPlayingItemPlaylistId() public string GetPlayingItemPlaylistId()
{ {
if (PlayingItemIndex < 0) var playingItem = GetPlayingItem();
if (playingItem != null)
{ {
return null; return playingItem.PlaylistItemId;
}
var list = GetPlaylistAsList();
if (list.Count() > 0)
{
return list[PlayingItemIndex].PlaylistItemId;
} }
else else
{ {
@ -304,16 +338,10 @@ namespace MediaBrowser.Controller.SyncPlay
/// <returns>The playing item identifier.</returns> /// <returns>The playing item identifier.</returns>
public Guid GetPlayingItemId() public Guid GetPlayingItemId()
{ {
if (PlayingItemIndex < 0) var playingItem = GetPlayingItem();
if (playingItem != null)
{ {
return Guid.Empty; return playingItem.ItemId;
}
var list = GetPlaylistAsList();
if (list.Count() > 0)
{
return list[PlayingItemIndex].ItemId;
} }
else else
{ {
@ -342,7 +370,7 @@ namespace MediaBrowser.Controller.SyncPlay
var playlistIds = GetPlaylistAsList().Select(queueItem => queueItem.PlaylistItemId).ToList(); var playlistIds = GetPlaylistAsList().Select(queueItem => queueItem.PlaylistItemId).ToList();
PlayingItemIndex = playlistIds.IndexOf(playlistItemId); PlayingItemIndex = playlistIds.IndexOf(playlistItemId);
LastChange = DateTime.UtcNow; LastChange = DateTime.UtcNow;
return PlayingItemIndex != -1; return PlayingItemIndex != NoPlayingItemIndex;
} }
/// <summary> /// <summary>
@ -354,7 +382,7 @@ namespace MediaBrowser.Controller.SyncPlay
var list = GetPlaylistAsList(); var list = GetPlaylistAsList();
if (playlistIndex < 0 || playlistIndex > list.Count()) if (playlistIndex < 0 || playlistIndex > list.Count())
{ {
PlayingItemIndex = -1; PlayingItemIndex = NoPlayingItemIndex;
} }
else else
{ {
@ -371,13 +399,9 @@ namespace MediaBrowser.Controller.SyncPlay
/// <returns><c>true</c> if playing item got removed; <c>false</c> otherwise.</returns> /// <returns><c>true</c> if playing item got removed; <c>false</c> otherwise.</returns>
public bool RemoveFromPlaylist(string[] playlistItemIds) public bool RemoveFromPlaylist(string[] playlistItemIds)
{ {
var playingItem = SortedPlaylist[PlayingItemIndex]; var playingItem = GetPlayingItem();
if (ShuffleMode.Equals(GroupShuffleMode.Shuffle))
{
playingItem = ShuffledPlaylist[PlayingItemIndex];
}
var playlistItemIdsList = playlistItemIds.ToList(); var playlistItemIdsList = playlistItemIds.ToList();
SortedPlaylist.RemoveAll(item => playlistItemIdsList.Contains(item.PlaylistItemId)); SortedPlaylist.RemoveAll(item => playlistItemIdsList.Contains(item.PlaylistItemId));
ShuffledPlaylist.RemoveAll(item => playlistItemIdsList.Contains(item.PlaylistItemId)); ShuffledPlaylist.RemoveAll(item => playlistItemIdsList.Contains(item.PlaylistItemId));
@ -392,7 +416,8 @@ namespace MediaBrowser.Controller.SyncPlay
if (PlayingItemIndex < 0) if (PlayingItemIndex < 0)
{ {
// Was first element, picking next if available. // Was first element, picking next if available.
PlayingItemIndex = SortedPlaylist.Count() > 0 ? 0 : -1; // Default to no playing item otherwise.
PlayingItemIndex = SortedPlaylist.Count() > 0 ? 0 : NoPlayingItemIndex;
} }
return true; return true;
@ -419,18 +444,19 @@ namespace MediaBrowser.Controller.SyncPlay
public bool MovePlaylistItem(string playlistItemId, int newIndex) public bool MovePlaylistItem(string playlistItemId, int newIndex)
{ {
var list = GetPlaylistAsList(); var list = GetPlaylistAsList();
var playingItem = list[PlayingItemIndex]; var playingItem = GetPlayingItem();
var playlistIds = list.Select(queueItem => queueItem.PlaylistItemId).ToList(); var playlistIds = list.Select(queueItem => queueItem.PlaylistItemId).ToList();
var oldIndex = playlistIds.IndexOf(playlistItemId); var oldIndex = playlistIds.IndexOf(playlistItemId);
if (oldIndex < 0) { if (oldIndex < 0)
{
return false; return false;
} }
var queueItem = list[oldIndex]; var queueItem = list[oldIndex];
list.RemoveAt(oldIndex); list.RemoveAt(oldIndex);
newIndex = newIndex > list.Count() ? list.Count() : newIndex; newIndex = Math.Min(newIndex, list.Count());
newIndex = newIndex < 0 ? 0 : newIndex; newIndex = Math.Max(newIndex, 0);
list.Insert(newIndex, queueItem); list.Insert(newIndex, queueItem);
LastChange = DateTime.UtcNow; LastChange = DateTime.UtcNow;
@ -446,7 +472,7 @@ namespace MediaBrowser.Controller.SyncPlay
ProgressiveId = 0; ProgressiveId = 0;
SortedPlaylist.Clear(); SortedPlaylist.Clear();
ShuffledPlaylist.Clear(); ShuffledPlaylist.Clear();
PlayingItemIndex = -1; PlayingItemIndex = NoPlayingItemIndex;
ShuffleMode = GroupShuffleMode.Sorted; ShuffleMode = GroupShuffleMode.Sorted;
RepeatMode = GroupRepeatMode.RepeatNone; RepeatMode = GroupRepeatMode.RepeatNone;
LastChange = DateTime.UtcNow; LastChange = DateTime.UtcNow;
@ -486,7 +512,7 @@ namespace MediaBrowser.Controller.SyncPlay
ShufflePlaylist(); ShufflePlaylist();
break; break;
default: default:
SortShuffledPlaylist(); RestoreSortedPlaylist();
break; break;
} }
} }