ソースを参照

add new playback checkin endpoints

Luke Pulverenti 11 年 前
コミット
2ce9e05d2f

+ 11 - 11
MediaBrowser.Api/SessionsService.cs

@@ -41,7 +41,7 @@ namespace MediaBrowser.Api
         /// </summary>
         /// <value>The id.</value>
         [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
-        public Guid Id { get; set; }
+        public string Id { get; set; }
 
         /// <summary>
         /// Artist, Genre, Studio, Person, or any kind of BaseItem
@@ -82,7 +82,7 @@ namespace MediaBrowser.Api
         /// </summary>
         /// <value>The id.</value>
         [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
-        public Guid Id { get; set; }
+        public string Id { get; set; }
 
         /// <summary>
         /// Artist, Genre, Studio, Person, or any kind of BaseItem
@@ -114,7 +114,7 @@ namespace MediaBrowser.Api
         /// </summary>
         /// <value>The id.</value>
         [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
-        public Guid Id { get; set; }
+        public string Id { get; set; }
 
         /// <summary>
         /// Gets or sets the position to seek to
@@ -138,7 +138,7 @@ namespace MediaBrowser.Api
         /// </summary>
         /// <value>The id.</value>
         [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
-        public Guid Id { get; set; }
+        public string Id { get; set; }
 
         /// <summary>
         /// Gets or sets the command.
@@ -156,7 +156,7 @@ namespace MediaBrowser.Api
         /// </summary>
         /// <value>The id.</value>
         [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
-        public Guid Id { get; set; }
+        public string Id { get; set; }
 
         /// <summary>
         /// Gets or sets the command.
@@ -174,7 +174,7 @@ namespace MediaBrowser.Api
         /// </summary>
         /// <value>The id.</value>
         [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
-        public Guid Id { get; set; }
+        public string Id { get; set; }
     }
 
     [Route("/Sessions/{Id}/Message", "POST", Summary = "Issues a command to a client to display a message to the user")]
@@ -185,7 +185,7 @@ namespace MediaBrowser.Api
         /// </summary>
         /// <value>The id.</value>
         [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
-        public Guid Id { get; set; }
+        public string Id { get; set; }
 
         [ApiMember(Name = "Text", Description = "The message text.", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
         public string Text { get; set; }
@@ -201,7 +201,7 @@ namespace MediaBrowser.Api
     public class AddUserToSession : IReturnVoid
     {
         [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
-        public Guid Id { get; set; }
+        public string Id { get; set; }
 
         [ApiMember(Name = "UserId", Description = "UserId Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
         public Guid UserId { get; set; }
@@ -211,7 +211,7 @@ namespace MediaBrowser.Api
     public class RemoveUserFromSession : IReturnVoid
     {
         [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
-        public Guid Id { get; set; }
+        public string Id { get; set; }
 
         [ApiMember(Name = "UserId", Description = "UserId Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
         public Guid UserId { get; set; }
@@ -423,9 +423,9 @@ namespace MediaBrowser.Api
         {
             if (string.IsNullOrWhiteSpace(request.Id))
             {
-                request.Id = GetSession().Id.ToString("N");
+                request.Id = GetSession().Id;
             }
-            _sessionManager.ReportCapabilities(new Guid(request.Id), new SessionCapabilities
+            _sessionManager.ReportCapabilities(request.Id, new SessionCapabilities
             {
                 PlayableMediaTypes = request.PlayableMediaTypes.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(),
 

+ 48 - 29
MediaBrowser.Api/UserLibrary/UserLibraryService.cs

@@ -9,6 +9,7 @@ using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Querying;
 using MediaBrowser.Model.Serialization;
+using MediaBrowser.Model.Session;
 using ServiceStack;
 using System;
 using System.Collections.Generic;
@@ -220,6 +221,24 @@ namespace MediaBrowser.Api.UserLibrary
         public string Id { get; set; }
     }
 
+    [Route("/Sessions/Playing", "POST")]
+    [Api(Description = "Reports playback has started within a session")]
+    public class ReportPlaybackStart : PlaybackStartInfo, IReturnVoid
+    {
+    }
+
+    [Route("/Sessions/Playing/Progress", "POST")]
+    [Api(Description = "Reports playback progress within a session")]
+    public class ReportPlaybackProgress : PlaybackProgressInfo, IReturnVoid
+    {
+    }
+
+    [Route("/Sessions/Playing/Stopped", "POST")]
+    [Api(Description = "Reports playback has stopped within a session")]
+    public class ReportPlaybackStopped : PlaybackStopInfo, IReturnVoid
+    {
+    }
+    
     /// <summary>
     /// Class OnPlaybackStart
     /// </summary>
@@ -740,24 +759,26 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="request">The request.</param>
         public void Post(OnPlaybackStart request)
         {
-            var user = _userManager.GetUserById(request.UserId);
-
-            var item = _dtoService.GetItemByDtoId(request.Id, user.Id);
-
             var queueableMediaTypes = (request.QueueableMediaTypes ?? string.Empty);
 
-            var info = new PlaybackInfo
+            Post(new ReportPlaybackStart
             {
                 CanSeek = request.CanSeek,
-                Item = item,
-                SessionId = GetSession(_sessionManager).Id,
+                ItemId = request.Id,
                 QueueableMediaTypes = queueableMediaTypes.Split(',').ToList(),
                 MediaSourceId = request.MediaSourceId,
                 AudioStreamIndex = request.AudioStreamIndex,
                 SubtitleStreamIndex = request.SubtitleStreamIndex
-            };
+            });
+        }
 
-            _sessionManager.OnPlaybackStart(info);
+        public void Post(ReportPlaybackStart request)
+        {
+            request.SessionId = GetSession(_sessionManager).Id;
+
+            var task = _sessionManager.OnPlaybackStart(request);
+
+            Task.WaitAll(task);
         }
 
         /// <summary>
@@ -766,24 +787,24 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="request">The request.</param>
         public void Post(OnPlaybackProgress request)
         {
-            var user = _userManager.GetUserById(request.UserId);
-
-            var item = _dtoService.GetItemByDtoId(request.Id, user.Id);
-
-            var info = new PlaybackProgressInfo
+            Post(new ReportPlaybackProgress
             {
-                Item = item,
+                ItemId = request.Id,
                 PositionTicks = request.PositionTicks,
                 IsMuted = request.IsMuted,
                 IsPaused = request.IsPaused,
-                SessionId = GetSession(_sessionManager).Id,
                 MediaSourceId = request.MediaSourceId,
                 AudioStreamIndex = request.AudioStreamIndex,
                 SubtitleStreamIndex = request.SubtitleStreamIndex,
                 VolumeLevel = request.VolumeLevel
-            };
+            });
+        }
+
+        public void Post(ReportPlaybackProgress request)
+        {
+            request.SessionId = GetSession(_sessionManager).Id;
 
-            var task = _sessionManager.OnPlaybackProgress(info);
+            var task = _sessionManager.OnPlaybackProgress(request);
 
             Task.WaitAll(task);
         }
@@ -794,21 +815,19 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="request">The request.</param>
         public void Delete(OnPlaybackStopped request)
         {
-            var user = _userManager.GetUserById(request.UserId);
-
-            var item = _dtoService.GetItemByDtoId(request.Id, user.Id);
-
-            var session = GetSession(_sessionManager);
-
-            var info = new PlaybackStopInfo
+            Post(new ReportPlaybackStopped
             {
-                Item = item,
+                ItemId = request.Id,
                 PositionTicks = request.PositionTicks,
-                SessionId = session.Id,
                 MediaSourceId = request.MediaSourceId
-            };
+            });
+        }
+
+        public void Post(ReportPlaybackStopped request)
+        {
+            request.SessionId = GetSession(_sessionManager).Id;
 
-            var task = _sessionManager.OnPlaybackStopped(info);
+            var task = _sessionManager.OnPlaybackStopped(request);
 
             Task.WaitAll(task);
         }

+ 0 - 3
MediaBrowser.Controller/MediaBrowser.Controller.csproj

@@ -251,9 +251,6 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Session\ISessionController.cs" />
     <Compile Include="Session\ISessionControllerFactory.cs" />
-    <Compile Include="Session\PlaybackInfo.cs" />
-    <Compile Include="Session\PlaybackProgressInfo.cs" />
-    <Compile Include="Session\PlaybackStopInfo.cs" />
     <Compile Include="Session\SessionEventArgs.cs" />
     <Compile Include="Session\SessionInfo.cs" />
     <Compile Include="Sorting\IBaseItemComparer.cs" />

+ 27 - 10
MediaBrowser.Controller/Session/ISessionManager.cs

@@ -1,5 +1,6 @@
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Session;
 using System;
 using System.Collections.Generic;
@@ -68,7 +69,7 @@ namespace MediaBrowser.Controller.Session
         /// </summary>
         /// <param name="info">The info.</param>
         /// <returns>Task.</returns>
-        Task OnPlaybackStart(PlaybackInfo info);
+        Task OnPlaybackStart(PlaybackStartInfo info);
 
         /// <summary>
         /// Used to report playback progress for an item
@@ -91,7 +92,7 @@ namespace MediaBrowser.Controller.Session
         /// </summary>
         /// <param name="sessionId">The session identifier.</param>
         /// <returns>Task.</returns>
-        Task ReportSessionEnded(Guid sessionId);
+        Task ReportSessionEnded(string sessionId);
 
         /// <summary>
         /// Gets the session info dto.
@@ -108,7 +109,7 @@ namespace MediaBrowser.Controller.Session
         /// <param name="command">The command.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>Task.</returns>
-        Task SendGeneralCommand(Guid controllingSessionId, Guid sessionId, GeneralCommand command, CancellationToken cancellationToken);
+        Task SendGeneralCommand(string controllingSessionId, string sessionId, GeneralCommand command, CancellationToken cancellationToken);
         
         /// <summary>
         /// Sends the message command.
@@ -118,7 +119,7 @@ namespace MediaBrowser.Controller.Session
         /// <param name="command">The command.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>Task.</returns>
-        Task SendMessageCommand(Guid controllingSessionId, Guid sessionId, MessageCommand command, CancellationToken cancellationToken);
+        Task SendMessageCommand(string controllingSessionId, string sessionId, MessageCommand command, CancellationToken cancellationToken);
 
         /// <summary>
         /// Sends the play command.
@@ -128,7 +129,7 @@ namespace MediaBrowser.Controller.Session
         /// <param name="command">The command.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>Task.</returns>
-        Task SendPlayCommand(Guid controllingSessionId, Guid sessionId, PlayRequest command, CancellationToken cancellationToken);
+        Task SendPlayCommand(string controllingSessionId, string sessionId, PlayRequest command, CancellationToken cancellationToken);
 
         /// <summary>
         /// Sends the browse command.
@@ -138,7 +139,7 @@ namespace MediaBrowser.Controller.Session
         /// <param name="command">The command.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>Task.</returns>
-        Task SendBrowseCommand(Guid controllingSessionId, Guid sessionId, BrowseRequest command, CancellationToken cancellationToken);
+        Task SendBrowseCommand(string controllingSessionId, string sessionId, BrowseRequest command, CancellationToken cancellationToken);
 
         /// <summary>
         /// Sends the playstate command.
@@ -148,7 +149,7 @@ namespace MediaBrowser.Controller.Session
         /// <param name="command">The command.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>Task.</returns>
-        Task SendPlaystateCommand(Guid controllingSessionId, Guid sessionId, PlaystateRequest command, CancellationToken cancellationToken);
+        Task SendPlaystateCommand(string controllingSessionId, string sessionId, PlaystateRequest command, CancellationToken cancellationToken);
 
         /// <summary>
         /// Sends the restart required message.
@@ -176,15 +177,31 @@ namespace MediaBrowser.Controller.Session
         /// </summary>
         /// <param name="sessionId">The session identifier.</param>
         /// <param name="userId">The user identifier.</param>
-        void AddAdditionalUser(Guid sessionId, Guid userId);
+        void AddAdditionalUser(string sessionId, Guid userId);
 
         /// <summary>
         /// Removes the additional user.
         /// </summary>
         /// <param name="sessionId">The session identifier.</param>
         /// <param name="userId">The user identifier.</param>
-        void RemoveAdditionalUser(Guid sessionId, Guid userId);
+        void RemoveAdditionalUser(string sessionId, Guid userId);
 
+        /// <summary>
+        /// Reports the now viewing item.
+        /// </summary>
+        /// <param name="sessionId">The session identifier.</param>
+        /// <param name="itemId">The item identifier.</param>
+        /// <param name="context">The context.</param>
+        void ReportNowViewingItem(string sessionId, string itemId, string context);
+
+        /// <summary>
+        /// Reports the now viewing item.
+        /// </summary>
+        /// <param name="sessionId">The session identifier.</param>
+        /// <param name="item">The item.</param>
+        /// <param name="context">The context.</param>
+        void ReportNowViewingItem(string sessionId, BaseItemInfo item, string context);
+        
         /// <summary>
         /// Authenticates the new session.
         /// </summary>
@@ -203,6 +220,6 @@ namespace MediaBrowser.Controller.Session
         /// </summary>
         /// <param name="sessionId">The session identifier.</param>
         /// <param name="capabilities">The capabilities.</param>
-        void ReportCapabilities(Guid sessionId, SessionCapabilities capabilities);
+        void ReportCapabilities(string sessionId, SessionCapabilities capabilities);
     }
 }

+ 0 - 56
MediaBrowser.Controller/Session/PlaybackInfo.cs

@@ -1,56 +0,0 @@
-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; }
-
-        /// <summary>
-        /// Gets or sets the media version identifier.
-        /// </summary>
-        /// <value>The media version identifier.</value>
-        public string MediaSourceId { get; set; }
-
-        /// <summary>
-        /// Gets or sets the index of the audio stream.
-        /// </summary>
-        /// <value>The index of the audio stream.</value>
-        public int? AudioStreamIndex { get; set; }
-
-        /// <summary>
-        /// Gets or sets the index of the subtitle stream.
-        /// </summary>
-        /// <value>The index of the subtitle stream.</value>
-        public int? SubtitleStreamIndex { get; set; }
-    }
-}

+ 0 - 62
MediaBrowser.Controller/Session/PlaybackProgressInfo.cs

@@ -1,62 +0,0 @@
-using MediaBrowser.Controller.Entities;
-using System;
-
-namespace MediaBrowser.Controller.Session
-{
-    public class PlaybackProgressInfo
-    {
-        /// <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; }
-
-        /// <summary>
-        /// Gets or sets a value indicating whether this instance is paused.
-        /// </summary>
-        /// <value><c>true</c> if this instance is paused; otherwise, <c>false</c>.</value>
-        public bool IsPaused { get; set; }
-
-        /// <summary>
-        /// Gets or sets a value indicating whether this instance is muted.
-        /// </summary>
-        /// <value><c>true</c> if this instance is muted; otherwise, <c>false</c>.</value>
-        public bool IsMuted { get; set; }
-
-        /// <summary>
-        /// Gets or sets the position ticks.
-        /// </summary>
-        /// <value>The position ticks.</value>
-        public long? PositionTicks { get; set; }
-
-        /// <summary>
-        /// Gets or sets the media version identifier.
-        /// </summary>
-        /// <value>The media version identifier.</value>
-        public string MediaSourceId { get; set; }
-
-        /// <summary>
-        /// Gets or sets the volume level.
-        /// </summary>
-        /// <value>The volume level.</value>
-        public int? VolumeLevel { get; set; }
-        
-        /// <summary>
-        /// Gets or sets the index of the audio stream.
-        /// </summary>
-        /// <value>The index of the audio stream.</value>
-        public int? AudioStreamIndex { get; set; }
-
-        /// <summary>
-        /// Gets or sets the index of the subtitle stream.
-        /// </summary>
-        /// <value>The index of the subtitle stream.</value>
-        public int? SubtitleStreamIndex { get; set; }
-    }
-}

+ 0 - 32
MediaBrowser.Controller/Session/PlaybackStopInfo.cs

@@ -1,32 +0,0 @@
-using MediaBrowser.Controller.Entities;
-using System;
-
-namespace MediaBrowser.Controller.Session
-{
-    public class PlaybackStopInfo
-    {
-        /// <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; }
-
-        /// <summary>
-        /// Gets or sets the position ticks.
-        /// </summary>
-        /// <value>The position ticks.</value>
-        public long? PositionTicks { get; set; }
-
-        /// <summary>
-        /// Gets or sets the media version identifier.
-        /// </summary>
-        /// <value>The media version identifier.</value>
-        public string MediaSourceId { get; set; }
-    }
-}

+ 7 - 62
MediaBrowser.Controller/Session/SessionInfo.cs

@@ -1,5 +1,4 @@
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Session;
 using System;
 using System.Collections.Generic;
@@ -26,8 +25,11 @@ namespace MediaBrowser.Controller.Session
 
             AdditionalUsers = new List<SessionUserInfo>();
             SupportedCommands = new List<string>();
+            PlayState = new PlayerStateInfo();
         }
 
+        public PlayerStateInfo PlayState { get; set; }
+        
         public List<SessionUserInfo> AdditionalUsers { get; set; }
 
         /// <summary>
@@ -36,12 +38,6 @@ namespace MediaBrowser.Controller.Session
         /// <value>The remote end point.</value>
         public string RemoteEndPoint { get; set; }
 
-        /// <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>
@@ -58,7 +54,7 @@ namespace MediaBrowser.Controller.Session
         /// Gets or sets the id.
         /// </summary>
         /// <value>The id.</value>
-        public Guid Id { get; set; }
+        public string Id { get; set; }
 
         /// <summary>
         /// Gets or sets the user id.
@@ -96,68 +92,17 @@ namespace MediaBrowser.Controller.Session
         /// <value>The now viewing context.</value>
         public string NowViewingContext { get; set; }
 
-        /// <summary>
-        /// Gets or sets the type of the now viewing item.
-        /// </summary>
-        /// <value>The type of the now viewing item.</value>
-        public string NowViewingItemType { get; set; }
-
-        /// <summary>
-        /// Gets or sets the now viewing item identifier.
-        /// </summary>
-        /// <value>The now viewing item identifier.</value>
-        public string NowViewingItemId { get; set; }
-
         /// <summary>
         /// Gets or sets the name of the now viewing item.
         /// </summary>
         /// <value>The name of the now viewing item.</value>
-        public string NowViewingItemName { get; set; }
+        public BaseItemInfo NowViewingItem { get; set; }
 
         /// <summary>
         /// Gets or sets the now playing item.
         /// </summary>
         /// <value>The now playing item.</value>
-        public BaseItem NowPlayingItem { get; set; }
-
-        /// <summary>
-        /// Gets or sets the now playing media version identifier.
-        /// </summary>
-        /// <value>The now playing media version identifier.</value>
-        public string NowPlayingMediaSourceId { get; set; }
-        
-        /// <summary>
-        /// Gets or sets the now playing run time ticks.
-        /// </summary>
-        /// <value>The now playing run time ticks.</value>
-        public long? NowPlayingRunTimeTicks { get; set; }
-
-        /// <summary>
-        /// Gets or sets the now playing position ticks.
-        /// </summary>
-        /// <value>The now playing position ticks.</value>
-        public long? NowPlayingPositionTicks { get; set; }
-        /// <summary>
-        /// Gets or sets a value indicating whether this instance is paused.
-        /// </summary>
-        /// <value><c>true</c> if this instance is paused; otherwise, <c>false</c>.</value>
-        public bool IsPaused { get; set; }
-
-        /// <summary>
-        /// Gets or sets a value indicating whether this instance is muted.
-        /// </summary>
-        /// <value><c>true</c> if this instance is muted; otherwise, <c>false</c>.</value>
-        public bool IsMuted { get; set; }
-
-        /// <summary>
-        /// Gets or sets the volume level, on a scale of 0-100
-        /// </summary>
-        /// <value>The volume level.</value>
-        public int? VolumeLevel { get; set; }
-
-        public int? NowPlayingAudioStreamIndex { get; set; }
-
-        public int? NowPlayingSubtitleStreamIndex { get; set; }
+        public BaseItemInfo NowPlayingItem { get; set; }
         
         /// <summary>
         /// Gets or sets the device id.

+ 27 - 23
MediaBrowser.Dlna/PlayTo/DlnaController.cs

@@ -1,5 +1,4 @@
-using System.Globalization;
-using MediaBrowser.Common.Net;
+using MediaBrowser.Common.Net;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller.Dlna;
 using MediaBrowser.Controller.Entities;
@@ -13,6 +12,7 @@ using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Session;
 using System;
 using System.Collections.Generic;
+using System.Globalization;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -91,9 +91,9 @@ namespace MediaBrowser.Dlna.PlayTo
             {
                 _playbackStarted = false;
 
-                await _sessionManager.OnPlaybackStopped(new Controller.Session.PlaybackStopInfo
+                await _sessionManager.OnPlaybackStopped(new PlaybackStopInfo
                 {
-                    Item = _currentItem,
+                    ItemId = _currentItem.Id.ToString("N"),
                     SessionId = _session.Id,
                     PositionTicks = _device.Position.Ticks
 
@@ -169,20 +169,23 @@ namespace MediaBrowser.Dlna.PlayTo
                 return;
 
             var playlistItem = Playlist.FirstOrDefault(p => p.PlayState == 1);
-            
+
             if (playlistItem != null)
             {
                 if (!_playbackStarted)
                 {
-                    await _sessionManager.OnPlaybackStart(new PlaybackInfo
+                    await _sessionManager.OnPlaybackStart(new PlaybackStartInfo
                     {
-                        Item = _currentItem,
+                        ItemId = _currentItem.Id.ToString("N"),
                         SessionId = _session.Id,
                         CanSeek = true,
                         QueueableMediaTypes = new List<string> { _currentItem.MediaType },
                         MediaSourceId = playlistItem.MediaSourceId,
                         AudioStreamIndex = playlistItem.AudioStreamIndex,
-                        SubtitleStreamIndex = playlistItem.SubtitleStreamIndex
+                        SubtitleStreamIndex = playlistItem.SubtitleStreamIndex,
+                        IsMuted = _device.IsMuted,
+                        IsPaused = _device.IsPaused,
+                        VolumeLevel = _device.Volume
 
                     }).ConfigureAwait(false);
 
@@ -198,9 +201,9 @@ namespace MediaBrowser.Dlna.PlayTo
                         ticks += playlistItem.StartPositionTicks;
                     }
 
-                    await _sessionManager.OnPlaybackProgress(new Controller.Session.PlaybackProgressInfo
+                    await _sessionManager.OnPlaybackProgress(new PlaybackProgressInfo
                     {
-                        Item = _currentItem,
+                        ItemId = _currentItem.Id.ToString("N"),
                         SessionId = _session.Id,
                         PositionTicks = ticks,
                         IsMuted = _device.IsMuted,
@@ -208,7 +211,8 @@ namespace MediaBrowser.Dlna.PlayTo
                         MediaSourceId = playlistItem.MediaSourceId,
                         AudioStreamIndex = playlistItem.AudioStreamIndex,
                         SubtitleStreamIndex = playlistItem.SubtitleStreamIndex,
-                        VolumeLevel = _device.Volume
+                        VolumeLevel = _device.Volume,
+                        CanSeek = true
 
                     }).ConfigureAwait(false);
                 }
@@ -617,7 +621,7 @@ namespace MediaBrowser.Dlna.PlayTo
         }
 
         private readonly CultureInfo _usCulture = new CultureInfo("en-US");
-        
+
         public Task SendGeneralCommand(GeneralCommand command, CancellationToken cancellationToken)
         {
             GeneralCommandType commandType;
@@ -637,23 +641,23 @@ namespace MediaBrowser.Dlna.PlayTo
                     case GeneralCommandType.ToggleMute:
                         return _device.ToggleMute();
                     case GeneralCommandType.SetVolume:
-                    {
-                        string volumeArg;
-
-                        if (command.Arguments.TryGetValue("Volume", out volumeArg))
                         {
-                            int volume;
+                            string volumeArg;
 
-                            if (int.TryParse(volumeArg, NumberStyles.Any, _usCulture, out volume))
+                            if (command.Arguments.TryGetValue("Volume", out volumeArg))
                             {
-                                return _device.SetVolume(volume);
+                                int volume;
+
+                                if (int.TryParse(volumeArg, NumberStyles.Any, _usCulture, out volume))
+                                {
+                                    return _device.SetVolume(volume);
+                                }
+
+                                throw new ArgumentException("Unsupported volume value supplied.");
                             }
 
-                            throw new ArgumentException("Unsupported volume value supplied.");
+                            throw new ArgumentException("Volume argument cannot be null");
                         }
-
-                        throw new ArgumentException("Volume argument cannot be null");
-                    }
                     default:
                         return Task.FromResult(true);
                 }

+ 0 - 6
MediaBrowser.Model/Entities/BaseItemInfo.cs

@@ -77,12 +77,6 @@ namespace MediaBrowser.Model.Entities
         /// <value>The thumb item identifier.</value>
         public string BackdropItemId { get; set; }
 
-        /// <summary>
-        /// Gets or sets the media version identifier.
-        /// </summary>
-        /// <value>The media version identifier.</value>
-        public string MediaSourceId { get; set; }
-
         /// <summary>
         /// Gets or sets the premiere date.
         /// </summary>

+ 91 - 27
MediaBrowser.Model/Session/PlaybackReports.cs

@@ -1,29 +1,23 @@
-
+using System.Collections.Generic;
+using MediaBrowser.Model.Entities;
+
 namespace MediaBrowser.Model.Session
 {
     /// <summary>
     /// Class PlaybackStartInfo.
     /// </summary>
-    public class PlaybackStartInfo
+    public class PlaybackStartInfo : PlaybackProgressInfo
     {
-        public string UserId { get; set; }
-
-        public string ItemId { get; set; }
-
-        public string MediaSourceId { get; set; }
-
-        public bool IsSeekable { get; set; }
-
-        public string[] QueueableMediaTypes { get; set; }
-
-        public int? AudioStreamIndex { get; set; }
-
-        public int? SubtitleStreamIndex { get; set; }
-
         public PlaybackStartInfo()
         {
-            QueueableMediaTypes = new string[] { };
+            QueueableMediaTypes = new List<string>();
         }
+
+        /// <summary>
+        /// Gets or sets the queueable media types.
+        /// </summary>
+        /// <value>The queueable media types.</value>
+        public List<string> QueueableMediaTypes { get; set; }
     }
 
     /// <summary>
@@ -31,22 +25,70 @@ namespace MediaBrowser.Model.Session
     /// </summary>
     public class PlaybackProgressInfo
     {
-        public string UserId { get; set; }
-
+        /// <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 item.
+        /// </summary>
+        /// <value>The item.</value>
+        public BaseItemInfo Item { get; set; }
+
+        /// <summary>
+        /// Gets or sets the item identifier.
+        /// </summary>
+        /// <value>The item identifier.</value>
         public string ItemId { get; set; }
-
+        
+        /// <summary>
+        /// Gets or sets the session id.
+        /// </summary>
+        /// <value>The session id.</value>
+        public string SessionId { get; set; }
+
+        /// <summary>
+        /// Gets or sets the media version identifier.
+        /// </summary>
+        /// <value>The media version identifier.</value>
         public string MediaSourceId { get; set; }
 
-        public long? PositionTicks { get; set; }
+        /// <summary>
+        /// Gets or sets the index of the audio stream.
+        /// </summary>
+        /// <value>The index of the audio stream.</value>
+        public int? AudioStreamIndex { get; set; }
+
+        /// <summary>
+        /// Gets or sets the index of the subtitle stream.
+        /// </summary>
+        /// <value>The index of the subtitle stream.</value>
+        public int? SubtitleStreamIndex { get; set; }
 
+        /// <summary>
+        /// Gets or sets a value indicating whether this instance is paused.
+        /// </summary>
+        /// <value><c>true</c> if this instance is paused; otherwise, <c>false</c>.</value>
         public bool IsPaused { get; set; }
 
+        /// <summary>
+        /// Gets or sets a value indicating whether this instance is muted.
+        /// </summary>
+        /// <value><c>true</c> if this instance is muted; otherwise, <c>false</c>.</value>
         public bool IsMuted { get; set; }
 
-        public int? AudioStreamIndex { get; set; }
-
-        public int? SubtitleStreamIndex { get; set; }
+        /// <summary>
+        /// Gets or sets the position ticks.
+        /// </summary>
+        /// <value>The position ticks.</value>
+        public long? PositionTicks { get; set; }
 
+        /// <summary>
+        /// Gets or sets the volume level.
+        /// </summary>
+        /// <value>The volume level.</value>
         public int? VolumeLevel { get; set; }
     }
 
@@ -55,12 +97,34 @@ namespace MediaBrowser.Model.Session
     /// </summary>
     public class PlaybackStopInfo
     {
-        public string UserId { get; set; }
-
+        /// <summary>
+        /// Gets or sets the item.
+        /// </summary>
+        /// <value>The item.</value>
+        public BaseItemInfo Item { get; set; }
+
+        /// <summary>
+        /// Gets or sets the item identifier.
+        /// </summary>
+        /// <value>The item identifier.</value>
         public string ItemId { get; set; }
-
+        
+        /// <summary>
+        /// Gets or sets the session id.
+        /// </summary>
+        /// <value>The session id.</value>
+        public string SessionId { get; set; }
+
+        /// <summary>
+        /// Gets or sets the media version identifier.
+        /// </summary>
+        /// <value>The media version identifier.</value>
         public string MediaSourceId { get; set; }
 
+        /// <summary>
+        /// Gets or sets the position ticks.
+        /// </summary>
+        /// <value>The position ticks.</value>
         public long? PositionTicks { get; set; }
     }
 }

+ 57 - 34
MediaBrowser.Model/Session/SessionInfoDto.cs

@@ -94,22 +94,10 @@ namespace MediaBrowser.Model.Session
         public string NowViewingContext { get; set; }
 
         /// <summary>
-        /// Gets or sets the type of the now viewing item.
+        /// Gets or sets the now viewing item.
         /// </summary>
-        /// <value>The type of the now viewing item.</value>
-        public string NowViewingItemType { get; set; }
-
-        /// <summary>
-        /// Gets or sets the now viewing item identifier.
-        /// </summary>
-        /// <value>The now viewing item identifier.</value>
-        public string NowViewingItemId { get; set; }
-
-        /// <summary>
-        /// Gets or sets the name of the now viewing item.
-        /// </summary>
-        /// <value>The name of the now viewing item.</value>
-        public string NowViewingItemName { get; set; }
+        /// <value>The now viewing item.</value>
+        public BaseItemInfo NowViewingItem { get; set; }
         
         /// <summary>
         /// Gets or sets the name of the device.
@@ -117,24 +105,6 @@ namespace MediaBrowser.Model.Session
         /// <value>The name of the device.</value>
         public string DeviceName { get; set; }
 
-        /// <summary>
-        /// Gets or sets the volume level.
-        /// </summary>
-        /// <value>The volume level.</value>
-        public int? VolumeLevel { get; set; }
-
-        /// <summary>
-        /// Gets or sets the index of the now playing audio stream.
-        /// </summary>
-        /// <value>The index of the now playing audio stream.</value>
-        public int? NowPlayingAudioStreamIndex { get; set; }
-
-        /// <summary>
-        /// Gets or sets the index of the now playing subtitle stream.
-        /// </summary>
-        /// <value>The index of the now playing subtitle stream.</value>
-        public int? NowPlayingSubtitleStreamIndex { get; set; }
-
         /// <summary>
         /// Gets or sets a value indicating whether this instance is paused.
         /// </summary>
@@ -170,7 +140,9 @@ namespace MediaBrowser.Model.Session
         /// </summary>
         /// <value><c>true</c> if [supports remote control]; otherwise, <c>false</c>.</value>
         public bool SupportsRemoteControl { get; set; }
-        
+
+        public PlayerStateInfo PlayState { get; set; }
+
         public event PropertyChangedEventHandler PropertyChanged;
 
         public SessionInfoDto()
@@ -211,4 +183,55 @@ namespace MediaBrowser.Model.Session
             SupportedCommands = new List<string>();
         }
     }
+
+    public class PlayerStateInfo
+    {
+        /// <summary>
+        /// Gets or sets the now playing position ticks.
+        /// </summary>
+        /// <value>The now playing position ticks.</value>
+        public long? PositionTicks { get; set; }
+
+        /// <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 a value indicating whether this instance is paused.
+        /// </summary>
+        /// <value><c>true</c> if this instance is paused; otherwise, <c>false</c>.</value>
+        public bool IsPaused { get; set; }
+
+        /// <summary>
+        /// Gets or sets a value indicating whether this instance is muted.
+        /// </summary>
+        /// <value><c>true</c> if this instance is muted; otherwise, <c>false</c>.</value>
+        public bool IsMuted { get; set; }
+
+        /// <summary>
+        /// Gets or sets the volume level.
+        /// </summary>
+        /// <value>The volume level.</value>
+        public int? VolumeLevel { get; set; }
+
+        /// <summary>
+        /// Gets or sets the index of the now playing audio stream.
+        /// </summary>
+        /// <value>The index of the now playing audio stream.</value>
+        public int? AudioStreamIndex { get; set; }
+
+        /// <summary>
+        /// Gets or sets the index of the now playing subtitle stream.
+        /// </summary>
+        /// <value>The index of the now playing subtitle stream.</value>
+        public int? SubtitleStreamIndex { get; set; }
+
+        /// <summary>
+        /// Gets or sets the now playing media version identifier.
+        /// </summary>
+        /// <value>The now playing media version identifier.</value>
+        public string MediaSourceId { get; set; }
+    }
 }

+ 1 - 1
MediaBrowser.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs

@@ -74,7 +74,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
 
             var now = DateTime.UtcNow;
 
-            return !_sessionManager.Sessions.Any(i => !string.IsNullOrEmpty(i.NowViewingItemName) || (now - i.LastActivityDate).TotalMinutes < 30);
+            return !_sessionManager.Sessions.Any(i => (now - i.LastActivityDate).TotalMinutes < 30);
         }
 
         public void Dispose()

ファイルの差分が大きいため隠しています
+ 0 - 0
MediaBrowser.Server.Implementations/Localization/Server/de.json


ファイルの差分が大きいため隠しています
+ 0 - 0
MediaBrowser.Server.Implementations/Localization/Server/it.json


ファイルの差分が大きいため隠しています
+ 0 - 0
MediaBrowser.Server.Implementations/Localization/Server/nl.json


ファイルの差分が大きいため隠しています
+ 0 - 0
MediaBrowser.Server.Implementations/Localization/Server/pt_PT.json


ファイルの差分が大きいため隠しています
+ 0 - 0
MediaBrowser.Server.Implementations/Localization/Server/ru.json


ファイルの差分が大きいため隠しています
+ 0 - 0
MediaBrowser.Server.Implementations/Localization/Server/sv.json


+ 127 - 146
MediaBrowser.Server.Implementations/Session/SessionManager.cs

@@ -1,5 +1,4 @@
-using System.IO;
-using MediaBrowser.Common.Events;
+using MediaBrowser.Common.Events;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Drawing;
@@ -229,7 +228,7 @@ namespace MediaBrowser.Server.Implementations.Session
             return session;
         }
 
-        public async Task ReportSessionEnded(Guid sessionId)
+        public async Task ReportSessionEnded(string sessionId)
         {
             await _sessionLock.WaitAsync(CancellationToken.None).ConfigureAwait(false);
 
@@ -261,50 +260,51 @@ namespace MediaBrowser.Server.Implementations.Session
         /// Updates the now playing item id.
         /// </summary>
         /// <param name="session">The session.</param>
-        /// <param name="item">The item.</param>
-        /// <param name="mediaSourceId">The media version identifier.</param>
-        /// <param name="isPaused">if set to <c>true</c> [is paused].</param>
-        /// <param name="currentPositionTicks">The current position ticks.</param>
-        private void UpdateNowPlayingItem(SessionInfo session, BaseItem item, string mediaSourceId, bool isPaused, long? currentPositionTicks = null)
+        /// <param name="info">The information.</param>
+        /// <param name="libraryItem">The library item.</param>
+        private void UpdateNowPlayingItem(SessionInfo session, PlaybackProgressInfo info, BaseItem libraryItem)
         {
-            session.IsPaused = isPaused;
-            session.NowPlayingPositionTicks = currentPositionTicks;
-            session.NowPlayingItem = item;
-            session.LastActivityDate = DateTime.UtcNow;
-            session.NowPlayingMediaSourceId = mediaSourceId;
+            var runtimeTicks = libraryItem.RunTimeTicks;
 
-            if (string.IsNullOrWhiteSpace(mediaSourceId))
+            if (string.IsNullOrWhiteSpace(info.MediaSourceId))
             {
-                session.NowPlayingRunTimeTicks = item.RunTimeTicks;
+                info.MediaSourceId = info.ItemId;
             }
-            else
+
+            if (!string.Equals(info.ItemId, info.MediaSourceId) &&
+                !string.IsNullOrWhiteSpace(info.MediaSourceId))
             {
-                var version = _libraryManager.GetItemById(new Guid(mediaSourceId));
+                runtimeTicks = _libraryManager.GetItemById(new Guid(info.MediaSourceId)).RunTimeTicks;
+            }
 
-                session.NowPlayingRunTimeTicks = version.RunTimeTicks;
+            if (!string.IsNullOrWhiteSpace(info.ItemId))
+            {
+                info.Item = GetItemInfo(libraryItem, runtimeTicks);
             }
+
+            session.PlayState.IsPaused = info.IsPaused;
+            session.PlayState.PositionTicks = info.PositionTicks;
+            session.NowPlayingItem = info.Item;
+            session.LastActivityDate = DateTime.UtcNow;
+            session.PlayState.MediaSourceId = info.MediaSourceId;
+
+            session.PlayState.CanSeek = info.CanSeek;
+
+            session.PlayState.IsMuted = info.IsMuted;
+            session.PlayState.VolumeLevel = info.VolumeLevel;
+            session.PlayState.AudioStreamIndex = info.AudioStreamIndex;
+            session.PlayState.SubtitleStreamIndex = info.SubtitleStreamIndex;
         }
 
         /// <summary>
         /// Removes the now playing item id.
         /// </summary>
         /// <param name="session">The session.</param>
-        /// <param name="item">The item.</param>
-        private void RemoveNowPlayingItem(SessionInfo session, BaseItem item)
+        /// <exception cref="System.ArgumentNullException">item</exception>
+        private void RemoveNowPlayingItem(SessionInfo session)
         {
-            if (item == null)
-            {
-                throw new ArgumentNullException("item");
-            }
-
-            if (session.NowPlayingItem != null && session.NowPlayingItem.Id == item.Id)
-            {
-                session.NowPlayingItem = null;
-                session.NowPlayingPositionTicks = null;
-                session.IsPaused = false;
-                session.NowPlayingRunTimeTicks = null;
-                session.NowPlayingMediaSourceId = null;
-            }
+            session.NowPlayingItem = null;
+            session.PlayState = new PlayerStateInfo();
         }
 
         private string GetSessionKey(string clientType, string appVersion, string deviceId)
@@ -338,7 +338,7 @@ namespace MediaBrowser.Server.Implementations.Session
                         Client = clientType,
                         DeviceId = deviceId,
                         ApplicationVersion = appVersion,
-                        Id = Guid.NewGuid()
+                        Id = Guid.NewGuid().ToString("N")
                     };
 
                     OnSessionStarted(sessionInfo);
@@ -402,45 +402,40 @@ namespace MediaBrowser.Server.Implementations.Session
         /// <param name="info">The info.</param>
         /// <returns>Task.</returns>
         /// <exception cref="System.ArgumentNullException">info</exception>
-        public async Task OnPlaybackStart(PlaybackInfo info)
+        public async Task OnPlaybackStart(PlaybackStartInfo info)
         {
             if (info == null)
             {
                 throw new ArgumentNullException("info");
             }
-            if (info.SessionId == Guid.Empty)
-            {
-                throw new ArgumentNullException("info");
-            }
-
-            var session = Sessions.First(i => i.Id.Equals(info.SessionId));
 
-            var item = info.Item;
+            var session = GetSession(info.SessionId);
 
-            var mediaSourceId = GetMediaSourceId(item, info.MediaSourceId);
+            var libraryItem = string.IsNullOrWhiteSpace(info.ItemId)
+                ? null
+                : _libraryManager.GetItemById(new Guid(info.ItemId));
 
-            UpdateNowPlayingItem(session, item, mediaSourceId, false);
+            UpdateNowPlayingItem(session, info, libraryItem);
 
-            session.CanSeek = info.CanSeek;
             session.QueueableMediaTypes = info.QueueableMediaTypes;
 
-            session.NowPlayingAudioStreamIndex = info.AudioStreamIndex;
-            session.NowPlayingSubtitleStreamIndex = info.SubtitleStreamIndex;
-
-            var key = item.GetUserDataKey();
-
             var users = GetUsers(session);
 
-            foreach (var user in users)
+            if (libraryItem != null)
             {
-                await OnPlaybackStart(user.Id, key, item).ConfigureAwait(false);
+                var key = libraryItem.GetUserDataKey();
+
+                foreach (var user in users)
+                {
+                    await OnPlaybackStart(user.Id, key, libraryItem).ConfigureAwait(false);
+                }
             }
 
             // Nothing to save here
             // Fire events to inform plugins
             EventHelper.QueueEventIfNotNull(PlaybackStart, this, new PlaybackProgressEventArgs
             {
-                Item = item,
+                Item = libraryItem,
                 Users = users,
                 MediaSourceId = info.MediaSourceId
 
@@ -478,44 +473,39 @@ namespace MediaBrowser.Server.Implementations.Session
         /// <returns>Task.</returns>
         /// <exception cref="System.ArgumentNullException"></exception>
         /// <exception cref="System.ArgumentOutOfRangeException">positionTicks</exception>
-        public async Task OnPlaybackProgress(Controller.Session.PlaybackProgressInfo info)
+        public async Task OnPlaybackProgress(PlaybackProgressInfo info)
         {
             if (info == null)
             {
                 throw new ArgumentNullException("info");
             }
 
-            if (info.PositionTicks.HasValue && info.PositionTicks.Value < 0)
-            {
-                throw new ArgumentOutOfRangeException("positionTicks");
-            }
-
-            var session = Sessions.First(i => i.Id.Equals(info.SessionId));
-
-            var mediaSourceId = GetMediaSourceId(info.Item, info.MediaSourceId);
+            var session = GetSession(info.SessionId);
 
-            UpdateNowPlayingItem(session, info.Item, mediaSourceId, info.IsPaused, info.PositionTicks);
+            var libraryItem = string.IsNullOrWhiteSpace(info.ItemId)
+                ? null
+                : _libraryManager.GetItemById(new Guid(info.ItemId));
 
-            session.IsMuted = info.IsMuted;
-            session.VolumeLevel = info.VolumeLevel;
-            session.NowPlayingAudioStreamIndex = info.AudioStreamIndex;
-            session.NowPlayingSubtitleStreamIndex = info.SubtitleStreamIndex;
-
-            var key = info.Item.GetUserDataKey();
+            UpdateNowPlayingItem(session, info, libraryItem);
 
             var users = GetUsers(session);
 
-            foreach (var user in users)
+            if (libraryItem != null)
             {
-                await OnPlaybackProgress(user.Id, key, info.Item, info.PositionTicks).ConfigureAwait(false);
+                var key = libraryItem.GetUserDataKey();
+
+                foreach (var user in users)
+                {
+                    await OnPlaybackProgress(user.Id, key, libraryItem, info.PositionTicks).ConfigureAwait(false);
+                }
             }
 
             EventHelper.QueueEventIfNotNull(PlaybackProgress, this, new PlaybackProgressEventArgs
             {
-                Item = info.Item,
+                Item = libraryItem,
                 Users = users,
-                PlaybackPositionTicks = info.PositionTicks,
-                MediaSourceId = mediaSourceId
+                PlaybackPositionTicks = session.PlayState.PositionTicks,
+                MediaSourceId = session.PlayState.MediaSourceId
 
             }, _logger);
         }
@@ -539,70 +529,58 @@ namespace MediaBrowser.Server.Implementations.Session
         /// <returns>Task.</returns>
         /// <exception cref="System.ArgumentNullException">info</exception>
         /// <exception cref="System.ArgumentOutOfRangeException">positionTicks</exception>
-        public async Task OnPlaybackStopped(Controller.Session.PlaybackStopInfo info)
+        public async Task OnPlaybackStopped(PlaybackStopInfo info)
         {
             if (info == null)
             {
                 throw new ArgumentNullException("info");
             }
 
-            if (info.Item == null)
-            {
-                throw new ArgumentException("PlaybackStopInfo.Item cannot be null");
-            }
-
-            if (info.SessionId == Guid.Empty)
-            {
-                throw new ArgumentException("PlaybackStopInfo.SessionId cannot be Guid.Empty");
-            }
-
             if (info.PositionTicks.HasValue && info.PositionTicks.Value < 0)
             {
                 throw new ArgumentOutOfRangeException("positionTicks");
             }
 
-            var session = Sessions.First(i => i.Id.Equals(info.SessionId));
+            var session = GetSession(info.SessionId);
+
+            var libraryItem = string.IsNullOrWhiteSpace(info.ItemId)
+                ? null
+                : _libraryManager.GetItemById(new Guid(info.ItemId));
 
-            RemoveNowPlayingItem(session, info.Item);
+            // Normalize
+            if (string.IsNullOrWhiteSpace(info.MediaSourceId))
+            {
+                info.MediaSourceId = info.ItemId;
+            }
 
-            var key = info.Item.GetUserDataKey();
+            RemoveNowPlayingItem(session);
 
             var users = GetUsers(session);
-
             var playedToCompletion = false;
-            foreach (var user in users)
+
+            if (libraryItem != null)
             {
-                playedToCompletion = await OnPlaybackStopped(user.Id, key, info.Item, info.PositionTicks).ConfigureAwait(false);
-            }
+                var key = libraryItem.GetUserDataKey();
 
-            var mediaSourceId = GetMediaSourceId(info.Item, info.MediaSourceId);
+                foreach (var user in users)
+                {
+                    playedToCompletion = await OnPlaybackStopped(user.Id, key, libraryItem, info.PositionTicks).ConfigureAwait(false);
+                }
+            }
 
             EventHelper.QueueEventIfNotNull(PlaybackStopped, this, new PlaybackStopEventArgs
             {
-                Item = info.Item,
+                Item = libraryItem,
                 Users = users,
                 PlaybackPositionTicks = info.PositionTicks,
                 PlayedToCompletion = playedToCompletion,
-                MediaSourceId = mediaSourceId
+                MediaSourceId = info.MediaSourceId
 
             }, _logger);
 
             await SendPlaybackStoppedNotification(session, CancellationToken.None).ConfigureAwait(false);
         }
 
-        private string GetMediaSourceId(BaseItem item, string reportedMediaSourceId)
-        {
-            if (string.IsNullOrWhiteSpace(reportedMediaSourceId))
-            {
-                if (item is Video || item is Audio)
-                {
-                    reportedMediaSourceId = item.Id.ToString("N");
-                }
-            }
-
-            return reportedMediaSourceId;
-        }
-
         private async Task<bool> OnPlaybackStopped(Guid userId, string userDataKey, BaseItem item, long? positionTicks)
         {
             var data = _userDataRepository.GetUserData(userId, userDataKey);
@@ -691,9 +669,9 @@ namespace MediaBrowser.Server.Implementations.Session
         /// <param name="sessionId">The session identifier.</param>
         /// <returns>SessionInfo.</returns>
         /// <exception cref="ResourceNotFoundException"></exception>
-        private SessionInfo GetSession(Guid sessionId)
+        private SessionInfo GetSession(string sessionId)
         {
-            var session = Sessions.First(i => i.Id.Equals(sessionId));
+            var session = Sessions.First(i => string.Equals(i.Id, sessionId));
 
             if (session == null)
             {
@@ -709,7 +687,7 @@ namespace MediaBrowser.Server.Implementations.Session
         /// <param name="sessionId">The session id.</param>
         /// <returns>SessionInfo.</returns>
         /// <exception cref="ResourceNotFoundException"></exception>
-        private SessionInfo GetSessionForRemoteControl(Guid sessionId)
+        private SessionInfo GetSessionForRemoteControl(string sessionId)
         {
             var session = GetSession(sessionId);
 
@@ -721,7 +699,7 @@ namespace MediaBrowser.Server.Implementations.Session
             return session;
         }
 
-        public Task SendMessageCommand(Guid controllingSessionId, Guid sessionId, MessageCommand command, CancellationToken cancellationToken)
+        public Task SendMessageCommand(string controllingSessionId, string sessionId, MessageCommand command, CancellationToken cancellationToken)
         {
             var session = GetSessionForRemoteControl(sessionId);
 
@@ -731,7 +709,7 @@ namespace MediaBrowser.Server.Implementations.Session
             return session.SessionController.SendMessageCommand(command, cancellationToken);
         }
 
-        public Task SendGeneralCommand(Guid controllingSessionId, Guid sessionId, GeneralCommand command, CancellationToken cancellationToken)
+        public Task SendGeneralCommand(string controllingSessionId, string sessionId, GeneralCommand command, CancellationToken cancellationToken)
         {
             var session = GetSessionForRemoteControl(sessionId);
 
@@ -741,7 +719,7 @@ namespace MediaBrowser.Server.Implementations.Session
             return session.SessionController.SendGeneralCommand(command, cancellationToken);
         }
 
-        public Task SendPlayCommand(Guid controllingSessionId, Guid sessionId, PlayRequest command, CancellationToken cancellationToken)
+        public Task SendPlayCommand(string controllingSessionId, string sessionId, PlayRequest command, CancellationToken cancellationToken)
         {
             var session = GetSessionForRemoteControl(sessionId);
 
@@ -861,7 +839,7 @@ namespace MediaBrowser.Server.Implementations.Session
             return new BaseItem[] { };
         }
 
-        public Task SendBrowseCommand(Guid controllingSessionId, Guid sessionId, BrowseRequest command, CancellationToken cancellationToken)
+        public Task SendBrowseCommand(string controllingSessionId, string sessionId, BrowseRequest command, CancellationToken cancellationToken)
         {
             var generalCommand = new GeneralCommand
             {
@@ -876,15 +854,10 @@ namespace MediaBrowser.Server.Implementations.Session
             return SendGeneralCommand(controllingSessionId, sessionId, generalCommand, cancellationToken);
         }
 
-        public Task SendPlaystateCommand(Guid controllingSessionId, Guid sessionId, PlaystateRequest command, CancellationToken cancellationToken)
+        public Task SendPlaystateCommand(string controllingSessionId, string sessionId, PlaystateRequest command, CancellationToken cancellationToken)
         {
             var session = GetSessionForRemoteControl(sessionId);
 
-            if (command.Command == PlaystateCommand.Seek && !session.CanSeek)
-            {
-                throw new ArgumentException(string.Format("Session {0} is unable to seek.", session.Id));
-            }
-
             var controllingSession = GetSession(controllingSessionId);
             AssertCanControl(session, controllingSession);
             if (controllingSession.UserId.HasValue)
@@ -1052,7 +1025,7 @@ namespace MediaBrowser.Server.Implementations.Session
         /// <param name="userId">The user identifier.</param>
         /// <exception cref="System.UnauthorizedAccessException">Cannot modify additional users without authenticating first.</exception>
         /// <exception cref="System.ArgumentException">The requested user is already the primary user of the session.</exception>
-        public void AddAdditionalUser(Guid sessionId, Guid userId)
+        public void AddAdditionalUser(string sessionId, Guid userId)
         {
             var session = GetSession(sessionId);
 
@@ -1085,7 +1058,7 @@ namespace MediaBrowser.Server.Implementations.Session
         /// <param name="userId">The user identifier.</param>
         /// <exception cref="System.UnauthorizedAccessException">Cannot modify additional users without authenticating first.</exception>
         /// <exception cref="System.ArgumentException">The requested user is already the primary user of the session.</exception>
-        public void RemoveAdditionalUser(Guid sessionId, Guid userId)
+        public void RemoveAdditionalUser(string sessionId, Guid userId)
         {
             var session = GetSession(sessionId);
 
@@ -1136,7 +1109,7 @@ namespace MediaBrowser.Server.Implementations.Session
         /// </summary>
         /// <param name="sessionId">The session identifier.</param>
         /// <param name="capabilities">The capabilities.</param>
-        public void ReportCapabilities(Guid sessionId, SessionCapabilities capabilities)
+        public void ReportCapabilities(string sessionId, SessionCapabilities capabilities)
         {
             var session = GetSession(sessionId);
 
@@ -1151,33 +1124,26 @@ namespace MediaBrowser.Server.Implementations.Session
                 Client = session.Client,
                 DeviceId = session.DeviceId,
                 DeviceName = session.DeviceName,
-                Id = session.Id.ToString("N"),
+                Id = session.Id,
                 LastActivityDate = session.LastActivityDate,
-                NowPlayingPositionTicks = session.NowPlayingPositionTicks,
+                NowPlayingPositionTicks = session.PlayState.PositionTicks,
                 SupportsRemoteControl = session.SupportsRemoteControl,
-                IsPaused = session.IsPaused,
-                IsMuted = session.IsMuted,
+                IsPaused = session.PlayState.IsPaused,
+                IsMuted = session.PlayState.IsMuted,
                 NowViewingContext = session.NowViewingContext,
-                NowViewingItemId = session.NowViewingItemId,
-                NowViewingItemName = session.NowViewingItemName,
-                NowViewingItemType = session.NowViewingItemType,
+                NowViewingItem = session.NowViewingItem,
                 ApplicationVersion = session.ApplicationVersion,
-                CanSeek = session.CanSeek,
+                CanSeek = session.PlayState.CanSeek,
                 QueueableMediaTypes = session.QueueableMediaTypes,
                 PlayableMediaTypes = session.PlayableMediaTypes,
                 RemoteEndPoint = session.RemoteEndPoint,
                 AdditionalUsers = session.AdditionalUsers,
                 SupportedCommands = session.SupportedCommands,
-                NowPlayingAudioStreamIndex = session.NowPlayingAudioStreamIndex,
-                NowPlayingSubtitleStreamIndex = session.NowPlayingSubtitleStreamIndex,
                 UserName = session.UserName,
-                VolumeLevel = session.VolumeLevel
-            };
+                NowPlayingItem = session.NowPlayingItem,
 
-            if (session.NowPlayingItem != null)
-            {
-                dto.NowPlayingItem = GetNowPlayingInfo(session.NowPlayingItem, session.NowPlayingMediaSourceId, session.NowPlayingRunTimeTicks);
-            }
+                PlayState = session.PlayState
+            };
 
             if (session.UserId.HasValue)
             {
@@ -1198,11 +1164,10 @@ namespace MediaBrowser.Server.Implementations.Session
         /// Converts a BaseItem to a BaseItemInfo
         /// </summary>
         /// <param name="item">The item.</param>
-        /// <param name="mediaSourceId">The media version identifier.</param>
-        /// <param name="nowPlayingRuntimeTicks">The now playing runtime ticks.</param>
+        /// <param name="runtimeTicks">The now playing runtime ticks.</param>
         /// <returns>BaseItemInfo.</returns>
         /// <exception cref="System.ArgumentNullException">item</exception>
-        private BaseItemInfo GetNowPlayingInfo(BaseItem item, string mediaSourceId, long? nowPlayingRuntimeTicks)
+        private BaseItemInfo GetItemInfo(BaseItem item, long? runtimeTicks)
         {
             if (item == null)
             {
@@ -1215,8 +1180,7 @@ namespace MediaBrowser.Server.Implementations.Session
                 Name = item.Name,
                 MediaType = item.MediaType,
                 Type = item.GetClientTypeName(),
-                RunTimeTicks = nowPlayingRuntimeTicks,
-                MediaSourceId = mediaSourceId,
+                RunTimeTicks = runtimeTicks,
                 IndexNumber = item.IndexNumber,
                 ParentIndexNumber = item.ParentIndexNumber,
                 PremiereDate = item.PremiereDate,
@@ -1287,7 +1251,7 @@ namespace MediaBrowser.Server.Implementations.Session
                     info.Artists.Add(musicVideo.Artist);
                 }
             }
-            
+
             var backropItem = item.HasImage(ImageType.Backdrop) ? item : null;
 
             var thumbItem = item.HasImage(ImageType.Thumb) ? item : null;
@@ -1360,5 +1324,22 @@ namespace MediaBrowser.Server.Implementations.Session
         {
             return _dtoService.GetDtoId(item);
         }
+
+        public void ReportNowViewingItem(string sessionId, string itemId, string context)
+        {
+            var item = _libraryManager.GetItemById(new Guid(itemId));
+
+            var info = GetItemInfo(item, item.RunTimeTicks);
+
+            ReportNowViewingItem(sessionId, info, context);
+        }
+
+        public void ReportNowViewingItem(string sessionId, BaseItemInfo item, string context)
+        {
+            var session = GetSession(sessionId);
+
+            session.NowViewingItem = item;
+            session.NowViewingContext = context;
+        }
     }
 }

+ 82 - 23
MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs

@@ -1,10 +1,11 @@
-using System.Globalization;
-using MediaBrowser.Common.Net;
+using MediaBrowser.Common.Net;
 using MediaBrowser.Controller;
-using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Session;
 using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
+using MediaBrowser.Model.Session;
 using System;
+using System.Globalization;
 using System.Linq;
 using System.Threading.Tasks;
 
@@ -33,7 +34,7 @@ namespace MediaBrowser.Server.Implementations.Session
         /// <summary>
         /// The _dto service
         /// </summary>
-        private readonly IDtoService _dtoService;
+        private readonly IJsonSerializer _json;
         private readonly IServerApplicationHost _appHost;
 
         /// <summary>
@@ -41,13 +42,13 @@ namespace MediaBrowser.Server.Implementations.Session
         /// </summary>
         /// <param name="sessionManager">The session manager.</param>
         /// <param name="logManager">The log manager.</param>
-        /// <param name="dtoService">The dto service.</param>
-        public SessionWebSocketListener(ISessionManager sessionManager, ILogManager logManager, IDtoService dtoService, IServerApplicationHost appHost)
+        /// <param name="appHost">The application host.</param>
+        public SessionWebSocketListener(ISessionManager sessionManager, ILogManager logManager, IServerApplicationHost appHost, IJsonSerializer json)
         {
             _sessionManager = sessionManager;
             _logger = logManager.GetLogger(GetType().Name);
-            _dtoService = dtoService;
             _appHost = appHost;
+            _json = json;
         }
 
         /// <summary>
@@ -67,13 +68,25 @@ namespace MediaBrowser.Server.Implementations.Session
             }
             else if (string.Equals(message.MessageType, "PlaybackStart", StringComparison.OrdinalIgnoreCase))
             {
-                ReportPlaybackStart(message);
+                OnPlaybackStart(message);
             }
             else if (string.Equals(message.MessageType, "PlaybackProgress", StringComparison.OrdinalIgnoreCase))
             {
-                ReportPlaybackProgress(message);
+                OnPlaybackProgress(message);
             }
             else if (string.Equals(message.MessageType, "PlaybackStopped", StringComparison.OrdinalIgnoreCase))
+            {
+                OnPlaybackStopped(message);
+            }
+            else if (string.Equals(message.MessageType, "ReportPlaybackStart", StringComparison.OrdinalIgnoreCase))
+            {
+                ReportPlaybackStart(message);
+            }
+            else if (string.Equals(message.MessageType, "ReportPlaybackProgress", StringComparison.OrdinalIgnoreCase))
+            {
+                ReportPlaybackProgress(message);
+            }
+            else if (string.Equals(message.MessageType, "ReportPlaybackStopped", StringComparison.OrdinalIgnoreCase))
             {
                 ReportPlaybackStopped(message);
             }
@@ -150,10 +163,8 @@ namespace MediaBrowser.Server.Implementations.Session
             {
                 var vals = message.Data.Split('|');
 
-                session.NowViewingItemType = vals[0];
-                session.NowViewingItemId = vals[1];
-                session.NowViewingItemName = vals[2];
-                session.NowViewingContext = vals.Length > 3 ? vals[3] : null;
+                var context = vals.Length > 3 ? vals[3] : null;
+                _sessionManager.ReportNowViewingItem(session.Id, vals[1], context);
             }
         }
 
@@ -194,7 +205,7 @@ namespace MediaBrowser.Server.Implementations.Session
         /// Reports the playback start.
         /// </summary>
         /// <param name="message">The message.</param>
-        private void ReportPlaybackStart(WebSocketMessageInfo message)
+        private void OnPlaybackStart(WebSocketMessageInfo message)
         {
             _logger.Debug("Received PlaybackStart message");
 
@@ -204,7 +215,7 @@ namespace MediaBrowser.Server.Implementations.Session
             {
                 var vals = message.Data.Split('|');
 
-                var item = _dtoService.GetItemByDtoId(vals[0]);
+                var itemId = vals[0];
 
                 var queueableMediaTypes = string.Empty;
                 var canSeek = true;
@@ -218,10 +229,10 @@ namespace MediaBrowser.Server.Implementations.Session
                     queueableMediaTypes = vals[2];
                 }
 
-                var info = new PlaybackInfo
+                var info = new PlaybackStartInfo
                 {
                     CanSeek = canSeek,
-                    Item = item,
+                    ItemId = itemId,
                     SessionId = session.Id,
                     QueueableMediaTypes = queueableMediaTypes.Split(',').ToList()
                 };
@@ -245,11 +256,43 @@ namespace MediaBrowser.Server.Implementations.Session
             }
         }
 
+        private void ReportPlaybackStart(WebSocketMessageInfo message)
+        {
+            _logger.Debug("Received ReportPlaybackStart message");
+
+            var session = GetSessionFromMessage(message);
+
+            if (session != null && session.UserId.HasValue)
+            {
+                var info = _json.DeserializeFromString<PlaybackStartInfo>(message.Data);
+
+                info.SessionId = session.Id;
+
+                _sessionManager.OnPlaybackStart(info);
+            }
+        }
+
+        private void ReportPlaybackProgress(WebSocketMessageInfo message)
+        {
+            //_logger.Debug("Received ReportPlaybackProgress message");
+
+            var session = GetSessionFromMessage(message);
+
+            if (session != null && session.UserId.HasValue)
+            {
+                var info = _json.DeserializeFromString<PlaybackProgressInfo>(message.Data);
+
+                info.SessionId = session.Id;
+
+                _sessionManager.OnPlaybackProgress(info);
+            }
+        }
+        
         /// <summary>
         /// Reports the playback progress.
         /// </summary>
         /// <param name="message">The message.</param>
-        private void ReportPlaybackProgress(WebSocketMessageInfo message)
+        private void OnPlaybackProgress(WebSocketMessageInfo message)
         {
             var session = GetSessionFromMessage(message);
 
@@ -257,7 +300,7 @@ namespace MediaBrowser.Server.Implementations.Session
             {
                 var vals = message.Data.Split('|');
 
-                var item = _dtoService.GetItemByDtoId(vals[0]);
+                var itemId = vals[0];
 
                 long? positionTicks = null;
 
@@ -276,7 +319,7 @@ namespace MediaBrowser.Server.Implementations.Session
 
                 var info = new PlaybackProgressInfo
                 {
-                    Item = item,
+                    ItemId = itemId,
                     PositionTicks = positionTicks,
                     IsMuted = isMuted,
                     IsPaused = isPaused,
@@ -307,11 +350,27 @@ namespace MediaBrowser.Server.Implementations.Session
             }
         }
 
+        private void ReportPlaybackStopped(WebSocketMessageInfo message)
+        {
+            _logger.Debug("Received ReportPlaybackStopped message");
+
+            var session = GetSessionFromMessage(message);
+
+            if (session != null && session.UserId.HasValue)
+            {
+                var info = _json.DeserializeFromString<PlaybackStopInfo>(message.Data);
+
+                info.SessionId = session.Id;
+
+                _sessionManager.OnPlaybackStopped(info);
+            }
+        }
+        
         /// <summary>
         /// Reports the playback stopped.
         /// </summary>
         /// <param name="message">The message.</param>
-        private void ReportPlaybackStopped(WebSocketMessageInfo message)
+        private void OnPlaybackStopped(WebSocketMessageInfo message)
         {
             _logger.Debug("Received PlaybackStopped message");
 
@@ -321,7 +380,7 @@ namespace MediaBrowser.Server.Implementations.Session
             {
                 var vals = message.Data.Split('|');
 
-                var item = _dtoService.GetItemByDtoId(vals[0]);
+                var itemId = vals[0];
 
                 long? positionTicks = null;
 
@@ -337,7 +396,7 @@ namespace MediaBrowser.Server.Implementations.Session
 
                 var info = new PlaybackStopInfo
                 {
-                    Item = item,
+                    ItemId = itemId,
                     PositionTicks = positionTicks,
                     SessionId = session.Id
                 };

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません