diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2013-09-24 11:08:51 -0400 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2013-09-24 11:08:51 -0400 |
| commit | b49764dbaafbbf11b6308ec675355696b9e58379 (patch) | |
| tree | 58677308bf98c95f1982a84eb403a01241f0a692 | |
| parent | 14c464c28a3b9cac207ef741711e31cef1c15378 (diff) | |
fixes #555 - Have clients report seek and queuing capabilities
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 |
