aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller/SyncPlay/Queue/PlayQueueManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Controller/SyncPlay/Queue/PlayQueueManager.cs')
-rw-r--r--MediaBrowser.Controller/SyncPlay/Queue/PlayQueueManager.cs315
1 files changed, 180 insertions, 135 deletions
diff --git a/MediaBrowser.Controller/SyncPlay/Queue/PlayQueueManager.cs b/MediaBrowser.Controller/SyncPlay/Queue/PlayQueueManager.cs
index 030005abe..8bc21a6a8 100644
--- a/MediaBrowser.Controller/SyncPlay/Queue/PlayQueueManager.cs
+++ b/MediaBrowser.Controller/SyncPlay/Queue/PlayQueueManager.cs
@@ -5,163 +5,96 @@ using MediaBrowser.Model.SyncPlay;
namespace MediaBrowser.Controller.SyncPlay
{
- static class ListShuffleExtension
- {
- private static Random rng = new Random();
- public static void Shuffle<T>(this IList<T> list)
- {
- int n = list.Count;
- while (n > 1)
- {
- n--;
- int k = rng.Next(n + 1);
- T value = list[k];
- list[k] = list[n];
- list[n] = value;
- }
- }
- }
-
/// <summary>
/// Class PlayQueueManager.
/// </summary>
public class PlayQueueManager
{
/// <summary>
- /// Gets or sets the playing item index.
+ /// Placeholder index for when no item is playing.
/// </summary>
- /// <value>The playing item index.</value>
- public int PlayingItemIndex { get; private set; }
+ /// <value>The no-playing item index.</value>
+ private const int NoPlayingItemIndex = -1;
/// <summary>
- /// Gets or sets the last time the queue has been changed.
+ /// Random number generator used to shuffle lists.
/// </summary>
- /// <value>The last time the queue has been changed.</value>
- public DateTime LastChange { get; private set; }
+ /// <value>The random number generator.</value>
+ private readonly Random randomNumberGenerator = new Random();
/// <summary>
- /// Gets the sorted playlist.
+ /// Initializes a new instance of the <see cref="PlayQueueManager" /> class.
/// </summary>
- /// <value>The sorted playlist, or play queue of the group.</value>
- private List<QueueItem> SortedPlaylist { get; set; } = new List<QueueItem>();
+ public PlayQueueManager()
+ {
+ Reset();
+ }
/// <summary>
- /// Gets the shuffled playlist.
+ /// Gets the playing item index.
/// </summary>
- /// <value>The shuffled playlist, or play queue of the group.</value>
- private List<QueueItem> ShuffledPlaylist { get; set; } = new List<QueueItem>();
+ /// <value>The playing item index.</value>
+ public int PlayingItemIndex { get; private set; }
/// <summary>
- /// Gets or sets the shuffle mode.
+ /// Gets the last time the queue has been changed.
+ /// </summary>
+ /// <value>The last time the queue has been changed.</value>
+ public DateTime LastChange { get; private set; }
+
+ /// <summary>
+ /// Gets the shuffle mode.
/// </summary>
/// <value>The shuffle mode.</value>
public GroupShuffleMode ShuffleMode { get; private set; } = GroupShuffleMode.Sorted;
/// <summary>
- /// Gets or sets the repeat mode.
+ /// Gets the repeat mode.
/// </summary>
/// <value>The repeat mode.</value>
public GroupRepeatMode RepeatMode { get; private set; } = GroupRepeatMode.RepeatNone;
/// <summary>
- /// Gets or sets the progressive identifier counter.
+ /// Gets or sets the sorted playlist.
/// </summary>
- /// <value>The progressive identifier.</value>
- private int ProgressiveId { get; set; } = 0;
-
- /// <summary>
- /// Placeholder index for when no item is playing.
- /// </summary>
- /// <value>The no-playing item index.</value>
- private const int NoPlayingItemIndex = -1;
+ /// <value>The sorted playlist, or play queue of the group.</value>
+ private List<QueueItem> SortedPlaylist { get; set; } = new List<QueueItem>();
/// <summary>
- /// Initializes a new instance of the <see cref="PlayQueueManager" /> class.
+ /// Gets or sets the shuffled playlist.
/// </summary>
- public PlayQueueManager()
- {
- Reset();
- }
+ /// <value>The shuffled playlist, or play queue of the group.</value>
+ private List<QueueItem> ShuffledPlaylist { get; set; } = new List<QueueItem>();
/// <summary>
- /// Gets the next available identifier.
+ /// Gets or sets the progressive identifier counter.
/// </summary>
- /// <returns>The next available identifier.</returns>
- private int GetNextProgressiveId() {
- return ProgressiveId++;
- }
+ /// <value>The progressive identifier.</value>
+ private int ProgressiveId { get; set; }
/// <summary>
- /// Creates a list from the array of items. Each item is given an unique playlist identifier.
+ /// Checks if an item is playing.
/// </summary>
- /// <returns>The list of queue items.</returns>
- private List<QueueItem> CreateQueueItemsFromArray(Guid[] items)
+ /// <returns><c>true</c> if an item is playing; <c>false</c> otherwise.</returns>
+ public bool IsItemPlaying()
{
- return items.ToList()
- .Select(item => new QueueItem()
- {
- ItemId = item,
- PlaylistItemId = "syncPlayItem" + GetNextProgressiveId()
- })
- .ToList();
+ return PlayingItemIndex != NoPlayingItemIndex;
}
/// <summary>
- /// Gets the current playlist, depending on the shuffle mode.
+ /// Gets the current playlist considering the shuffle mode.
/// </summary>
/// <returns>The playlist.</returns>
- private List<QueueItem> GetPlaylistAsList()
+ public IReadOnlyList<QueueItem> GetPlaylist()
{
- if (ShuffleMode.Equals(GroupShuffleMode.Shuffle))
- {
- return ShuffledPlaylist;
- }
- else
- {
- return SortedPlaylist;
- }
- }
-
- /// <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>
- /// Gets the current playlist as an array, depending on the shuffle mode.
- /// </summary>
- /// <returns>The array of items in the playlist.</returns>
- public QueueItem[] GetPlaylist() {
- if (ShuffleMode.Equals(GroupShuffleMode.Shuffle))
- {
- return ShuffledPlaylist.ToArray();
- }
- else
- {
- return SortedPlaylist.ToArray();
- }
+ return GetPlaylistInternal();
}
/// <summary>
/// Sets a new playlist. Playing item is reset.
/// </summary>
/// <param name="items">The new items of the playlist.</param>
- public void SetPlaylist(Guid[] items)
+ public void SetPlaylist(IEnumerable<Guid> items)
{
SortedPlaylist.Clear();
ShuffledPlaylist.Clear();
@@ -170,7 +103,7 @@ namespace MediaBrowser.Controller.SyncPlay
if (ShuffleMode.Equals(GroupShuffleMode.Shuffle))
{
ShuffledPlaylist = SortedPlaylist.ToList();
- ShuffledPlaylist.Shuffle();
+ Shuffle(ShuffledPlaylist);
}
PlayingItemIndex = NoPlayingItemIndex;
@@ -181,7 +114,7 @@ namespace MediaBrowser.Controller.SyncPlay
/// Appends new items to the playlist. The specified order is mantained.
/// </summary>
/// <param name="items">The items to add to the playlist.</param>
- public void Queue(Guid[] items)
+ public void Queue(IEnumerable<Guid> items)
{
var newItems = CreateQueueItemsFromArray(items);
@@ -195,13 +128,14 @@ namespace MediaBrowser.Controller.SyncPlay
}
/// <summary>
- /// Shuffles the playlist. Shuffle mode is changed.
+ /// Shuffles the playlist. Shuffle mode is changed. The playlist gets re-shuffled if already shuffled.
/// </summary>
public void ShufflePlaylist()
{
- if (PlayingItemIndex == NoPlayingItemIndex) {
+ if (PlayingItemIndex == NoPlayingItemIndex)
+ {
ShuffledPlaylist = SortedPlaylist.ToList();
- ShuffledPlaylist.Shuffle();
+ Shuffle(ShuffledPlaylist);
}
else if (ShuffleMode.Equals(GroupShuffleMode.Sorted))
{
@@ -209,7 +143,7 @@ namespace MediaBrowser.Controller.SyncPlay
var playingItem = SortedPlaylist[PlayingItemIndex];
ShuffledPlaylist = SortedPlaylist.ToList();
ShuffledPlaylist.RemoveAt(PlayingItemIndex);
- ShuffledPlaylist.Shuffle();
+ Shuffle(ShuffledPlaylist);
ShuffledPlaylist = ShuffledPlaylist.Prepend(playingItem).ToList();
PlayingItemIndex = 0;
}
@@ -218,7 +152,7 @@ namespace MediaBrowser.Controller.SyncPlay
// Re-shuffle playlist.
var playingItem = ShuffledPlaylist[PlayingItemIndex];
ShuffledPlaylist.RemoveAt(PlayingItemIndex);
- ShuffledPlaylist.Shuffle();
+ Shuffle(ShuffledPlaylist);
ShuffledPlaylist = ShuffledPlaylist.Prepend(playingItem).ToList();
PlayingItemIndex = 0;
}
@@ -262,6 +196,7 @@ namespace MediaBrowser.Controller.SyncPlay
{
ShuffledPlaylist.Add(playingItem);
}
+
PlayingItemIndex = 0;
}
else
@@ -274,7 +209,7 @@ namespace MediaBrowser.Controller.SyncPlay
/// Adds new items to the playlist right after the playing item. The specified order is mantained.
/// </summary>
/// <param name="items">The items to add to the playlist.</param>
- public void QueueNext(Guid[] items)
+ public void QueueNext(IEnumerable<Guid> items)
{
var newItems = CreateQueueItemsFromArray(items);
@@ -334,8 +269,18 @@ namespace MediaBrowser.Controller.SyncPlay
/// <param name="itemId">The new playing item identifier.</param>
public void SetPlayingItemById(Guid itemId)
{
- var itemIds = GetPlaylistAsList().Select(queueItem => queueItem.ItemId).ToList();
- PlayingItemIndex = itemIds.IndexOf(itemId);
+ PlayingItemIndex = NoPlayingItemIndex;
+
+ var playlist = GetPlaylistInternal();
+ foreach (var item in playlist)
+ {
+ if (item.ItemId.Equals(itemId))
+ {
+ PlayingItemIndex = playlist.IndexOf(item);
+ break;
+ }
+ }
+
LastChange = DateTime.UtcNow;
}
@@ -346,8 +291,18 @@ namespace MediaBrowser.Controller.SyncPlay
/// <returns><c>true</c> if playing item has been set; <c>false</c> if item is not in the playlist.</returns>
public bool SetPlayingItemByPlaylistId(string playlistItemId)
{
- var playlistIds = GetPlaylistAsList().Select(queueItem => queueItem.PlaylistItemId).ToList();
- PlayingItemIndex = playlistIds.IndexOf(playlistItemId);
+ PlayingItemIndex = NoPlayingItemIndex;
+
+ var playlist = GetPlaylistInternal();
+ foreach (var item in playlist)
+ {
+ if (item.PlaylistItemId.Equals(playlistItemId, StringComparison.OrdinalIgnoreCase))
+ {
+ PlayingItemIndex = playlist.IndexOf(item);
+ break;
+ }
+ }
+
LastChange = DateTime.UtcNow;
return PlayingItemIndex != NoPlayingItemIndex;
}
@@ -358,8 +313,8 @@ namespace MediaBrowser.Controller.SyncPlay
/// <param name="playlistIndex">The new playing item index.</param>
public void SetPlayingItemByIndex(int playlistIndex)
{
- var list = GetPlaylistAsList();
- if (playlistIndex < 0 || playlistIndex > list.Count())
+ var playlist = GetPlaylistInternal();
+ if (playlistIndex < 0 || playlistIndex > playlist.Count)
{
PlayingItemIndex = NoPlayingItemIndex;
}
@@ -376,7 +331,7 @@ namespace MediaBrowser.Controller.SyncPlay
/// </summary>
/// <param name="playlistItemIds">The items to remove.</param>
/// <returns><c>true</c> if playing item got removed; <c>false</c> otherwise.</returns>
- public bool RemoveFromPlaylist(string[] playlistItemIds)
+ public bool RemoveFromPlaylist(IEnumerable<string> playlistItemIds)
{
var playingItem = GetPlayingItem();
var playlistItemIdsList = playlistItemIds.ToList();
@@ -396,7 +351,7 @@ namespace MediaBrowser.Controller.SyncPlay
{
// Was first element, picking next if available.
// Default to no playing item otherwise.
- PlayingItemIndex = SortedPlaylist.Count() > 0 ? 0 : NoPlayingItemIndex;
+ PlayingItemIndex = SortedPlaylist.Count > 0 ? 0 : NoPlayingItemIndex;
}
return true;
@@ -422,24 +377,32 @@ namespace MediaBrowser.Controller.SyncPlay
/// <returns><c>true</c> if the item has been moved; <c>false</c> otherwise.</returns>
public bool MovePlaylistItem(string playlistItemId, int newIndex)
{
- var list = GetPlaylistAsList();
+ var playlist = GetPlaylistInternal();
var playingItem = GetPlayingItem();
- var playlistIds = list.Select(queueItem => queueItem.PlaylistItemId).ToList();
- var oldIndex = playlistIds.IndexOf(playlistItemId);
+ var oldIndex = -1;
+ foreach (var item in playlist)
+ {
+ if (item.PlaylistItemId.Equals(playlistItemId, StringComparison.OrdinalIgnoreCase))
+ {
+ oldIndex = playlist.IndexOf(item);
+ break;
+ }
+ }
+
if (oldIndex < 0)
{
return false;
}
- var queueItem = list[oldIndex];
- list.RemoveAt(oldIndex);
- newIndex = Math.Min(newIndex, list.Count());
+ var queueItem = playlist[oldIndex];
+ playlist.RemoveAt(oldIndex);
+ newIndex = Math.Min(newIndex, playlist.Count);
newIndex = Math.Max(newIndex, 0);
- list.Insert(newIndex, queueItem);
+ playlist.Insert(newIndex, queueItem);
LastChange = DateTime.UtcNow;
- PlayingItemIndex = list.IndexOf(playingItem);
+ PlayingItemIndex = playlist.IndexOf(playingItem);
return true;
}
@@ -505,7 +468,7 @@ namespace MediaBrowser.Controller.SyncPlay
public QueueItem GetNextItemPlaylistId()
{
int newIndex;
- var playlist = GetPlaylistAsList();
+ var playlist = GetPlaylistInternal();
switch (RepeatMode)
{
@@ -514,17 +477,18 @@ namespace MediaBrowser.Controller.SyncPlay
break;
case GroupRepeatMode.RepeatAll:
newIndex = PlayingItemIndex + 1;
- if (newIndex >= playlist.Count())
+ if (newIndex >= playlist.Count)
{
newIndex = 0;
}
+
break;
default:
newIndex = PlayingItemIndex + 1;
break;
}
- if (newIndex < 0 || newIndex >= playlist.Count())
+ if (newIndex < 0 || newIndex >= playlist.Count)
{
return null;
}
@@ -545,7 +509,7 @@ namespace MediaBrowser.Controller.SyncPlay
}
PlayingItemIndex++;
- if (PlayingItemIndex >= SortedPlaylist.Count())
+ if (PlayingItemIndex >= SortedPlaylist.Count)
{
if (RepeatMode.Equals(GroupRepeatMode.RepeatAll))
{
@@ -579,7 +543,7 @@ namespace MediaBrowser.Controller.SyncPlay
{
if (RepeatMode.Equals(GroupRepeatMode.RepeatAll))
{
- PlayingItemIndex = SortedPlaylist.Count() - 1;
+ PlayingItemIndex = SortedPlaylist.Count - 1;
}
else
{
@@ -591,5 +555,86 @@ namespace MediaBrowser.Controller.SyncPlay
LastChange = DateTime.UtcNow;
return true;
}
+
+ /// <summary>
+ /// Shuffles a given list.
+ /// </summary>
+ /// <param name="list">The list to shuffle.</param>
+ private void Shuffle<T>(IList<T> list)
+ {
+ int n = list.Count;
+ while (n > 1)
+ {
+ n--;
+ int k = randomNumberGenerator.Next(n + 1);
+ T value = list[k];
+ list[k] = list[n];
+ list[n] = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets the next available identifier.
+ /// </summary>
+ /// <returns>The next available identifier.</returns>
+ private int GetNextProgressiveId()
+ {
+ return ProgressiveId++;
+ }
+
+ /// <summary>
+ /// Creates a list from the array of items. Each item is given an unique playlist identifier.
+ /// </summary>
+ /// <returns>The list of queue items.</returns>
+ private List<QueueItem> CreateQueueItemsFromArray(IEnumerable<Guid> items)
+ {
+ var list = new List<QueueItem>();
+ foreach (var item in items)
+ {
+ list.Add(new QueueItem()
+ {
+ ItemId = item,
+ PlaylistItemId = "syncPlayItem" + GetNextProgressiveId()
+ });
+ }
+
+ return list;
+ }
+
+ /// <summary>
+ /// Gets the current playlist considering the shuffle mode.
+ /// </summary>
+ /// <returns>The playlist.</returns>
+ private List<QueueItem> GetPlaylistInternal()
+ {
+ if (ShuffleMode.Equals(GroupShuffleMode.Shuffle))
+ {
+ return ShuffledPlaylist;
+ }
+ else
+ {
+ return SortedPlaylist;
+ }
+ }
+
+ /// <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];
+ }
+ }
}
}