aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2013-09-24 11:08:51 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2013-09-24 11:08:51 -0400
commitb49764dbaafbbf11b6308ec675355696b9e58379 (patch)
tree58677308bf98c95f1982a84eb403a01241f0a692
parent14c464c28a3b9cac207ef741711e31cef1c15378 (diff)
fixes #555 - Have clients report seek and queuing capabilities
-rw-r--r--MediaBrowser.Api/UserLibrary/UserLibraryService.cs37
-rw-r--r--MediaBrowser.Common.Implementations/Logging/NlogManager.cs18
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs37
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerTask.cs6
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs5
-rw-r--r--MediaBrowser.Controller/MediaBrowser.Controller.csproj1
-rw-r--r--MediaBrowser.Controller/Session/ISessionManager.cs7
-rw-r--r--MediaBrowser.Controller/Session/PlaybackInfo.cs38
-rw-r--r--MediaBrowser.Controller/Session/SessionInfo.cs13
-rw-r--r--MediaBrowser.Model/ApiClient/IApiClient.cs4
-rw-r--r--MediaBrowser.Model/Session/SessionInfoDto.cs17
-rw-r--r--MediaBrowser.Providers/Movies/FanArtMovieProvider.cs1
-rw-r--r--MediaBrowser.Providers/Music/SoundtrackPostScanTask.cs4
-rw-r--r--MediaBrowser.Providers/TV/SeriesPostScanTask.cs4
-rw-r--r--MediaBrowser.Server.Implementations/Dto/DtoService.cs4
-rw-r--r--MediaBrowser.Server.Implementations/Library/LibraryManager.cs54
-rw-r--r--MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs4
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs15
-rw-r--r--MediaBrowser.Server.Implementations/Session/SessionManager.cs22
-rw-r--r--MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs52
-rw-r--r--MediaBrowser.Server.Implementations/WebSocket/AlchemyWebSocket.cs4
-rw-r--r--MediaBrowser.WebDashboard/ApiClient.js15
-rw-r--r--MediaBrowser.WebDashboard/packages.config2
23 files changed, 248 insertions, 116 deletions
diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
index ab3e2af19..9085a3ecf 100644
--- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
+++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
@@ -186,7 +186,7 @@ namespace MediaBrowser.Api.UserLibrary
[ApiMember(Name = "DatePlayed", Description = "The date the item was played (if any)", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
public DateTime? DatePlayed { get; set; }
-
+
/// <summary>
/// Gets or sets the id.
/// </summary>
@@ -224,6 +224,13 @@ namespace MediaBrowser.Api.UserLibrary
[Api(Description = "Reports that a user has begun playing an item")]
public class OnPlaybackStart : IReturnVoid
{
+ public OnPlaybackStart()
+ {
+ // Have to default these until all clients have a chance to incorporate them
+ CanSeek = true;
+ QueueableMediaTypes = "Audio,Video,Book,Game";
+ }
+
/// <summary>
/// Gets or sets the user id.
/// </summary>
@@ -237,6 +244,20 @@ namespace MediaBrowser.Api.UserLibrary
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
public string Id { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether this <see cref="UpdateUserItemRating" /> is likes.
+ /// </summary>
+ /// <value><c>true</c> if likes; otherwise, <c>false</c>.</value>
+ [ApiMember(Name = "CanSeek", Description = "Indicates if the client can seek", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "POST")]
+ public bool CanSeek { get; set; }
+
+ /// <summary>
+ /// Gets or sets the id.
+ /// </summary>
+ /// <value>The id.</value>
+ [ApiMember(Name = "QueueableMediaTypes", Description = "A list of media types that can be queued from this item, comma delimited. Audio,Video,Book,Game", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST", AllowMultiple = true)]
+ public string QueueableMediaTypes { get; set; }
}
/// <summary>
@@ -378,6 +399,8 @@ namespace MediaBrowser.Api.UserLibrary
/// <param name="libraryManager">The library manager.</param>
/// <param name="userDataRepository">The user data repository.</param>
/// <param name="itemRepo">The item repo.</param>
+ /// <param name="sessionManager">The session manager.</param>
+ /// <param name="dtoService">The dto service.</param>
/// <exception cref="System.ArgumentNullException">jsonSerializer</exception>
public UserLibraryService(IUserManager userManager, ILibraryManager libraryManager, IUserDataRepository userDataRepository, IItemRepository itemRepo, ISessionManager sessionManager, IDtoService dtoService)
{
@@ -665,7 +688,17 @@ namespace MediaBrowser.Api.UserLibrary
var item = _dtoService.GetItemByDtoId(request.Id, user.Id);
- _sessionManager.OnPlaybackStart(item, GetSession().Id);
+ var queueableMediaTypes = (request.QueueableMediaTypes ?? string.Empty);
+
+ var info = new PlaybackInfo
+ {
+ CanSeek = request.CanSeek,
+ Item = item,
+ SessionId = GetSession().Id,
+ QueueableMediaTypes = queueableMediaTypes.Split(',').ToList()
+ };
+
+ _sessionManager.OnPlaybackStart(info);
}
/// <summary>
diff --git a/MediaBrowser.Common.Implementations/Logging/NlogManager.cs b/MediaBrowser.Common.Implementations/Logging/NlogManager.cs
index 109e85d80..e20f9bc13 100644
--- a/MediaBrowser.Common.Implementations/Logging/NlogManager.cs
+++ b/MediaBrowser.Common.Implementations/Logging/NlogManager.cs
@@ -5,7 +5,6 @@ using NLog.Targets;
using System;
using System.IO;
using System.Linq;
-using System.Threading.Tasks;
namespace MediaBrowser.Common.Implementations.Logging
{
@@ -193,17 +192,14 @@ namespace MediaBrowser.Common.Implementations.Logging
if (LoggerLoaded != null)
{
- Task.Run(() =>
+ try
{
- try
- {
- LoggerLoaded(this, EventArgs.Empty);
- }
- catch (Exception ex)
- {
- GetLogger("Logger").ErrorException("Error in LoggerLoaded event", ex);
- }
- });
+ LoggerLoaded(this, EventArgs.Empty);
+ }
+ catch (Exception ex)
+ {
+ GetLogger("Logger").ErrorException("Error in LoggerLoaded event", ex);
+ }
}
}
}
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs
index 15f955723..bfd626adb 100644
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs
@@ -54,33 +54,32 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
/// <returns>Task.</returns>
public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
{
- return Task.Run(() =>
- {
- // Delete log files more than n days old
- var minDateModified = DateTime.UtcNow.AddDays(-(ConfigurationManager.CommonConfiguration.LogFileRetentionDays));
+ // Delete log files more than n days old
+ var minDateModified = DateTime.UtcNow.AddDays(-(ConfigurationManager.CommonConfiguration.LogFileRetentionDays));
+
+ var filesToDelete = new DirectoryInfo(ConfigurationManager.CommonApplicationPaths.LogDirectoryPath).EnumerateFileSystemInfos("*", SearchOption.AllDirectories)
+ .Where(f => f.LastWriteTimeUtc < minDateModified)
+ .ToList();
- var filesToDelete = new DirectoryInfo(ConfigurationManager.CommonApplicationPaths.LogDirectoryPath).EnumerateFileSystemInfos("*", SearchOption.AllDirectories)
- .Where(f => f.LastWriteTimeUtc < minDateModified)
- .ToList();
+ var index = 0;
- var index = 0;
+ foreach (var file in filesToDelete)
+ {
+ double percent = index;
+ percent /= filesToDelete.Count;
- foreach (var file in filesToDelete)
- {
- double percent = index;
- percent /= filesToDelete.Count;
+ progress.Report(100 * percent);
- progress.Report(100 * percent);
+ cancellationToken.ThrowIfCancellationRequested();
- cancellationToken.ThrowIfCancellationRequested();
+ File.Delete(file.FullName);
- File.Delete(file.FullName);
+ index++;
+ }
- index++;
- }
+ progress.Report(100);
- progress.Report(100);
- });
+ return Task.FromResult(true);
}
/// <summary>
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerTask.cs
index e860834ec..00928255c 100644
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerTask.cs
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerTask.cs
@@ -58,7 +58,11 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
progress.Report(0);
- return Task.Run(() => LogManager.ReloadLogger(ConfigurationManager.CommonConfiguration.EnableDebugLevelLogging ? LogSeverity.Debug : LogSeverity.Info));
+ LogManager.ReloadLogger(ConfigurationManager.CommonConfiguration.EnableDebugLevelLogging
+ ? LogSeverity.Debug
+ : LogSeverity.Info);
+
+ return Task.FromResult(true);
}
/// <summary>
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index 326d30bd7..0f090f587 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -16,7 +16,6 @@ using System.Linq;
using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
-using MoreLinq;
namespace MediaBrowser.Controller.Entities
{
@@ -690,7 +689,7 @@ namespace MediaBrowser.Controller.Entities
var options = new ParallelOptions
{
- MaxDegreeOfParallelism = 20
+ MaxDegreeOfParallelism = 10
};
Parallel.ForEach(nonCachedChildren, options, child =>
@@ -805,7 +804,7 @@ namespace MediaBrowser.Controller.Entities
foreach (var tuple in list)
{
- if (tasks.Count > 8)
+ if (tasks.Count > 5)
{
await Task.WhenAll(tasks).ConfigureAwait(false);
}
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index f49bd8cf0..80cf82da1 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -165,6 +165,7 @@
<Compile Include="Kernel.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Providers\BaseMetadataProvider.cs" />
+ <Compile Include="Session\PlaybackInfo.cs" />
<Compile Include="Session\SessionInfo.cs" />
<Compile Include="Sorting\IBaseItemComparer.cs" />
<Compile Include="Sorting\IUserBaseItemComparer.cs" />
diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs
index 1976c653a..fba1d26e8 100644
--- a/MediaBrowser.Controller/Session/ISessionManager.cs
+++ b/MediaBrowser.Controller/Session/ISessionManager.cs
@@ -47,11 +47,9 @@ namespace MediaBrowser.Controller.Session
/// <summary>
/// Used to report that playback has started for an item
/// </summary>
- /// <param name="item">The item.</param>
- /// <param name="sessionId">The session id.</param>
+ /// <param name="info">The info.</param>
/// <returns>Task.</returns>
- /// <exception cref="System.ArgumentNullException"></exception>
- Task OnPlaybackStart(BaseItem item, Guid sessionId);
+ Task OnPlaybackStart(PlaybackInfo info);
/// <summary>
/// Used to report playback progress for an item
@@ -59,6 +57,7 @@ namespace MediaBrowser.Controller.Session
/// <param name="item">The item.</param>
/// <param name="positionTicks">The position ticks.</param>
/// <param name="isPaused">if set to <c>true</c> [is paused].</param>
+ /// <param name="isMuted">if set to <c>true</c> [is muted].</param>
/// <param name="sessionId">The session id.</param>
/// <returns>Task.</returns>
/// <exception cref="System.ArgumentNullException"></exception>
diff --git a/MediaBrowser.Controller/Session/PlaybackInfo.cs b/MediaBrowser.Controller/Session/PlaybackInfo.cs
new file mode 100644
index 000000000..ab3111e76
--- /dev/null
+++ b/MediaBrowser.Controller/Session/PlaybackInfo.cs
@@ -0,0 +1,38 @@
+using MediaBrowser.Controller.Entities;
+using System;
+using System.Collections.Generic;
+
+namespace MediaBrowser.Controller.Session
+{
+ public class PlaybackInfo
+ {
+ public PlaybackInfo()
+ {
+ QueueableMediaTypes = new List<string>();
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether this instance can seek.
+ /// </summary>
+ /// <value><c>true</c> if this instance can seek; otherwise, <c>false</c>.</value>
+ public bool CanSeek { get; set; }
+
+ /// <summary>
+ /// Gets or sets the queueable media types.
+ /// </summary>
+ /// <value>The queueable media types.</value>
+ public List<string> QueueableMediaTypes { get; set; }
+
+ /// <summary>
+ /// Gets or sets the item.
+ /// </summary>
+ /// <value>The item.</value>
+ public BaseItem Item { get; set; }
+
+ /// <summary>
+ /// Gets or sets the session id.
+ /// </summary>
+ /// <value>The session id.</value>
+ public Guid SessionId { get; set; }
+ }
+}
diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs
index 6c0f1a085..ba6d3d0ac 100644
--- a/MediaBrowser.Controller/Session/SessionInfo.cs
+++ b/MediaBrowser.Controller/Session/SessionInfo.cs
@@ -15,9 +15,22 @@ namespace MediaBrowser.Controller.Session
public SessionInfo()
{
WebSockets = new List<IWebSocketConnection>();
+ QueueableMediaTypes = new List<string>();
}
/// <summary>
+ /// Gets or sets a value indicating whether this instance can seek.
+ /// </summary>
+ /// <value><c>true</c> if this instance can seek; otherwise, <c>false</c>.</value>
+ public bool CanSeek { get; set; }
+
+ /// <summary>
+ /// Gets or sets the queueable media types.
+ /// </summary>
+ /// <value>The queueable media types.</value>
+ public List<string> QueueableMediaTypes { get; set; }
+
+ /// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs
index 03ea79b3b..4a459cac8 100644
--- a/MediaBrowser.Model/ApiClient/IApiClient.cs
+++ b/MediaBrowser.Model/ApiClient/IApiClient.cs
@@ -497,9 +497,11 @@ namespace MediaBrowser.Model.ApiClient
/// </summary>
/// <param name="itemId">The item id.</param>
/// <param name="userId">The user id.</param>
+ /// <param name="isSeekable">if set to <c>true</c> [is seekable].</param>
+ /// <param name="queueableMediaTypes">The list of media types that the client is capable of queuing onto the playlist. See MediaType class.</param>
/// <returns>Task{UserItemDataDto}.</returns>
/// <exception cref="ArgumentNullException">itemId</exception>
- Task ReportPlaybackStartAsync(string itemId, string userId);
+ Task ReportPlaybackStartAsync(string itemId, string userId, bool isSeekable, List<string> queueableMediaTypes);
/// <summary>
/// Reports playback progress to the server
diff --git a/MediaBrowser.Model/Session/SessionInfoDto.cs b/MediaBrowser.Model/Session/SessionInfoDto.cs
index f9b0e0abd..02b7f0226 100644
--- a/MediaBrowser.Model/Session/SessionInfoDto.cs
+++ b/MediaBrowser.Model/Session/SessionInfoDto.cs
@@ -1,12 +1,25 @@
-using System.ComponentModel;
-using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Entities;
using System;
+using System.Collections.Generic;
+using System.ComponentModel;
namespace MediaBrowser.Model.Session
{
public class SessionInfoDto : INotifyPropertyChanged
{
/// <summary>
+ /// Gets or sets a value indicating whether this instance can seek.
+ /// </summary>
+ /// <value><c>true</c> if this instance can seek; otherwise, <c>false</c>.</value>
+ public bool CanSeek { get; set; }
+
+ /// <summary>
+ /// Gets or sets the queueable media types.
+ /// </summary>
+ /// <value>The queueable media types.</value>
+ public List<string> QueueableMediaTypes { get; set; }
+
+ /// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
diff --git a/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs b/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs
index fefcd8371..adc013699 100644
--- a/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs
+++ b/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs
@@ -1,5 +1,4 @@
using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
diff --git a/MediaBrowser.Providers/Music/SoundtrackPostScanTask.cs b/MediaBrowser.Providers/Music/SoundtrackPostScanTask.cs
index 18868d3ea..e18351248 100644
--- a/MediaBrowser.Providers/Music/SoundtrackPostScanTask.cs
+++ b/MediaBrowser.Providers/Music/SoundtrackPostScanTask.cs
@@ -23,7 +23,9 @@ namespace MediaBrowser.Providers.Music
public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
{
- return Task.Run(() => RunInternal(progress, cancellationToken));
+ RunInternal(progress, cancellationToken);
+
+ return Task.FromResult(true);
}
private void RunInternal(IProgress<double> progress, CancellationToken cancellationToken)
diff --git a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs
index a781551de..2b73ba1f7 100644
--- a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs
+++ b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs
@@ -21,7 +21,9 @@ namespace MediaBrowser.Providers.TV
public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
{
- return Task.Run(() => RunInternal(progress, cancellationToken));
+ RunInternal(progress, cancellationToken);
+
+ return Task.FromResult(true);
}
private void RunInternal(IProgress<double> progress, CancellationToken cancellationToken)
diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
index e5260004a..a5f54b938 100644
--- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs
+++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
@@ -237,7 +237,9 @@ namespace MediaBrowser.Server.Implementations.Dto
NowViewingItemId = session.NowViewingItemId,
NowViewingItemName = session.NowViewingItemName,
NowViewingItemType = session.NowViewingItemType,
- ApplicationVersion = session.ApplicationVersion
+ ApplicationVersion = session.ApplicationVersion,
+ CanSeek = session.CanSeek,
+ QueueableMediaTypes = session.QueueableMediaTypes
};
if (session.NowPlayingItem != null)
diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
index a5b792726..1bc3f1094 100644
--- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
@@ -829,10 +829,6 @@ namespace MediaBrowser.Server.Implementations.Library
/// <returns>Task.</returns>
public async Task ValidatePeople(CancellationToken cancellationToken, IProgress<double> progress)
{
- const int maxTasks = 3;
-
- var tasks = new List<Task>();
-
var people = RootFolder.RecursiveChildren
.SelectMany(c => c.People)
.DistinctBy(p => p.Name, StringComparer.OrdinalIgnoreCase)
@@ -842,47 +838,27 @@ namespace MediaBrowser.Server.Implementations.Library
foreach (var person in people)
{
- if (tasks.Count > maxTasks)
+ cancellationToken.ThrowIfCancellationRequested();
+
+ try
{
- await Task.WhenAll(tasks).ConfigureAwait(false);
- tasks.Clear();
+ var item = GetPerson(person.Name);
- // Safe cancellation point, when there are no pending tasks
- cancellationToken.ThrowIfCancellationRequested();
+ await item.RefreshMetadata(cancellationToken).ConfigureAwait(false);
}
-
- // Avoid accessing the foreach variable within the closure
- var currentPerson = person;
-
- tasks.Add(Task.Run(async () =>
+ catch (IOException ex)
{
- cancellationToken.ThrowIfCancellationRequested();
-
- try
- {
- var item = GetPerson(currentPerson.Name);
-
- await item.RefreshMetadata(cancellationToken).ConfigureAwait(false);
- }
- catch (IOException ex)
- {
- _logger.ErrorException("Error validating IBN entry {0}", ex, currentPerson.Name);
- }
+ _logger.ErrorException("Error validating IBN entry {0}", ex, person.Name);
+ }
- // Update progress
- lock (progress)
- {
- numComplete++;
- double percent = numComplete;
- percent /= people.Count;
+ // Update progress
+ numComplete++;
+ double percent = numComplete;
+ percent /= people.Count;
- progress.Report(100 * percent);
- }
- }));
+ progress.Report(100 * percent);
}
- await Task.WhenAll(tasks).ConfigureAwait(false);
-
progress.Report(100);
_logger.Info("People validation complete");
@@ -956,7 +932,9 @@ namespace MediaBrowser.Server.Implementations.Library
public Task ValidateMediaLibrary(IProgress<double> progress, CancellationToken cancellationToken)
{
// Just run the scheduled task so that the user can see it
- return Task.Run(() => _taskManager.CancelIfRunningAndQueue<RefreshMediaLibraryTask>());
+ _taskManager.CancelIfRunningAndQueue<RefreshMediaLibraryTask>();
+
+ return Task.FromResult(true);
}
/// <summary>
diff --git a/MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs b/MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs
index efefaeba3..dc96632f6 100644
--- a/MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs
+++ b/MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs
@@ -41,7 +41,9 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
/// <returns>Task.</returns>
public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
{
- return Task.Run(() => RunInternal(progress, cancellationToken));
+ RunInternal(progress, cancellationToken);
+
+ return Task.FromResult(true);
}
private void RunInternal(IProgress<double> progress, CancellationToken cancellationToken)
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
index f4f5f08e4..9c5cf6f1c 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
@@ -333,17 +333,16 @@ namespace MediaBrowser.Server.Implementations.Persistence
/// <returns>Task.</returns>
public Task SaveCriticReviews(Guid itemId, IEnumerable<ItemReview> criticReviews)
{
- return Task.Run(() =>
+ if (!Directory.Exists(_criticReviewsPath))
{
- if (!Directory.Exists(_criticReviewsPath))
- {
- Directory.CreateDirectory(_criticReviewsPath);
- }
+ Directory.CreateDirectory(_criticReviewsPath);
+ }
- var path = Path.Combine(_criticReviewsPath, itemId + ".json");
+ var path = Path.Combine(_criticReviewsPath, itemId + ".json");
+
+ _jsonSerializer.SerializeToFile(criticReviews.ToList(), path);
- _jsonSerializer.SerializeToFile(criticReviews.ToList(), path);
- });
+ return Task.FromResult(true);
}
/// <summary>
diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs
index ce757d142..65ec02d12 100644
--- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs
+++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs
@@ -207,21 +207,29 @@ namespace MediaBrowser.Server.Implementations.Session
/// <summary>
/// Used to report that playback has started for an item
/// </summary>
- /// <param name="item">The item.</param>
- /// <param name="sessionId">The session id.</param>
+ /// <param name="info">The info.</param>
/// <returns>Task.</returns>
- /// <exception cref="System.ArgumentNullException"></exception>
- public async Task OnPlaybackStart(BaseItem item, Guid sessionId)
+ /// <exception cref="System.ArgumentNullException">info</exception>
+ public async Task OnPlaybackStart(PlaybackInfo info)
{
- if (item == null)
+ if (info == null)
{
- throw new ArgumentNullException();
+ throw new ArgumentNullException("info");
+ }
+ if (info.SessionId == Guid.Empty)
+ {
+ throw new ArgumentNullException("info");
}
- var session = Sessions.First(i => i.Id.Equals(sessionId));
+ var session = Sessions.First(i => i.Id.Equals(info.SessionId));
+
+ var item = info.Item;
UpdateNowPlayingItem(session, item, false, false);
+ session.CanSeek = info.CanSeek;
+ session.QueueableMediaTypes = info.QueueableMediaTypes;
+
var key = item.GetUserDataKey();
var user = session.User;
diff --git a/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs b/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs
index 2a4361e61..95eb5948f 100644
--- a/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs
+++ b/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs
@@ -101,16 +101,7 @@ namespace MediaBrowser.Server.Implementations.Session
}
else if (string.Equals(message.MessageType, "PlaybackStart", StringComparison.OrdinalIgnoreCase))
{
- _logger.Debug("Received PlaybackStart message");
-
- var session = _sessionManager.Sessions.FirstOrDefault(i => i.WebSockets.Contains(message.Connection));
-
- if (session != null && session.User != null)
- {
- var item = _dtoService.GetItemByDtoId(message.Data);
-
- _sessionManager.OnPlaybackStart(item, session.Id);
- }
+ ReportPlaybackStart(message);
}
else if (string.Equals(message.MessageType, "PlaybackProgress", StringComparison.OrdinalIgnoreCase))
{
@@ -170,5 +161,46 @@ namespace MediaBrowser.Server.Implementations.Session
return _trueTaskResult;
}
+
+ /// <summary>
+ /// Reports the playback start.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ private void ReportPlaybackStart(WebSocketMessageInfo message)
+ {
+ _logger.Debug("Received PlaybackStart message");
+
+ var session = _sessionManager.Sessions
+ .FirstOrDefault(i => i.WebSockets.Contains(message.Connection));
+
+ if (session != null && session.User != null)
+ {
+ var vals = message.Data.Split('|');
+
+ var item = _dtoService.GetItemByDtoId(vals[0]);
+
+ var queueableMediaTypes = string.Empty;
+ var canSeek = true;
+
+ if (vals.Length > 1)
+ {
+ canSeek = string.Equals(vals[1], "true", StringComparison.OrdinalIgnoreCase);
+ }
+ if (vals.Length > 2)
+ {
+ queueableMediaTypes = vals[2];
+ }
+
+ var info = new PlaybackInfo
+ {
+ CanSeek = canSeek,
+ Item = item,
+ SessionId = session.Id,
+ QueueableMediaTypes = queueableMediaTypes.Split(',').ToList()
+ };
+
+ _sessionManager.OnPlaybackStart(info);
+ }
+ }
}
}
diff --git a/MediaBrowser.Server.Implementations/WebSocket/AlchemyWebSocket.cs b/MediaBrowser.Server.Implementations/WebSocket/AlchemyWebSocket.cs
index 958201625..de998254c 100644
--- a/MediaBrowser.Server.Implementations/WebSocket/AlchemyWebSocket.cs
+++ b/MediaBrowser.Server.Implementations/WebSocket/AlchemyWebSocket.cs
@@ -92,7 +92,9 @@ namespace MediaBrowser.Server.Implementations.WebSocket
/// <returns>Task.</returns>
public Task SendAsync(byte[] bytes, WebSocketMessageType type, bool endOfMessage, CancellationToken cancellationToken)
{
- return Task.Run(() => UserContext.Send(bytes));
+ UserContext.Send(bytes);
+
+ return Task.FromResult(true);
}
/// <summary>
diff --git a/MediaBrowser.WebDashboard/ApiClient.js b/MediaBrowser.WebDashboard/ApiClient.js
index d139adfc3..189812a3c 100644
--- a/MediaBrowser.WebDashboard/ApiClient.js
+++ b/MediaBrowser.WebDashboard/ApiClient.js
@@ -3200,7 +3200,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
* @param {String} userId
* @param {String} itemId
*/
- self.reportPlaybackStart = function (userId, itemId) {
+ self.reportPlaybackStart = function (userId, itemId, canSeek, queueableMediaTypes) {
if (!userId) {
throw new Error("null userId");
@@ -3210,17 +3210,26 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
throw new Error("null itemId");
}
+ canSeek = canSeek || false;
+ queueableMediaTypes = queueableMediaTypes || '';
+
if (self.isWebSocketOpen()) {
var deferred = $.Deferred();
- self.sendWebSocketMessage("PlaybackStart", itemId);
+ var msg = [itemId, canSeek, queueableMediaTypes];
+
+ self.sendWebSocketMessage("PlaybackStart", msg.join('|'));
deferred.resolveWith(null, []);
return deferred.promise();
}
- var url = self.getUrl("Users/" + userId + "/PlayingItems/" + itemId);
+ var url = self.getUrl("Users/" + userId + "/PlayingItems/" + itemId, {
+
+ CanSeek: canSeek,
+ QueueableMediaTypes: queueableMediaTypes
+ });
return self.ajax({
type: "POST",
diff --git a/MediaBrowser.WebDashboard/packages.config b/MediaBrowser.WebDashboard/packages.config
index 25b4f7b47..1c5a0f818 100644
--- a/MediaBrowser.WebDashboard/packages.config
+++ b/MediaBrowser.WebDashboard/packages.config
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="MediaBrowser.ApiClient.Javascript" version="3.0.175" targetFramework="net45" />
+ <package id="MediaBrowser.ApiClient.Javascript" version="3.0.176" targetFramework="net45" />
<package id="ServiceStack.Common" version="3.9.62" targetFramework="net45" />
<package id="ServiceStack.Text" version="3.9.62" targetFramework="net45" />
</packages> \ No newline at end of file