diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
index ab3e2af190..9085a3ecfd 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; }
-
+
///
/// Gets or sets the id.
///
@@ -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";
+ }
+
///
/// Gets or sets the user id.
///
@@ -237,6 +244,20 @@ namespace MediaBrowser.Api.UserLibrary
/// The id.
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
public string Id { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether this is likes.
+ ///
+ /// true if likes; otherwise, false.
+ [ApiMember(Name = "CanSeek", Description = "Indicates if the client can seek", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "POST")]
+ public bool CanSeek { get; set; }
+
+ ///
+ /// Gets or sets the id.
+ ///
+ /// The id.
+ [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; }
}
///
@@ -378,6 +399,8 @@ namespace MediaBrowser.Api.UserLibrary
/// The library manager.
/// The user data repository.
/// The item repo.
+ /// The session manager.
+ /// The dto service.
/// jsonSerializer
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);
}
///
diff --git a/MediaBrowser.Common.Implementations/Logging/NlogManager.cs b/MediaBrowser.Common.Implementations/Logging/NlogManager.cs
index 109e85d80a..e20f9bc138 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 15f955723a..bfd626adbc 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
/// Task.
public Task Execute(CancellationToken cancellationToken, IProgress 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);
}
///
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerTask.cs
index e860834eca..00928255cb 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);
}
///
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index 326d30bd76..0f090f587b 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 f49bd8cf00..80cf82da15 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -165,6 +165,7 @@
+
diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs
index 1976c653a6..fba1d26e8b 100644
--- a/MediaBrowser.Controller/Session/ISessionManager.cs
+++ b/MediaBrowser.Controller/Session/ISessionManager.cs
@@ -47,11 +47,9 @@ namespace MediaBrowser.Controller.Session
///
/// Used to report that playback has started for an item
///
- /// The item.
- /// The session id.
+ /// The info.
/// Task.
- ///
- Task OnPlaybackStart(BaseItem item, Guid sessionId);
+ Task OnPlaybackStart(PlaybackInfo info);
///
/// Used to report playback progress for an item
@@ -59,6 +57,7 @@ namespace MediaBrowser.Controller.Session
/// The item.
/// The position ticks.
/// if set to true [is paused].
+ /// if set to true [is muted].
/// The session id.
/// Task.
///
diff --git a/MediaBrowser.Controller/Session/PlaybackInfo.cs b/MediaBrowser.Controller/Session/PlaybackInfo.cs
new file mode 100644
index 0000000000..ab3111e766
--- /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();
+ }
+
+ ///
+ /// Gets or sets a value indicating whether this instance can seek.
+ ///
+ /// true if this instance can seek; otherwise, false.
+ public bool CanSeek { get; set; }
+
+ ///
+ /// Gets or sets the queueable media types.
+ ///
+ /// The queueable media types.
+ public List QueueableMediaTypes { get; set; }
+
+ ///
+ /// Gets or sets the item.
+ ///
+ /// The item.
+ public BaseItem Item { get; set; }
+
+ ///
+ /// Gets or sets the session id.
+ ///
+ /// The session id.
+ public Guid SessionId { get; set; }
+ }
+}
diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs
index 6c0f1a0854..ba6d3d0acd 100644
--- a/MediaBrowser.Controller/Session/SessionInfo.cs
+++ b/MediaBrowser.Controller/Session/SessionInfo.cs
@@ -15,8 +15,21 @@ namespace MediaBrowser.Controller.Session
public SessionInfo()
{
WebSockets = new List();
+ QueueableMediaTypes = new List();
}
+ ///
+ /// Gets or sets a value indicating whether this instance can seek.
+ ///
+ /// true if this instance can seek; otherwise, false.
+ public bool CanSeek { get; set; }
+
+ ///
+ /// Gets or sets the queueable media types.
+ ///
+ /// The queueable media types.
+ public List QueueableMediaTypes { get; set; }
+
///
/// Gets or sets the id.
///
diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs
index 03ea79b3b0..4a459cac81 100644
--- a/MediaBrowser.Model/ApiClient/IApiClient.cs
+++ b/MediaBrowser.Model/ApiClient/IApiClient.cs
@@ -497,9 +497,11 @@ namespace MediaBrowser.Model.ApiClient
///
/// The item id.
/// The user id.
+ /// if set to true [is seekable].
+ /// The list of media types that the client is capable of queuing onto the playlist. See MediaType class.
/// Task{UserItemDataDto}.
/// itemId
- Task ReportPlaybackStartAsync(string itemId, string userId);
+ Task ReportPlaybackStartAsync(string itemId, string userId, bool isSeekable, List queueableMediaTypes);
///
/// Reports playback progress to the server
diff --git a/MediaBrowser.Model/Session/SessionInfoDto.cs b/MediaBrowser.Model/Session/SessionInfoDto.cs
index f9b0e0abdb..02b7f02268 100644
--- a/MediaBrowser.Model/Session/SessionInfoDto.cs
+++ b/MediaBrowser.Model/Session/SessionInfoDto.cs
@@ -1,11 +1,24 @@
-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
{
+ ///
+ /// Gets or sets a value indicating whether this instance can seek.
+ ///
+ /// true if this instance can seek; otherwise, false.
+ public bool CanSeek { get; set; }
+
+ ///
+ /// Gets or sets the queueable media types.
+ ///
+ /// The queueable media types.
+ public List QueueableMediaTypes { get; set; }
+
///
/// Gets or sets the id.
///
diff --git a/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs b/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs
index fefcd8371a..adc013699a 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 18868d3eae..e18351248a 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 progress, CancellationToken cancellationToken)
{
- return Task.Run(() => RunInternal(progress, cancellationToken));
+ RunInternal(progress, cancellationToken);
+
+ return Task.FromResult(true);
}
private void RunInternal(IProgress progress, CancellationToken cancellationToken)
diff --git a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs
index a781551dee..2b73ba1f7d 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 progress, CancellationToken cancellationToken)
{
- return Task.Run(() => RunInternal(progress, cancellationToken));
+ RunInternal(progress, cancellationToken);
+
+ return Task.FromResult(true);
}
private void RunInternal(IProgress progress, CancellationToken cancellationToken)
diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
index e5260004a6..a5f54b9380 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 a5b7927265..1bc3f10943 100644
--- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
@@ -829,10 +829,6 @@ namespace MediaBrowser.Server.Implementations.Library
/// Task.
public async Task ValidatePeople(CancellationToken cancellationToken, IProgress progress)
{
- const int maxTasks = 3;
-
- var tasks = new List();
-
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 progress, CancellationToken cancellationToken)
{
// Just run the scheduled task so that the user can see it
- return Task.Run(() => _taskManager.CancelIfRunningAndQueue());
+ _taskManager.CancelIfRunningAndQueue();
+
+ return Task.FromResult(true);
}
///
diff --git a/MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs b/MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs
index efefaeba35..dc96632f60 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
/// Task.
public Task Run(IProgress progress, CancellationToken cancellationToken)
{
- return Task.Run(() => RunInternal(progress, cancellationToken));
+ RunInternal(progress, cancellationToken);
+
+ return Task.FromResult(true);
}
private void RunInternal(IProgress progress, CancellationToken cancellationToken)
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
index f4f5f08e48..9c5cf6f1c5 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
@@ -333,17 +333,16 @@ namespace MediaBrowser.Server.Implementations.Persistence
/// Task.
public Task SaveCriticReviews(Guid itemId, IEnumerable 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);
}
///
diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs
index ce757d142d..65ec02d128 100644
--- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs
+++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs
@@ -207,21 +207,29 @@ namespace MediaBrowser.Server.Implementations.Session
///
/// Used to report that playback has started for an item
///
- /// The item.
- /// The session id.
+ /// The info.
/// Task.
- ///
- public async Task OnPlaybackStart(BaseItem item, Guid sessionId)
+ /// info
+ 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 2a4361e616..95eb5948f3 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;
}
+
+ ///
+ /// Reports the playback start.
+ ///
+ /// The message.
+ 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 9582016258..de998254cc 100644
--- a/MediaBrowser.Server.Implementations/WebSocket/AlchemyWebSocket.cs
+++ b/MediaBrowser.Server.Implementations/WebSocket/AlchemyWebSocket.cs
@@ -92,7 +92,9 @@ namespace MediaBrowser.Server.Implementations.WebSocket
/// Task.
public Task SendAsync(byte[] bytes, WebSocketMessageType type, bool endOfMessage, CancellationToken cancellationToken)
{
- return Task.Run(() => UserContext.Send(bytes));
+ UserContext.Send(bytes);
+
+ return Task.FromResult(true);
}
///
diff --git a/MediaBrowser.WebDashboard/ApiClient.js b/MediaBrowser.WebDashboard/ApiClient.js
index d139adfc3e..189812a3c8 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 25b4f7b47c..1c5a0f818d 100644
--- a/MediaBrowser.WebDashboard/packages.config
+++ b/MediaBrowser.WebDashboard/packages.config
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file