rework media versions to be based on original item id

This commit is contained in:
Luke Pulverenti 2014-03-21 23:35:03 -04:00
parent 72917cc0b7
commit 327af0fe62
30 changed files with 325 additions and 133 deletions

View File

@ -1308,7 +1308,9 @@ namespace MediaBrowser.Api.Playback
RequestedUrl = url RequestedUrl = url
}; };
var item = DtoService.GetItemByDtoId(request.Id); var item = string.IsNullOrEmpty(request.MediaVersionId) ?
DtoService.GetItemByDtoId(request.Id) :
DtoService.GetItemByDtoId(request.MediaVersionId);
if (user != null && item.GetPlayAccess(user) != PlayAccess.Full) if (user != null && item.GetPlayAccess(user) != PlayAccess.Full)
{ {

View File

@ -15,6 +15,9 @@ namespace MediaBrowser.Api.Playback
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; } public string Id { get; set; }
[ApiMember(Name = "MediaVersionId", Description = "The media version id, if playing an alternate version", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string MediaVersionId { get; set; }
[ApiMember(Name = "DeviceId", Description = "The device id of the client requesting. Used to stop encoding processes when needed.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] [ApiMember(Name = "DeviceId", Description = "The device id of the client requesting. Used to stop encoding processes when needed.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string DeviceId { get; set; } public string DeviceId { get; set; }

View File

@ -241,6 +241,9 @@ namespace MediaBrowser.Api.UserLibrary
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
public string Id { get; set; } public string Id { get; set; }
[ApiMember(Name = "MediaVersionId", Description = "The id of the MediaVersion", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
public string MediaVersionId { get; set; }
/// <summary> /// <summary>
/// Gets or sets a value indicating whether this <see cref="UpdateUserItemRating" /> is likes. /// Gets or sets a value indicating whether this <see cref="UpdateUserItemRating" /> is likes.
/// </summary> /// </summary>
@ -277,6 +280,9 @@ namespace MediaBrowser.Api.UserLibrary
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
public string Id { get; set; } public string Id { get; set; }
[ApiMember(Name = "MediaVersionId", Description = "The id of the MediaVersion", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
public string MediaVersionId { get; set; }
/// <summary> /// <summary>
/// Gets or sets the position ticks. /// Gets or sets the position ticks.
/// </summary> /// </summary>
@ -312,6 +318,9 @@ namespace MediaBrowser.Api.UserLibrary
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")] [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
public string Id { get; set; } public string Id { get; set; }
[ApiMember(Name = "MediaVersionId", Description = "The id of the MediaVersion", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "DELETE")]
public string MediaVersionId { get; set; }
/// <summary> /// <summary>
/// Gets or sets the position ticks. /// Gets or sets the position ticks.
/// </summary> /// </summary>
@ -736,7 +745,8 @@ namespace MediaBrowser.Api.UserLibrary
CanSeek = request.CanSeek, CanSeek = request.CanSeek,
Item = item, Item = item,
SessionId = GetSession().Id, SessionId = GetSession().Id,
QueueableMediaTypes = queueableMediaTypes.Split(',').ToList() QueueableMediaTypes = queueableMediaTypes.Split(',').ToList(),
MediaVersionId = request.MediaVersionId
}; };
_sessionManager.OnPlaybackStart(info); _sessionManager.OnPlaybackStart(info);
@ -758,7 +768,8 @@ namespace MediaBrowser.Api.UserLibrary
PositionTicks = request.PositionTicks, PositionTicks = request.PositionTicks,
IsMuted = request.IsMuted, IsMuted = request.IsMuted,
IsPaused = request.IsPaused, IsPaused = request.IsPaused,
SessionId = GetSession().Id SessionId = GetSession().Id,
MediaVersionId = request.MediaVersionId
}; };
var task = _sessionManager.OnPlaybackProgress(info); var task = _sessionManager.OnPlaybackProgress(info);
@ -782,7 +793,8 @@ namespace MediaBrowser.Api.UserLibrary
{ {
Item = item, Item = item,
PositionTicks = request.PositionTicks, PositionTicks = request.PositionTicks,
SessionId = session.Id SessionId = session.Id,
MediaVersionId = request.MediaVersionId
}; };
var task = _sessionManager.OnPlaybackStopped(info); var task = _sessionManager.OnPlaybackStopped(info);

View File

@ -14,8 +14,7 @@ namespace MediaBrowser.Api.UserLibrary
/// <summary> /// <summary>
/// Class GetYears /// Class GetYears
/// </summary> /// </summary>
[Route("/Years", "GET")] [Route("/Years", "GET", Summary = "Gets all years from a given item, folder, or the entire library")]
[Api(Description = "Gets all years from a given item, folder, or the entire library")]
public class GetYears : GetItemsByName public class GetYears : GetItemsByName
{ {
} }
@ -23,8 +22,7 @@ namespace MediaBrowser.Api.UserLibrary
/// <summary> /// <summary>
/// Class GetYear /// Class GetYear
/// </summary> /// </summary>
[Route("/Years/{Year}", "GET")] [Route("/Years/{Year}", "GET", Summary = "Gets a year")]
[Api(Description = "Gets a year")]
public class GetYear : IReturn<BaseItemDto> public class GetYear : IReturn<BaseItemDto>
{ {
/// <summary> /// <summary>

View File

@ -13,8 +13,7 @@ using System.Threading.Tasks;
namespace MediaBrowser.Api namespace MediaBrowser.Api
{ {
[Route("/Videos/{Id}/AdditionalParts", "GET")] [Route("/Videos/{Id}/AdditionalParts", "GET", Summary = "Gets additional parts for a video.")]
[Api(Description = "Gets additional parts for a video.")]
public class GetAdditionalParts : IReturn<ItemsResult> public class GetAdditionalParts : IReturn<ItemsResult>
{ {
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] [ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
@ -28,16 +27,14 @@ namespace MediaBrowser.Api
public string Id { get; set; } public string Id { get; set; }
} }
[Route("/Videos/{Id}/AlternateVersions", "DELETE")] [Route("/Videos/{Id}/AlternateVersions", "DELETE", Summary = "Assigns videos as alternates of another.")]
[Api(Description = "Assigns videos as alternates of antoher.")]
public class DeleteAlternateVersions : IReturnVoid public class DeleteAlternateVersions : IReturnVoid
{ {
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")] [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
public string Id { get; set; } public string Id { get; set; }
} }
[Route("/Videos/MergeVersions", "POST")] [Route("/Videos/MergeVersions", "POST", Summary = "Merges videos into a single record")]
[Api(Description = "Merges videos into a single record")]
public class MergeVersions : IReturnVoid public class MergeVersions : IReturnVoid
{ {
[ApiMember(Name = "Ids", Description = "Item id list. This allows multiple, comma delimited.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST", AllowMultiple = true)] [ApiMember(Name = "Ids", Description = "Item id list. This allows multiple, comma delimited.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST", AllowMultiple = true)]

View File

@ -28,13 +28,6 @@ namespace MediaBrowser.Controller.Dto
/// <returns>SessionInfoDto.</returns> /// <returns>SessionInfoDto.</returns>
SessionInfoDto GetSessionInfoDto(SessionInfo session); SessionInfoDto GetSessionInfoDto(SessionInfo session);
/// <summary>
/// Gets the base item info.
/// </summary>
/// <param name="item">The item.</param>
/// <returns>BaseItemInfo.</returns>
BaseItemInfo GetBaseItemInfo(BaseItem item);
/// <summary> /// <summary>
/// Gets the dto id. /// Gets the dto id.
/// </summary> /// </summary>

View File

@ -12,6 +12,7 @@ namespace MediaBrowser.Controller.Library
public List<User> Users { get; set; } public List<User> Users { get; set; }
public long? PlaybackPositionTicks { get; set; } public long? PlaybackPositionTicks { get; set; }
public BaseItem Item { get; set; } public BaseItem Item { get; set; }
public string MediaVersionId { get; set; }
public PlaybackProgressEventArgs() public PlaybackProgressEventArgs()
{ {

View File

@ -34,5 +34,11 @@ namespace MediaBrowser.Controller.Session
/// </summary> /// </summary>
/// <value>The session id.</value> /// <value>The session id.</value>
public Guid SessionId { get; set; } public Guid SessionId { get; set; }
/// <summary>
/// Gets or sets the media version identifier.
/// </summary>
/// <value>The media version identifier.</value>
public string MediaVersionId { get; set; }
} }
} }

View File

@ -34,5 +34,11 @@ namespace MediaBrowser.Controller.Session
/// </summary> /// </summary>
/// <value>The position ticks.</value> /// <value>The position ticks.</value>
public long? PositionTicks { get; set; } public long? PositionTicks { get; set; }
/// <summary>
/// Gets or sets the media version identifier.
/// </summary>
/// <value>The media version identifier.</value>
public string MediaVersionId { get; set; }
} }
} }

View File

@ -22,5 +22,11 @@ namespace MediaBrowser.Controller.Session
/// </summary> /// </summary>
/// <value>The position ticks.</value> /// <value>The position ticks.</value>
public long? PositionTicks { get; set; } public long? PositionTicks { get; set; }
/// <summary>
/// Gets or sets the media version identifier.
/// </summary>
/// <value>The media version identifier.</value>
public string MediaVersionId { get; set; }
} }
} }

View File

@ -119,12 +119,24 @@ namespace MediaBrowser.Controller.Session
/// <value>The now playing item.</value> /// <value>The now playing item.</value>
public BaseItem NowPlayingItem { get; set; } 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 NowPlayingMediaVersionId { 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> /// <summary>
/// Gets or sets the now playing position ticks. /// Gets or sets the now playing position ticks.
/// </summary> /// </summary>
/// <value>The now playing position ticks.</value> /// <value>The now playing position ticks.</value>
public long? NowPlayingPositionTicks { get; set; } public long? NowPlayingPositionTicks { get; set; }
/// <summary> /// <summary>
/// Gets or sets a value indicating whether this instance is paused. /// Gets or sets a value indicating whether this instance is paused.
/// </summary> /// </summary>
@ -161,6 +173,18 @@ namespace MediaBrowser.Controller.Session
/// <value><c>true</c> if [supports fullscreen toggle]; otherwise, <c>false</c>.</value> /// <value><c>true</c> if [supports fullscreen toggle]; otherwise, <c>false</c>.</value>
public bool SupportsFullscreenToggle { get; set; } public bool SupportsFullscreenToggle { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [supports osd toggle].
/// </summary>
/// <value><c>true</c> if [supports osd toggle]; otherwise, <c>false</c>.</value>
public bool SupportsOsdToggle { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [supports navigation commands].
/// </summary>
/// <value><c>true</c> if [supports navigation commands]; otherwise, <c>false</c>.</value>
public bool SupportsNavigationControl { get; set; }
/// <summary> /// <summary>
/// Gets a value indicating whether this instance is active. /// Gets a value indicating whether this instance is active.
/// </summary> /// </summary>

View File

@ -69,12 +69,12 @@ namespace MediaBrowser.Dlna.PlayTo
_device.CurrentIdChanged += Device_CurrentIdChanged; _device.CurrentIdChanged += Device_CurrentIdChanged;
_device.Start(); _device.Start();
_updateTimer = new System.Threading.Timer(updateTimer_Elapsed, null, UpdateTimerIntervalMs, UpdateTimerIntervalMs); _updateTimer = new Timer(updateTimer_Elapsed, null, UpdateTimerIntervalMs, UpdateTimerIntervalMs);
} }
#region Device EventHandlers & Update Timer #region Device EventHandlers & Update Timer
System.Threading.Timer _updateTimer; Timer _updateTimer;
async void Device_PlaybackChanged(object sender, TransportStateEventArgs e) async void Device_PlaybackChanged(object sender, TransportStateEventArgs e)
{ {
@ -88,7 +88,7 @@ namespace MediaBrowser.Dlna.PlayTo
{ {
_playbackStarted = false; _playbackStarted = false;
await _sessionManager.OnPlaybackStopped(new PlaybackStopInfo await _sessionManager.OnPlaybackStopped(new Controller.Session.PlaybackStopInfo
{ {
Item = _currentItem, Item = _currentItem,
SessionId = _session.Id, SessionId = _session.Id,
@ -164,7 +164,7 @@ namespace MediaBrowser.Dlna.PlayTo
var playlistItem = Playlist.FirstOrDefault(p => p.PlayState == 1); var playlistItem = Playlist.FirstOrDefault(p => p.PlayState == 1);
if (playlistItem != null && playlistItem.Transcode) if (playlistItem != null && playlistItem.Transcode)
{ {
await _sessionManager.OnPlaybackProgress(new PlaybackProgressInfo await _sessionManager.OnPlaybackProgress(new Controller.Session.PlaybackProgressInfo
{ {
Item = _currentItem, Item = _currentItem,
SessionId = _session.Id, SessionId = _session.Id,
@ -176,7 +176,7 @@ namespace MediaBrowser.Dlna.PlayTo
} }
else if (_currentItem != null) else if (_currentItem != null)
{ {
await _sessionManager.OnPlaybackProgress(new PlaybackProgressInfo await _sessionManager.OnPlaybackProgress(new Controller.Session.PlaybackProgressInfo
{ {
Item = _currentItem, Item = _currentItem,
SessionId = _session.Id, SessionId = _session.Id,

View File

@ -428,6 +428,9 @@
<Compile Include="..\MediaBrowser.Model\Session\MessageCommand.cs"> <Compile Include="..\MediaBrowser.Model\Session\MessageCommand.cs">
<Link>Session\MessageCommand.cs</Link> <Link>Session\MessageCommand.cs</Link>
</Compile> </Compile>
<Compile Include="..\MediaBrowser.Model\Session\PlaybackReports.cs">
<Link>Session\PlaybackReports.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Session\PlayRequest.cs"> <Compile Include="..\MediaBrowser.Model\Session\PlayRequest.cs">
<Link>Session\PlayRequest.cs</Link> <Link>Session\PlayRequest.cs</Link>
</Compile> </Compile>

View File

@ -415,6 +415,9 @@
<Compile Include="..\MediaBrowser.Model\Session\MessageCommand.cs"> <Compile Include="..\MediaBrowser.Model\Session\MessageCommand.cs">
<Link>Session\MessageCommand.cs</Link> <Link>Session\MessageCommand.cs</Link>
</Compile> </Compile>
<Compile Include="..\MediaBrowser.Model\Session\PlaybackReports.cs">
<Link>Session\PlaybackReports.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Session\PlayRequest.cs"> <Compile Include="..\MediaBrowser.Model\Session\PlayRequest.cs">
<Link>Session\PlayRequest.cs</Link> <Link>Session\PlayRequest.cs</Link>
</Compile> </Compile>

View File

@ -538,35 +538,26 @@ namespace MediaBrowser.Model.ApiClient
/// <summary> /// <summary>
/// Reports to the server that the user has begun playing an item /// Reports to the server that the user has begun playing an item
/// </summary> /// </summary>
/// <param name="itemId">The item id.</param> /// <param name="info">The information.</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> /// <returns>Task{UserItemDataDto}.</returns>
/// <exception cref="ArgumentNullException">itemId</exception> /// <exception cref="ArgumentNullException">itemId</exception>
Task ReportPlaybackStartAsync(string itemId, string userId, bool isSeekable, List<string> queueableMediaTypes); Task ReportPlaybackStartAsync(PlaybackStartInfo info);
/// <summary> /// <summary>
/// Reports playback progress to the server /// Reports playback progress to the server
/// </summary> /// </summary>
/// <param name="itemId">The item id.</param> /// <param name="info">The information.</param>
/// <param name="userId">The user id.</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>
/// <returns>Task{UserItemDataDto}.</returns> /// <returns>Task{UserItemDataDto}.</returns>
/// <exception cref="ArgumentNullException">itemId</exception> /// <exception cref="ArgumentNullException">itemId</exception>
Task ReportPlaybackProgressAsync(string itemId, string userId, long? positionTicks, bool isPaused, bool isMuted); Task ReportPlaybackProgressAsync(PlaybackProgressInfo info);
/// <summary> /// <summary>
/// Reports to the server that the user has stopped playing an item /// Reports to the server that the user has stopped playing an item
/// </summary> /// </summary>
/// <param name="itemId">The item id.</param> /// <param name="info">The information.</param>
/// <param name="userId">The user id.</param>
/// <param name="positionTicks">The position ticks.</param>
/// <returns>Task{UserItemDataDto}.</returns> /// <returns>Task{UserItemDataDto}.</returns>
/// <exception cref="ArgumentNullException">itemId</exception> /// <exception cref="ArgumentNullException">itemId</exception>
Task ReportPlaybackStoppedAsync(string itemId, string userId, long? positionTicks); Task ReportPlaybackStoppedAsync(PlaybackStopInfo info);
/// <summary> /// <summary>
/// Instructs antoher client to browse to a library item. /// Instructs antoher client to browse to a library item.

View File

@ -147,7 +147,7 @@ namespace MediaBrowser.Model.Configuration
/// different directories and files. /// different directories and files.
/// </summary> /// </summary>
/// <value>The file watcher delay.</value> /// <value>The file watcher delay.</value>
public int RealtimeWatcherDelay { get; set; } public int RealtimeMonitorDelay { get; set; }
/// <summary> /// <summary>
/// Gets or sets a value indicating whether [enable dashboard response caching]. /// Gets or sets a value indicating whether [enable dashboard response caching].
@ -239,7 +239,7 @@ namespace MediaBrowser.Model.Configuration
MaxResumePct = 90; MaxResumePct = 90;
MinResumeDurationSeconds = Convert.ToInt32(TimeSpan.FromMinutes(5).TotalSeconds); MinResumeDurationSeconds = Convert.ToInt32(TimeSpan.FromMinutes(5).TotalSeconds);
RealtimeWatcherDelay = 20; RealtimeMonitorDelay = 30;
RecentItemDays = 10; RecentItemDays = 10;

View File

@ -5,7 +5,7 @@ namespace MediaBrowser.Model.Dto
{ {
public class MediaVersionInfo public class MediaVersionInfo
{ {
public string ItemId { get; set; } public string Id { get; set; }
public string Path { get; set; } public string Path { get; set; }
@ -23,8 +23,6 @@ namespace MediaBrowser.Model.Dto
public List<MediaStream> MediaStreams { get; set; } public List<MediaStream> MediaStreams { get; set; }
public List<ChapterInfoDto> Chapters { get; set; }
public bool IsPrimaryVersion { get; set; } public bool IsPrimaryVersion { get; set; }
} }
} }

View File

@ -69,6 +69,12 @@ namespace MediaBrowser.Model.Entities
/// </summary> /// </summary>
/// <value>The thumb item identifier.</value> /// <value>The thumb item identifier.</value>
public string BackdropItemId { get; set; } public string BackdropItemId { get; set; }
/// <summary>
/// Gets or sets the media version identifier.
/// </summary>
/// <value>The media version identifier.</value>
public string MediaVersionId { get; set; }
/// <summary> /// <summary>
/// Gets a value indicating whether this instance has primary image. /// Gets a value indicating whether this instance has primary image.

View File

@ -132,6 +132,7 @@
<Compile Include="Search\SearchQuery.cs" /> <Compile Include="Search\SearchQuery.cs" />
<Compile Include="Session\BrowseRequest.cs" /> <Compile Include="Session\BrowseRequest.cs" />
<Compile Include="Session\MessageCommand.cs" /> <Compile Include="Session\MessageCommand.cs" />
<Compile Include="Session\PlaybackReports.cs" />
<Compile Include="Session\PlayRequest.cs" /> <Compile Include="Session\PlayRequest.cs" />
<Compile Include="Session\PlaystateCommand.cs" /> <Compile Include="Session\PlaystateCommand.cs" />
<Compile Include="Logging\ILogManager.cs" /> <Compile Include="Logging\ILogManager.cs" />

View File

@ -0,0 +1,56 @@

namespace MediaBrowser.Model.Session
{
/// <summary>
/// Class PlaybackStartInfo.
/// </summary>
public class PlaybackStartInfo
{
public string UserId { get; set; }
public string ItemId { get; set; }
public string MediaVersionId { get; set; }
public bool IsSeekable { get; set; }
public string[] QueueableMediaTypes { get; set; }
public PlaybackStartInfo()
{
QueueableMediaTypes = new string[] { };
}
}
/// <summary>
/// Class PlaybackProgressInfo.
/// </summary>
public class PlaybackProgressInfo
{
public string UserId { get; set; }
public string ItemId { get; set; }
public string MediaVersionId { get; set; }
public long? PositionTicks { get; set; }
public bool IsPaused { get; set; }
public bool IsMuted { get; set; }
}
/// <summary>
/// Class PlaybackStopInfo.
/// </summary>
public class PlaybackStopInfo
{
public string UserId { get; set; }
public string ItemId { get; set; }
public string MediaVersionId { get; set; }
public long? PositionTicks { get; set; }
}
}

View File

@ -7,6 +7,10 @@ namespace MediaBrowser.Model.Session
public bool SupportsFullscreenToggle { get; set; } public bool SupportsFullscreenToggle { get; set; }
public bool SupportsOsdToggle { get; set; }
public bool SupportsNavigationControl { get; set; }
public SessionCapabilities() public SessionCapabilities()
{ {
PlayableMediaTypes = new string[] {}; PlayableMediaTypes = new string[] {};

View File

@ -1,8 +1,8 @@
using System.Diagnostics; using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Entities;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics;
namespace MediaBrowser.Model.Session namespace MediaBrowser.Model.Session
{ {
@ -147,6 +147,18 @@ namespace MediaBrowser.Model.Session
/// <value><c>true</c> if [supports remote control]; otherwise, <c>false</c>.</value> /// <value><c>true</c> if [supports remote control]; otherwise, <c>false</c>.</value>
public bool SupportsRemoteControl { get; set; } public bool SupportsRemoteControl { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [supports osd toggle].
/// </summary>
/// <value><c>true</c> if [supports osd toggle]; otherwise, <c>false</c>.</value>
public bool SupportsOsdToggle { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [supports navigation commands].
/// </summary>
/// <value><c>true</c> if [supports navigation commands]; otherwise, <c>false</c>.</value>
public bool SupportsNavigationControl { get; set; }
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
public SessionInfoDto() public SessionInfoDto()

View File

@ -267,12 +267,14 @@ namespace MediaBrowser.Server.Implementations.Dto
PlayableMediaTypes = session.PlayableMediaTypes, PlayableMediaTypes = session.PlayableMediaTypes,
RemoteEndPoint = session.RemoteEndPoint, RemoteEndPoint = session.RemoteEndPoint,
AdditionalUsers = session.AdditionalUsers, AdditionalUsers = session.AdditionalUsers,
SupportsFullscreenToggle = session.SupportsFullscreenToggle SupportsFullscreenToggle = session.SupportsFullscreenToggle,
SupportsNavigationControl = session.SupportsNavigationControl,
SupportsOsdToggle = session.SupportsOsdToggle
}; };
if (session.NowPlayingItem != null) if (session.NowPlayingItem != null)
{ {
dto.NowPlayingItem = GetBaseItemInfo(session.NowPlayingItem); dto.NowPlayingItem = GetNowPlayingInfo(session.NowPlayingItem, session.NowPlayingMediaVersionId, session.NowPlayingRunTimeTicks);
} }
if (session.UserId.HasValue) if (session.UserId.HasValue)
@ -288,9 +290,11 @@ namespace MediaBrowser.Server.Implementations.Dto
/// Converts a BaseItem to a BaseItemInfo /// Converts a BaseItem to a BaseItemInfo
/// </summary> /// </summary>
/// <param name="item">The item.</param> /// <param name="item">The item.</param>
/// <param name="mediaVersionId">The media version identifier.</param>
/// <param name="nowPlayingRuntimeTicks">The now playing runtime ticks.</param>
/// <returns>BaseItemInfo.</returns> /// <returns>BaseItemInfo.</returns>
/// <exception cref="System.ArgumentNullException">item</exception> /// <exception cref="System.ArgumentNullException">item</exception>
public BaseItemInfo GetBaseItemInfo(BaseItem item) private BaseItemInfo GetNowPlayingInfo(BaseItem item, string mediaVersionId, long? nowPlayingRuntimeTicks)
{ {
if (item == null) if (item == null)
{ {
@ -303,7 +307,8 @@ namespace MediaBrowser.Server.Implementations.Dto
Name = item.Name, Name = item.Name,
MediaType = item.MediaType, MediaType = item.MediaType,
Type = item.GetClientTypeName(), Type = item.GetClientTypeName(),
RunTimeTicks = item.RunTimeTicks RunTimeTicks = nowPlayingRuntimeTicks,
MediaVersionId = mediaVersionId
}; };
info.PrimaryImageTag = GetImageCacheTag(item, ImageType.Primary); info.PrimaryImageTag = GetImageCacheTag(item, ImageType.Primary);
@ -1103,9 +1108,7 @@ namespace MediaBrowser.Server.Implementations.Dto
if (dto.MediaVersions != null && dto.MediaVersions.Count > 0) if (dto.MediaVersions != null && dto.MediaVersions.Count > 0)
{ {
chapters = dto.MediaVersions.Where(i => i.IsPrimaryVersion) chapters = _itemRepo.GetChapters(item.Id).Select(c => GetChapterInfoDto(c, item)).ToList();
.SelectMany(i => i.Chapters)
.ToList();
} }
else else
{ {
@ -1292,24 +1295,25 @@ namespace MediaBrowser.Server.Implementations.Dto
private List<MediaVersionInfo> GetMediaVersions(Audio item) private List<MediaVersionInfo> GetMediaVersions(Audio item)
{ {
var result = new List<MediaVersionInfo>(); var result = new List<MediaVersionInfo>
{
result.Add(GetVersionInfo(item, true)); GetVersionInfo(item, true)
};
return result; return result;
} }
private MediaVersionInfo GetVersionInfo(Video i, bool isPrimary) private MediaVersionInfo GetVersionInfo(Video i, bool isPrimary)
{ {
var mediaStreams = _itemRepo.GetMediaStreams(new MediaStreamQuery {ItemId = i.Id}).ToList();
return new MediaVersionInfo return new MediaVersionInfo
{ {
Chapters = _itemRepo.GetChapters(i.Id).Select(c => GetChapterInfoDto(c, i)).ToList(), Id = i.Id.ToString("N"),
ItemId = i.Id.ToString("N"),
IsoType = i.IsoType, IsoType = i.IsoType,
LocationType = i.LocationType, LocationType = i.LocationType,
MediaStreams = _itemRepo.GetMediaStreams(new MediaStreamQuery { ItemId = i.Id }).ToList(), MediaStreams = mediaStreams,
Name = GetAlternateVersionName(i), Name = GetAlternateVersionName(i, mediaStreams),
Path = GetMappedPath(i), Path = GetMappedPath(i),
RunTimeTicks = i.RunTimeTicks, RunTimeTicks = i.RunTimeTicks,
Video3DFormat = i.Video3DFormat, Video3DFormat = i.Video3DFormat,
@ -1322,7 +1326,7 @@ namespace MediaBrowser.Server.Implementations.Dto
{ {
return new MediaVersionInfo return new MediaVersionInfo
{ {
ItemId = i.Id.ToString("N"), Id = i.Id.ToString("N"),
LocationType = i.LocationType, LocationType = i.LocationType,
MediaStreams = _itemRepo.GetMediaStreams(new MediaStreamQuery { ItemId = i.Id }).ToList(), MediaStreams = _itemRepo.GetMediaStreams(new MediaStreamQuery { ItemId = i.Id }).ToList(),
Name = i.Name, Name = i.Name,
@ -1351,32 +1355,29 @@ namespace MediaBrowser.Server.Implementations.Dto
return path; return path;
} }
private string GetAlternateVersionName(Video video) private string GetAlternateVersionName(Video video, List<MediaStream> mediaStreams)
{ {
var name = ""; var terms = new List<string>();
var videoStream = video.GetDefaultVideoStream(); var videoStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video);
var audioStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio);
if (video.Video3DFormat.HasValue) if (video.Video3DFormat.HasValue)
{ {
name = "3D " + name; terms.Add("3D");
name = name.Trim();
} }
if (video.VideoType == VideoType.BluRay) if (video.VideoType == VideoType.BluRay)
{ {
name = name + " " + "Bluray"; terms.Add("Bluray");
name = name.Trim();
} }
else if (video.VideoType == VideoType.Dvd) else if (video.VideoType == VideoType.Dvd)
{ {
name = name + " " + "DVD"; terms.Add("DVD");
name = name.Trim();
} }
else if (video.VideoType == VideoType.HdDvd) else if (video.VideoType == VideoType.HdDvd)
{ {
name = name + " " + "HD-DVD"; terms.Add("HD-DVD");
name = name.Trim();
} }
else if (video.VideoType == VideoType.Iso) else if (video.VideoType == VideoType.Iso)
{ {
@ -1384,18 +1385,17 @@ namespace MediaBrowser.Server.Implementations.Dto
{ {
if (video.IsoType.Value == IsoType.BluRay) if (video.IsoType.Value == IsoType.BluRay)
{ {
name = name + " " + "Bluray"; terms.Add("Bluray");
} }
else if (video.IsoType.Value == IsoType.Dvd) else if (video.IsoType.Value == IsoType.Dvd)
{ {
name = name + " " + "DVD"; terms.Add("DVD");
} }
} }
else else
{ {
name = name + " " + "ISO"; terms.Add("ISO");
} }
name = name.Trim();
} }
if (videoStream != null) if (videoStream != null)
@ -1404,44 +1404,45 @@ namespace MediaBrowser.Server.Implementations.Dto
{ {
if (videoStream.Width.Value >= 3800) if (videoStream.Width.Value >= 3800)
{ {
name = name + " " + "4K"; terms.Add("4K");
name = name.Trim();
} }
else if (videoStream.Width.Value >= 1900) else if (videoStream.Width.Value >= 1900)
{ {
name = name + " " + "1080P"; terms.Add("1080P");
name = name.Trim();
} }
else if (videoStream.Width.Value >= 1270) else if (videoStream.Width.Value >= 1270)
{ {
name = name + " " + "720P"; terms.Add("720P");
name = name.Trim();
} }
else if (videoStream.Width.Value >= 700) else if (videoStream.Width.Value >= 700)
{ {
name = name + " " + "480p"; terms.Add("480P");
name = name.Trim();
} }
else else
{ {
name = name + " " + "SD"; terms.Add("SD");
name = name.Trim();
} }
} }
} }
if (videoStream != null && !string.IsNullOrWhiteSpace(videoStream.Codec)) if (videoStream != null && !string.IsNullOrWhiteSpace(videoStream.Codec))
{ {
name = name + " " + videoStream.Codec.ToUpper(); terms.Add(videoStream.Codec.ToUpper());
name = name.Trim();
} }
if (string.IsNullOrWhiteSpace(name)) if (audioStream != null)
{ {
return video.Name; var audioCodec = string.Equals(audioStream.Codec, "dca", StringComparison.OrdinalIgnoreCase)
? audioStream.Profile
: audioStream.Codec;
if (!string.IsNullOrEmpty(audioCodec))
{
terms.Add(audioCodec.ToUpper());
}
} }
return name; return string.Join("/", terms.ToArray());
} }
private string GetMappedPath(string path) private string GetMappedPath(string path)

View File

@ -427,11 +427,11 @@ namespace MediaBrowser.Server.Implementations.IO
{ {
if (_updateTimer == null) if (_updateTimer == null)
{ {
_updateTimer = new Timer(TimerStopped, null, TimeSpan.FromSeconds(ConfigurationManager.Configuration.RealtimeWatcherDelay), TimeSpan.FromMilliseconds(-1)); _updateTimer = new Timer(TimerStopped, null, TimeSpan.FromSeconds(ConfigurationManager.Configuration.RealtimeMonitorDelay), TimeSpan.FromMilliseconds(-1));
} }
else else
{ {
_updateTimer.Change(TimeSpan.FromSeconds(ConfigurationManager.Configuration.RealtimeWatcherDelay), TimeSpan.FromMilliseconds(-1)); _updateTimer.Change(TimeSpan.FromSeconds(ConfigurationManager.Configuration.RealtimeMonitorDelay), TimeSpan.FromMilliseconds(-1));
} }
} }
} }

View File

@ -1,8 +1,10 @@
using MediaBrowser.Common.Net; using MediaBrowser.Common.Net;
using MediaBrowser.Controller; using MediaBrowser.Controller;
using MediaBrowser.Controller.Session; using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Serialization;
using System; using System;
using System.Collections.Generic;
namespace MediaBrowser.Server.Implementations.Roku namespace MediaBrowser.Server.Implementations.Roku
{ {
@ -23,6 +25,9 @@ namespace MediaBrowser.Server.Implementations.Roku
{ {
if (string.Equals(session.Client, "roku", StringComparison.OrdinalIgnoreCase)) if (string.Equals(session.Client, "roku", StringComparison.OrdinalIgnoreCase))
{ {
session.PlayableMediaTypes = new List<string> { MediaType.Video, MediaType.Audio };
session.SupportsFullscreenToggle = false;
return new RokuSessionController(_httpClient, _json, _appHost, session); return new RokuSessionController(_httpClient, _json, _appHost, session);
} }

View File

@ -218,15 +218,29 @@ namespace MediaBrowser.Server.Implementations.Session
/// </summary> /// </summary>
/// <param name="session">The session.</param> /// <param name="session">The session.</param>
/// <param name="item">The item.</param> /// <param name="item">The item.</param>
/// <param name="mediaVersionId">The media version identifier.</param>
/// <param name="isPaused">if set to <c>true</c> [is paused].</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="currentPositionTicks">The current position ticks.</param> /// <param name="currentPositionTicks">The current position ticks.</param>
private void UpdateNowPlayingItem(SessionInfo session, BaseItem item, bool isPaused, bool isMuted, long? currentPositionTicks = null) private void UpdateNowPlayingItem(SessionInfo session, BaseItem item, string mediaVersionId, bool isPaused, bool isMuted, long? currentPositionTicks = null)
{ {
session.IsMuted = isMuted; session.IsMuted = isMuted;
session.IsPaused = isPaused; session.IsPaused = isPaused;
session.NowPlayingPositionTicks = currentPositionTicks; session.NowPlayingPositionTicks = currentPositionTicks;
session.NowPlayingItem = item; session.NowPlayingItem = item;
session.LastActivityDate = DateTime.UtcNow; session.LastActivityDate = DateTime.UtcNow;
session.NowPlayingMediaVersionId = mediaVersionId;
if (string.IsNullOrWhiteSpace(mediaVersionId))
{
session.NowPlayingRunTimeTicks = item.RunTimeTicks;
}
else
{
var version = _libraryManager.GetItemById(new Guid(mediaVersionId));
session.NowPlayingRunTimeTicks = version.RunTimeTicks;
}
} }
/// <summary> /// <summary>
@ -246,6 +260,8 @@ namespace MediaBrowser.Server.Implementations.Session
session.NowPlayingItem = null; session.NowPlayingItem = null;
session.NowPlayingPositionTicks = null; session.NowPlayingPositionTicks = null;
session.IsPaused = false; session.IsPaused = false;
session.NowPlayingRunTimeTicks = null;
session.NowPlayingMediaVersionId = null;
} }
} }
@ -352,7 +368,9 @@ namespace MediaBrowser.Server.Implementations.Session
var item = info.Item; var item = info.Item;
UpdateNowPlayingItem(session, item, false, false); var mediaVersionId = GetMediaVersionId(item, info.MediaVersionId);
UpdateNowPlayingItem(session, item, mediaVersionId, false, false);
session.CanSeek = info.CanSeek; session.CanSeek = info.CanSeek;
session.QueueableMediaTypes = info.QueueableMediaTypes; session.QueueableMediaTypes = info.QueueableMediaTypes;
@ -371,7 +389,8 @@ namespace MediaBrowser.Server.Implementations.Session
EventHelper.QueueEventIfNotNull(PlaybackStart, this, new PlaybackProgressEventArgs EventHelper.QueueEventIfNotNull(PlaybackStart, this, new PlaybackProgressEventArgs
{ {
Item = item, Item = item,
Users = users Users = users,
MediaVersionId = info.MediaVersionId
}, _logger); }, _logger);
} }
@ -405,7 +424,7 @@ namespace MediaBrowser.Server.Implementations.Session
/// <returns>Task.</returns> /// <returns>Task.</returns>
/// <exception cref="System.ArgumentNullException"></exception> /// <exception cref="System.ArgumentNullException"></exception>
/// <exception cref="System.ArgumentOutOfRangeException">positionTicks</exception> /// <exception cref="System.ArgumentOutOfRangeException">positionTicks</exception>
public async Task OnPlaybackProgress(PlaybackProgressInfo info) public async Task OnPlaybackProgress(Controller.Session.PlaybackProgressInfo info)
{ {
if (info == null) if (info == null)
{ {
@ -419,7 +438,9 @@ namespace MediaBrowser.Server.Implementations.Session
var session = Sessions.First(i => i.Id.Equals(info.SessionId)); var session = Sessions.First(i => i.Id.Equals(info.SessionId));
UpdateNowPlayingItem(session, info.Item, info.IsPaused, info.IsMuted, info.PositionTicks); var mediaVersionId = GetMediaVersionId(info.Item, info.MediaVersionId);
UpdateNowPlayingItem(session, info.Item, mediaVersionId, info.IsPaused, info.IsMuted, info.PositionTicks);
var key = info.Item.GetUserDataKey(); var key = info.Item.GetUserDataKey();
@ -434,7 +455,8 @@ namespace MediaBrowser.Server.Implementations.Session
{ {
Item = info.Item, Item = info.Item,
Users = users, Users = users,
PlaybackPositionTicks = info.PositionTicks PlaybackPositionTicks = info.PositionTicks,
MediaVersionId = mediaVersionId
}, _logger); }, _logger);
} }
@ -458,7 +480,7 @@ namespace MediaBrowser.Server.Implementations.Session
/// <returns>Task.</returns> /// <returns>Task.</returns>
/// <exception cref="System.ArgumentNullException">info</exception> /// <exception cref="System.ArgumentNullException">info</exception>
/// <exception cref="System.ArgumentOutOfRangeException">positionTicks</exception> /// <exception cref="System.ArgumentOutOfRangeException">positionTicks</exception>
public async Task OnPlaybackStopped(PlaybackStopInfo info) public async Task OnPlaybackStopped(Controller.Session.PlaybackStopInfo info)
{ {
if (info == null) if (info == null)
{ {
@ -494,16 +516,32 @@ namespace MediaBrowser.Server.Implementations.Session
playedToCompletion = await OnPlaybackStopped(user.Id, key, info.Item, info.PositionTicks).ConfigureAwait(false); playedToCompletion = await OnPlaybackStopped(user.Id, key, info.Item, info.PositionTicks).ConfigureAwait(false);
} }
var mediaVersionId = GetMediaVersionId(info.Item, info.MediaVersionId);
EventHelper.QueueEventIfNotNull(PlaybackStopped, this, new PlaybackStopEventArgs EventHelper.QueueEventIfNotNull(PlaybackStopped, this, new PlaybackStopEventArgs
{ {
Item = info.Item, Item = info.Item,
Users = users, Users = users,
PlaybackPositionTicks = info.PositionTicks, PlaybackPositionTicks = info.PositionTicks,
PlayedToCompletion = playedToCompletion PlayedToCompletion = playedToCompletion,
MediaVersionId = mediaVersionId
}, _logger); }, _logger);
} }
private string GetMediaVersionId(BaseItem item, string reportedMediaVersionId)
{
if (string.IsNullOrWhiteSpace(reportedMediaVersionId))
{
if (item is Video || item is Audio)
{
reportedMediaVersionId = item.Id.ToString("N");
}
}
return reportedMediaVersionId;
}
private async Task<bool> OnPlaybackStopped(Guid userId, string userDataKey, BaseItem item, long? positionTicks) private async Task<bool> OnPlaybackStopped(Guid userId, string userDataKey, BaseItem item, long? positionTicks)
{ {
var data = _userDataRepository.GetUserData(userId, userDataKey); var data = _userDataRepository.GetUserData(userId, userDataKey);
@ -899,6 +937,8 @@ namespace MediaBrowser.Server.Implementations.Session
session.PlayableMediaTypes = capabilities.PlayableMediaTypes.ToList(); session.PlayableMediaTypes = capabilities.PlayableMediaTypes.ToList();
session.SupportsFullscreenToggle = capabilities.SupportsFullscreenToggle; session.SupportsFullscreenToggle = capabilities.SupportsFullscreenToggle;
session.SupportsOsdToggle = capabilities.SupportsOsdToggle;
session.SupportsNavigationControl = capabilities.SupportsNavigationControl;
} }
} }
} }

View File

@ -223,6 +223,11 @@ namespace MediaBrowser.Server.Implementations.Session
QueueableMediaTypes = queueableMediaTypes.Split(',').ToList() QueueableMediaTypes = queueableMediaTypes.Split(',').ToList()
}; };
if (vals.Length > 3)
{
info.MediaVersionId = vals[3];
}
_sessionManager.OnPlaybackStart(info); _sessionManager.OnPlaybackStart(info);
} }
} }
@ -265,6 +270,11 @@ namespace MediaBrowser.Server.Implementations.Session
SessionId = session.Id SessionId = session.Id
}; };
if (vals.Length > 4)
{
info.MediaVersionId = vals[4];
}
_sessionManager.OnPlaybackProgress(info); _sessionManager.OnPlaybackProgress(info);
} }
} }
@ -304,6 +314,11 @@ namespace MediaBrowser.Server.Implementations.Session
SessionId = session.Id SessionId = session.Id
}; };
if (vals.Length > 2)
{
info.MediaVersionId = vals[2];
}
_sessionManager.OnPlaybackStopped(info); _sessionManager.OnPlaybackStopped(info);
} }
} }

View File

@ -2191,20 +2191,6 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
}); });
}; };
/**
* Gets a list of all available conrete BaseItem types from the server
*/
self.getItemTypes = function (options) {
var url = self.getUrl("Library/ItemTypes", options);
return self.ajax({
type: "GET",
url: url,
dataType: "json"
});
};
/** /**
* Constructs a url for a user image * Constructs a url for a user image
* @param {String} userId * @param {String} userId
@ -3805,7 +3791,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
* @param {String} userId * @param {String} userId
* @param {String} itemId * @param {String} itemId
*/ */
self.reportPlaybackStart = function (userId, itemId, canSeek, queueableMediaTypes) { self.reportPlaybackStart = function (userId, itemId, mediaVersionId, canSeek, queueableMediaTypes) {
if (!userId) { if (!userId) {
throw new Error("null userId"); throw new Error("null userId");
@ -3823,6 +3809,10 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
var deferred = $.Deferred(); var deferred = $.Deferred();
var msg = [itemId, canSeek, queueableMediaTypes]; var msg = [itemId, canSeek, queueableMediaTypes];
if (mediaVersionId) {
msg.push(mediaVersionId);
}
self.sendWebSocketMessage("PlaybackStart", msg.join('|')); self.sendWebSocketMessage("PlaybackStart", msg.join('|'));
@ -3830,10 +3820,16 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
return deferred.promise(); return deferred.promise();
} }
var url = self.getUrl("Users/" + userId + "/PlayingItems/" + itemId, { var params = {
CanSeek: canSeek, CanSeek: canSeek,
QueueableMediaTypes: queueableMediaTypes QueueableMediaTypes: queueableMediaTypes
}); };
if (mediaVersionId) {
params.mediaVersionId = mediaVersionId;
}
var url = self.getUrl("Users/" + userId + "/PlayingItems/" + itemId, params);
return self.ajax({ return self.ajax({
type: "POST", type: "POST",
@ -3846,7 +3842,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
* @param {String} userId * @param {String} userId
* @param {String} itemId * @param {String} itemId
*/ */
self.reportPlaybackProgress = function (userId, itemId, positionTicks, isPaused, isMuted) { self.reportPlaybackProgress = function (userId, itemId, mediaVersionId, positionTicks, isPaused, isMuted) {
if (!userId) { if (!userId) {
throw new Error("null userId"); throw new Error("null userId");
@ -3860,7 +3856,12 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
var deferred = $.Deferred(); var deferred = $.Deferred();
var msgData = itemId + "|" + (positionTicks == null ? "" : positionTicks) + "|" + (isPaused == null ? "" : isPaused) + "|" + (isMuted == null ? "" : isMuted); var msgData = itemId;
msgData += "|" + (positionTicks == null ? "" : positionTicks);
msgData += "|" + (isPaused == null ? "" : isPaused);
msgData += "|" + (isMuted == null ? "" : isMuted);
msgData += "|" + (mediaVersionId == null ? "" : mediaVersionId);
self.sendWebSocketMessage("PlaybackProgress", msgData); self.sendWebSocketMessage("PlaybackProgress", msgData);
@ -3877,6 +3878,10 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
params.positionTicks = positionTicks; params.positionTicks = positionTicks;
} }
if (mediaVersionId) {
params.mediaVersionId = mediaVersionId;
}
var url = self.getUrl("Users/" + userId + "/PlayingItems/" + itemId + "/Progress", params); var url = self.getUrl("Users/" + userId + "/PlayingItems/" + itemId + "/Progress", params);
return self.ajax({ return self.ajax({
@ -3890,7 +3895,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
* @param {String} userId * @param {String} userId
* @param {String} itemId * @param {String} itemId
*/ */
self.reportPlaybackStopped = function (userId, itemId, positionTicks) { self.reportPlaybackStopped = function (userId, itemId, mediaVersionId, positionTicks) {
if (!userId) { if (!userId) {
throw new Error("null userId"); throw new Error("null userId");
@ -3904,20 +3909,26 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
var deferred = $.Deferred(); var deferred = $.Deferred();
self.sendWebSocketMessage("PlaybackStopped", itemId + "|" + (positionTicks == null ? "" : positionTicks)); var msg = itemId;
msg += "|" + (positionTicks == null ? "" : positionTicks);
msg += "|" + (mediaVersionId == null ? "" : mediaVersionId);
self.sendWebSocketMessage("PlaybackStopped", msg);
deferred.resolveWith(null, []); deferred.resolveWith(null, []);
return deferred.promise(); return deferred.promise();
} }
var params = { var params = {};
};
if (positionTicks) { if (positionTicks) {
params.positionTicks = positionTicks; params.positionTicks = positionTicks;
} }
if (mediaVersionId) {
params.mediaVersionId = mediaVersionId;
}
var url = self.getUrl("Users/" + userId + "/PlayingItems/" + itemId, params); var url = self.getUrl("Users/" + userId + "/PlayingItems/" + itemId, params);
return self.ajax({ return self.ajax({

View File

@ -84,9 +84,7 @@
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="ApiClient.js"> <EmbeddedResource Include="ApiClient.js" />
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<Content Include="dashboard-ui\advancedserversettings.html"> <Content Include="dashboard-ui\advancedserversettings.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.245" targetFramework="net45" /> <package id="MediaBrowser.ApiClient.Javascript" version="3.0.246" targetFramework="net45" />
</packages> </packages>