From 348b8c44142ce14a8395552f8d429fb9d0b24a36 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 26 Mar 2015 12:58:02 -0400 Subject: use server to build initial stream url's --- MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'MediaBrowser.Model.Portable') diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index c2d46b9b3f..118e5659ad 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -800,12 +800,15 @@ MediaInfo\IBlurayExaminer.cs - - MediaInfo\LiveMediaInfoResult.cs - MediaInfo\MediaProtocol.cs + + MediaInfo\PlaybackInfoRequest.cs + + + MediaInfo\PlaybackInfoResponse.cs + MediaInfo\SubtitleFormat.cs -- cgit v1.2.3 From 7e312e75bbb1324748319b29c9353716ed93a8da Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 26 Mar 2015 16:31:57 -0400 Subject: update stream sorting --- .../MediaBrowser.Model.Portable.csproj | 3 ++ .../MediaBrowser.Model.net35.csproj | 3 ++ MediaBrowser.Model/Dlna/StreamBuilder.cs | 24 +------------ MediaBrowser.Model/Dlna/StreamInfoSorter.cs | 40 ++++++++++++++++++++++ MediaBrowser.Model/MediaBrowser.Model.csproj | 1 + .../Drawing/ImageProcessor.cs | 6 ++-- .../Photos/BaseDynamicImageProvider.cs | 16 ++------- .../Udp/UdpServer.cs | 1 + Nuget/MediaBrowser.Common.Internal.nuspec | 4 +-- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Model.Signed.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 +-- SharedVersion.cs | 4 +-- 13 files changed, 61 insertions(+), 49 deletions(-) create mode 100644 MediaBrowser.Model/Dlna/StreamInfoSorter.cs (limited to 'MediaBrowser.Model.Portable') diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index 118e5659ad..ab77dc271b 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -413,6 +413,9 @@ Dlna\StreamInfo.cs + + Dlna\StreamInfoSorter.cs + Dlna\SubtitleDeliveryMethod.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index a97bf2a8c6..b772e17539 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -378,6 +378,9 @@ Dlna\StreamInfo.cs + + Dlna\StreamInfoSorter.cs + Dlna\SubtitleDeliveryMethod.cs diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 7338f604c0..62ac321fe3 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -89,29 +89,7 @@ namespace MediaBrowser.Model.Dlna private StreamInfo GetOptimalStream(List streams) { - // Grab the first one that can be direct streamed - // If that doesn't produce anything, just take the first - foreach (StreamInfo i in streams) - { - if (i.PlayMethod == PlayMethod.DirectPlay && i.MediaSource.Protocol == MediaProtocol.File) - { - return i; - } - } - foreach (StreamInfo i in streams) - { - if (i.PlayMethod == PlayMethod.DirectPlay) - { - return i; - } - } - foreach (StreamInfo i in streams) - { - if (i.PlayMethod == PlayMethod.DirectStream) - { - return i; - } - } + streams = StreamInfoSorter.SortMediaSources(streams); foreach (StreamInfo stream in streams) { diff --git a/MediaBrowser.Model/Dlna/StreamInfoSorter.cs b/MediaBrowser.Model/Dlna/StreamInfoSorter.cs new file mode 100644 index 0000000000..80eca193f5 --- /dev/null +++ b/MediaBrowser.Model/Dlna/StreamInfoSorter.cs @@ -0,0 +1,40 @@ +using MediaBrowser.Model.MediaInfo; +using MediaBrowser.Model.Session; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace MediaBrowser.Model.Dlna +{ + public class StreamInfoSorter + { + public static List SortMediaSources(List streams) + { + return streams.OrderBy(i => + { + switch (i.PlayMethod) + { + case PlayMethod.DirectPlay: + return 0; + case PlayMethod.DirectStream: + return 1; + case PlayMethod.Transcode: + return 2; + default: + throw new ArgumentException("Unrecognized PlayMethod"); + } + + }).ThenBy(i => + { + switch (i.MediaSource.Protocol) + { + case MediaProtocol.File: + return 0; + default: + return 1; + } + + }).ToList(); + } + } +} diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 30eec434db..fe67038df9 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -126,6 +126,7 @@ + diff --git a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs index a9affe1ec0..5474892e81 100644 --- a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs +++ b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs @@ -268,8 +268,6 @@ namespace MediaBrowser.Server.Implementations.Drawing originalImage.CurrentImage.CompressionQuality = quality; originalImage.SaveImage(cacheFilePath); - - return cacheFilePath; } } else @@ -286,8 +284,6 @@ namespace MediaBrowser.Server.Implementations.Drawing wand.CurrentImage.CompressionQuality = quality; wand.SaveImage(cacheFilePath); - - return cacheFilePath; } } } @@ -296,6 +292,8 @@ namespace MediaBrowser.Server.Implementations.Drawing { semaphore.Release(); } + + return cacheFilePath; } private ImageFormat GetOutputFormat(ImageFormat requestedFormat) diff --git a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs index 6fb02358e4..eac0cd96d9 100644 --- a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs +++ b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs @@ -223,8 +223,8 @@ namespace MediaBrowser.Server.Implementations.Photos protected virtual List GetFinalItems(List items, int limit) { - // Rotate the images no more than once per week - var random = new Random(GetWeekOfYear()).Next(); + // Rotate the images once every 7 days + var random = DateTime.Now.DayOfYear % 7; return items .OrderBy(i => (random + "" + items.IndexOf(i)).GetMD5()) @@ -233,18 +233,6 @@ namespace MediaBrowser.Server.Implementations.Photos .ToList(); } - private int GetWeekOfYear() - { - return DateTime.Now.Second; - var usCulture = new CultureInfo("en-US"); - var weekNo = usCulture.Calendar.GetWeekOfYear( - DateTime.Now, - usCulture.DateTimeFormat.CalendarWeekRule, - usCulture.DateTimeFormat.FirstDayOfWeek); - - return weekNo; - } - public int Order { get diff --git a/MediaBrowser.Server.Implementations/Udp/UdpServer.cs b/MediaBrowser.Server.Implementations/Udp/UdpServer.cs index 9dbffa9222..966129f4b9 100644 --- a/MediaBrowser.Server.Implementations/Udp/UdpServer.cs +++ b/MediaBrowser.Server.Implementations/Udp/UdpServer.cs @@ -51,6 +51,7 @@ namespace MediaBrowser.Server.Implementations.Udp AddMessageResponder("who is MediaBrowserServer?", RespondToV1Message); AddMessageResponder("who is MediaBrowserServer_v2?", RespondToV2Message); + AddMessageResponder("who is EmbyServer_v2?", RespondToV2Message); } private void AddMessageResponder(string message, Action responder) diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index 5f1c138b81..d229302bde 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.598 + 3.0.599 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption. Copyright © Media Browser 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index b5a0f3bba0..65205fa250 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.598 + 3.0.599 MediaBrowser.Common Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Model.Signed.nuspec b/Nuget/MediaBrowser.Model.Signed.nuspec index 085408f2e2..2e829b436a 100644 --- a/Nuget/MediaBrowser.Model.Signed.nuspec +++ b/Nuget/MediaBrowser.Model.Signed.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Model.Signed - 3.0.598 + 3.0.599 MediaBrowser.Model - Signed Edition Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index dca8aa61a0..f5d5b788bb 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.598 + 3.0.599 Media Browser.Server.Core Media Browser Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Media Browser Server. Copyright © Media Browser 2013 - + diff --git a/SharedVersion.cs b/SharedVersion.cs index 7528d4060b..fa4ca1ac7e 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -//[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5557.20000")] +[assembly: AssemblyVersion("3.0.*")] +//[assembly: AssemblyVersion("3.0.5557.20000")] -- cgit v1.2.3 From a79962b7ebfe59d837970581ac1b5f184b0aa42d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 29 Mar 2015 12:45:16 -0400 Subject: update live stream generation --- MediaBrowser.Api/Playback/BaseStreamingService.cs | 9 ++-- MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 4 +- MediaBrowser.Api/Playback/MediaInfoService.cs | 45 ++++++++++++----- .../Library/IMediaSourceManager.cs | 5 +- .../MediaBrowser.Model.Portable.csproj | 6 +++ .../MediaBrowser.Model.net35.csproj | 6 +++ MediaBrowser.Model/ApiClient/IConnectionManager.cs | 6 +++ MediaBrowser.Model/MediaBrowser.Model.csproj | 2 + MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs | 16 ++++++ MediaBrowser.Model/MediaInfo/LiveStreamResponse.cs | 9 ++++ .../Library/MediaSourceManager.cs | 27 ++++++---- .../Session/SessionManager.cs | 57 ++++++++++++++-------- .../ApplicationHost.cs | 2 +- 13 files changed, 145 insertions(+), 49 deletions(-) create mode 100644 MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs create mode 100644 MediaBrowser.Model/MediaInfo/LiveStreamResponse.cs (limited to 'MediaBrowser.Model.Portable') diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 2e7c9a5a7b..5a4cdaaa93 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -936,10 +936,13 @@ namespace MediaBrowser.Api.Playback if (state.MediaSource.RequiresOpening) { - var mediaSource = await MediaSourceManager.OpenLiveStream(state.MediaSource.OpenToken, false, cancellationTokenSource.Token) - .ConfigureAwait(false); + var liveStreamResponse = await MediaSourceManager.OpenLiveStream(new LiveStreamRequest + { + OpenToken = state.MediaSource.OpenToken + + }, false, cancellationTokenSource.Token).ConfigureAwait(false); - AttachMediaSourceInfo(state, mediaSource, state.VideoRequest, state.RequestedUrl); + AttachMediaSourceInfo(state, liveStreamResponse.MediaSource, state.VideoRequest, state.RequestedUrl); if (state.VideoRequest != null) { diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index b166bc319f..4f7c0444b2 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -698,7 +698,7 @@ namespace MediaBrowser.Api.Playback.Hls { var outputTsArg = Path.Combine(Path.GetDirectoryName(outputPath), Path.GetFileNameWithoutExtension(outputPath)) + "%d.ts"; - return string.Format("{0} {1} -map_metadata -1 -threads {2} {3} {4} -copyts -flags -global_header {5} -f segment -segment_time {6} -segment_start_number {7} -segment_list \"{8}\" -y \"{9}\"", + return string.Format("{0} {1} -map_metadata -1 -threads {2} {3} {4} -copyts -flags -global_header -sc_threshold 0 {5} -f segment -segment_time {6} -segment_start_number {7} -segment_list \"{8}\" -y \"{9}\"", inputModifier, GetInputArgument(state), threads, @@ -712,7 +712,7 @@ namespace MediaBrowser.Api.Playback.Hls ).Trim(); } - return string.Format("{0} {1} -map_metadata -1 -threads {2} {3} {4} -copyts -flags -global_header {5} -hls_time {6} -start_number {7} -hls_list_size {8} -y \"{9}\"", + return string.Format("{0} {1} -map_metadata -1 -threads {2} {3} {4} -copyts -flags -global_header -sc_threshold 0 {5} -hls_time {6} -start_number {7} -hls_list_size {8} -y \"{9}\"", inputModifier, GetInputArgument(state), threads, diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs index d954c5b197..6f8c2cc505 100644 --- a/MediaBrowser.Api/Playback/MediaInfoService.cs +++ b/MediaBrowser.Api/Playback/MediaInfoService.cs @@ -61,14 +61,12 @@ namespace MediaBrowser.Api.Playback public string MediaSourceId { get; set; } } - [Route("/MediaSources/Open", "POST", Summary = "Opens a media source")] - public class OpenMediaSource : IReturn + [Route("/LiveStreams/Open", "POST", Summary = "Opens a media source")] + public class OpenMediaSource : LiveStreamRequest, IReturn { - [ApiMember(Name = "OpenToken", Description = "OpenToken", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] - public string OpenToken { get; set; } } - [Route("/MediaSources/Close", "POST", Summary = "Closes a media source")] + [Route("/LiveStreams/Close", "POST", Summary = "Closes a media source")] public class CloseMediaSource : IReturnVoid { [ApiMember(Name = "LiveStreamId", Description = "LiveStreamId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] @@ -103,7 +101,32 @@ namespace MediaBrowser.Api.Playback public async Task Post(OpenMediaSource request) { - var result = await _mediaSourceManager.OpenLiveStream(request.OpenToken, false, CancellationToken.None).ConfigureAwait(false); + var authInfo = AuthorizationContext.GetAuthorizationInfo(Request); + + var result = await _mediaSourceManager.OpenLiveStream(request, false, CancellationToken.None).ConfigureAwait(false); + + var profile = request.DeviceProfile; + if (profile == null) + { + var caps = _deviceManager.GetCapabilities(authInfo.DeviceId); + if (caps != null) + { + profile = caps.DeviceProfile; + } + } + + if (profile != null) + { + var item = _libraryManager.GetItemById(request.ItemId); + + SetDeviceSpecificData(item, result.MediaSource, profile, authInfo, request.MaxStreamingBitrate, request.StartTimeTicks ?? 0, result.MediaSource.Id, request.AudioStreamIndex, request.SubtitleStreamIndex); + } + + if (!string.IsNullOrWhiteSpace(result.MediaSource.TranscodingUrl)) + { + result.MediaSource.TranscodingUrl += "&LiveStreamId=" + result.MediaSource.LiveStreamId; + } + return ToOptimizedResult(result); } @@ -177,11 +200,11 @@ namespace MediaBrowser.Api.Playback return result; } - private void SetDeviceSpecificData(string itemId, - PlaybackInfoResponse result, - DeviceProfile profile, - AuthorizationInfo auth, - int? maxBitrate, + private void SetDeviceSpecificData(string itemId, + PlaybackInfoResponse result, + DeviceProfile profile, + AuthorizationInfo auth, + int? maxBitrate, long startTimeTicks, string mediaSourceId, int? audioStreamIndex, diff --git a/MediaBrowser.Controller/Library/IMediaSourceManager.cs b/MediaBrowser.Controller/Library/IMediaSourceManager.cs index 292205c033..9cbbabc8db 100644 --- a/MediaBrowser.Controller/Library/IMediaSourceManager.cs +++ b/MediaBrowser.Controller/Library/IMediaSourceManager.cs @@ -2,6 +2,7 @@ using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.MediaInfo; using System; using System.Collections.Generic; using System.Threading; @@ -84,11 +85,11 @@ namespace MediaBrowser.Controller.Library /// /// Opens the media source. /// - /// The open token. + /// The request. /// if set to true [enable automatic close]. /// The cancellation token. /// Task<MediaSourceInfo>. - Task OpenLiveStream(string openToken, bool enableAutoClose, CancellationToken cancellationToken); + Task OpenLiveStream(LiveStreamRequest request, bool enableAutoClose, CancellationToken cancellationToken); /// /// Gets the live stream. diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index ab77dc271b..fdedc51a21 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -803,6 +803,12 @@ MediaInfo\IBlurayExaminer.cs + + MediaInfo\LiveStreamRequest.cs + + + MediaInfo\LiveStreamResponse.cs + MediaInfo\MediaProtocol.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index b772e17539..3618aa9728 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -759,6 +759,12 @@ MediaInfo\IBlurayExaminer.cs + + MediaInfo\LiveStreamRequest.cs + + + MediaInfo\LiveStreamResponse.cs + MediaInfo\MediaProtocol.cs diff --git a/MediaBrowser.Model/ApiClient/IConnectionManager.cs b/MediaBrowser.Model/ApiClient/IConnectionManager.cs index 84a815dfc0..f8837f15de 100644 --- a/MediaBrowser.Model/ApiClient/IConnectionManager.cs +++ b/MediaBrowser.Model/ApiClient/IConnectionManager.cs @@ -172,5 +172,11 @@ namespace MediaBrowser.Model.ApiClient /// if set to true [remember credentials]. /// Task. Task AuthenticateOffline(UserDto user, string password, bool rememberCredentials); + + /// + /// Gets the offline users. + /// + /// Task<List<UserDto>>. + Task> GetOfflineUsers(); } } diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index fe67038df9..0673095125 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -141,6 +141,8 @@ + + diff --git a/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs b/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs new file mode 100644 index 0000000000..8078219d82 --- /dev/null +++ b/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs @@ -0,0 +1,16 @@ +using MediaBrowser.Model.Dlna; + +namespace MediaBrowser.Model.MediaInfo +{ + public class LiveStreamRequest + { + public string OpenToken { get; set; } + public string UserId { get; set; } + public int? MaxStreamingBitrate { get; set; } + public long? StartTimeTicks { get; set; } + public int? AudioStreamIndex { get; set; } + public int? SubtitleStreamIndex { get; set; } + public string ItemId { get; set; } + public DeviceProfile DeviceProfile { get; set; } + } +} diff --git a/MediaBrowser.Model/MediaInfo/LiveStreamResponse.cs b/MediaBrowser.Model/MediaInfo/LiveStreamResponse.cs new file mode 100644 index 0000000000..e79e37a717 --- /dev/null +++ b/MediaBrowser.Model/MediaInfo/LiveStreamResponse.cs @@ -0,0 +1,9 @@ +using MediaBrowser.Model.Dto; + +namespace MediaBrowser.Model.MediaInfo +{ + public class LiveStreamResponse + { + public MediaSourceInfo MediaSource { get; set; } + } +} diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs index 3dbcf4aad4..64b1f2c89a 100644 --- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs @@ -1,5 +1,4 @@ -using System.Collections.Concurrent; -using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.MediaEncoding; @@ -8,13 +7,14 @@ using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Model.MediaInfo; +using MediaBrowser.Model.Serialization; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Server.Implementations.LiveTv; namespace MediaBrowser.Server.Implementations.Library { @@ -23,16 +23,18 @@ namespace MediaBrowser.Server.Implementations.Library private readonly IItemRepository _itemRepo; private readonly IUserManager _userManager; private readonly ILibraryManager _libraryManager; + private readonly IJsonSerializer _jsonSerializer; private IMediaSourceProvider[] _providers; private readonly ILogger _logger; - public MediaSourceManager(IItemRepository itemRepo, IUserManager userManager, ILibraryManager libraryManager, ILogger logger) + public MediaSourceManager(IItemRepository itemRepo, IUserManager userManager, ILibraryManager libraryManager, ILogger logger, IJsonSerializer jsonSerializer) { _itemRepo = itemRepo; _userManager = userManager; _libraryManager = libraryManager; _logger = logger; + _jsonSerializer = jsonSerializer; } public void AddParts(IEnumerable providers) @@ -317,13 +319,13 @@ namespace MediaBrowser.Server.Implementations.Library private readonly ConcurrentDictionary _openStreams = new ConcurrentDictionary(); private readonly SemaphoreSlim _liveStreamSemaphore = new SemaphoreSlim(1, 1); - public async Task OpenLiveStream(string openToken, bool enableAutoClose, CancellationToken cancellationToken) + public async Task OpenLiveStream(LiveStreamRequest request, bool enableAutoClose, CancellationToken cancellationToken) { await _liveStreamSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); try { - var tuple = GetProvider(openToken); + var tuple = GetProvider(request.OpenToken); var provider = tuple.Item1; var mediaSource = await provider.OpenMediaSource(tuple.Item2, cancellationToken).ConfigureAwait(false); @@ -344,12 +346,19 @@ namespace MediaBrowser.Server.Implementations.Library StartCloseTimer(); } - if (!string.IsNullOrWhiteSpace(mediaSource.TranscodingUrl)) + var json = _jsonSerializer.SerializeToString(mediaSource); + var clone = _jsonSerializer.DeserializeFromString(json); + + if (!string.IsNullOrWhiteSpace(request.UserId)) { - mediaSource.TranscodingUrl += "&LiveStreamId=" + mediaSource.LiveStreamId; + var user = _userManager.GetUserById(request.UserId); + SetUserProperties(clone, user); } - return mediaSource; + return new LiveStreamResponse + { + MediaSource = clone + }; } finally { diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index ec93ae8766..16fc420639 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -14,6 +14,7 @@ using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Security; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Devices; +using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Events; using MediaBrowser.Model.Library; @@ -304,13 +305,21 @@ namespace MediaBrowser.Server.Implementations.Session } } + private async Task GetMediaSource(BaseItem item, string mediaSourceId) + { + var sources = await _mediaSourceManager.GetPlayackMediaSources(item.Id.ToString("N"), false, CancellationToken.None) + .ConfigureAwait(false); + + return sources.FirstOrDefault(i => string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase)); + } + /// /// Updates the now playing item id. /// /// The session. /// The information. /// The library item. - private void UpdateNowPlayingItem(SessionInfo session, PlaybackProgressInfo info, BaseItem libraryItem) + private async Task UpdateNowPlayingItem(SessionInfo session, PlaybackProgressInfo info, BaseItem libraryItem) { if (string.IsNullOrWhiteSpace(info.MediaSourceId)) { @@ -319,29 +328,27 @@ namespace MediaBrowser.Server.Implementations.Session if (!string.IsNullOrWhiteSpace(info.ItemId) && info.Item == null && libraryItem != null) { - var runtimeTicks = libraryItem.RunTimeTicks; + var current = session.NowPlayingItem; - if (!string.Equals(info.ItemId, info.MediaSourceId) && - !string.IsNullOrWhiteSpace(info.MediaSourceId)) + if (current == null || !string.Equals(current.Id, info.ItemId, StringComparison.OrdinalIgnoreCase)) { - var runtimeItem = _libraryManager.GetItemById(new Guid(info.MediaSourceId)) ?? - _libraryManager.GetItemById(info.ItemId); + var runtimeTicks = libraryItem.RunTimeTicks; - runtimeTicks = runtimeItem.RunTimeTicks; - } + var mediaSource = await GetMediaSource(libraryItem, info.MediaSourceId).ConfigureAwait(false); - var current = session.NowPlayingItem; + if (mediaSource != null) + { + runtimeTicks = mediaSource.RunTimeTicks; + } - if (current == null || !string.Equals(current.Id, info.ItemId, StringComparison.OrdinalIgnoreCase)) - { - info.Item = GetItemInfo(libraryItem, libraryItem, info.MediaSourceId); + info.Item = GetItemInfo(libraryItem, libraryItem, mediaSource); + + info.Item.RunTimeTicks = runtimeTicks; } else { info.Item = current; } - - info.Item.RunTimeTicks = runtimeTicks; } session.NowPlayingItem = info.Item; @@ -432,6 +439,12 @@ namespace MediaBrowser.Server.Implementations.Session device = device ?? _deviceManager.GetDevice(deviceId); + if (device == null) + { + var userIdString = userId.HasValue ? userId.Value.ToString("N") : null; + device = await _deviceManager.RegisterDevice(deviceId, deviceName, appName, appVersion, userIdString).ConfigureAwait(false); + } + if (device != null) { if (!string.IsNullOrEmpty(device.CustomName)) @@ -570,7 +583,7 @@ namespace MediaBrowser.Server.Implementations.Session ? null : _libraryManager.GetItemById(new Guid(info.ItemId)); - UpdateNowPlayingItem(session, info, libraryItem); + await UpdateNowPlayingItem(session, info, libraryItem).ConfigureAwait(false); if (!string.IsNullOrEmpty(session.DeviceId) && info.PlayMethod != PlayMethod.Transcode) { @@ -652,7 +665,7 @@ namespace MediaBrowser.Server.Implementations.Session ? null : _libraryManager.GetItemById(new Guid(info.ItemId)); - UpdateNowPlayingItem(session, info, libraryItem); + await UpdateNowPlayingItem(session, info, libraryItem).ConfigureAwait(false); var users = GetUsers(session); @@ -731,7 +744,9 @@ namespace MediaBrowser.Server.Implementations.Session if (current == null || !string.Equals(current.Id, info.ItemId, StringComparison.OrdinalIgnoreCase)) { - info.Item = GetItemInfo(libraryItem, libraryItem, info.MediaSourceId); + var mediaSource = await GetMediaSource(libraryItem, info.MediaSourceId).ConfigureAwait(false); + + info.Item = GetItemInfo(libraryItem, libraryItem, mediaSource); } else { @@ -1439,10 +1454,10 @@ namespace MediaBrowser.Server.Implementations.Session /// /// The item. /// The chapter owner. - /// The media source identifier. + /// The media source. /// BaseItemInfo. /// item - private BaseItemInfo GetItemInfo(BaseItem item, BaseItem chapterOwner, string mediaSourceId) + private BaseItemInfo GetItemInfo(BaseItem item, BaseItem chapterOwner, MediaSourceInfo mediaSource) { if (item == null) { @@ -1593,9 +1608,9 @@ namespace MediaBrowser.Server.Implementations.Session info.Chapters = _dtoService.GetChapterInfoDtos(chapterOwner).ToList(); } - if (!string.IsNullOrWhiteSpace(mediaSourceId)) + if (mediaSource != null) { - info.MediaStreams = _mediaSourceManager.GetMediaStreams(mediaSourceId).ToList(); + info.MediaStreams = mediaSource.MediaStreams; } return info; diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 039c5edf38..aad88d022f 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -472,7 +472,7 @@ namespace MediaBrowser.Server.Startup.Common ChannelManager = new ChannelManager(UserManager, DtoService, LibraryManager, LogManager.GetLogger("ChannelManager"), ServerConfigurationManager, FileSystemManager, UserDataManager, JsonSerializer, LocalizationManager, HttpClient); RegisterSingleInstance(ChannelManager); - MediaSourceManager = new MediaSourceManager(ItemRepository, UserManager, LibraryManager, LogManager.GetLogger("MediaSourceManager")); + MediaSourceManager = new MediaSourceManager(ItemRepository, UserManager, LibraryManager, LogManager.GetLogger("MediaSourceManager"), JsonSerializer); RegisterSingleInstance(MediaSourceManager); SessionManager = new SessionManager(UserDataManager, LogManager.GetLogger("SessionManager"), UserRepository, LibraryManager, UserManager, musicManager, DtoService, ImageProcessor, JsonSerializer, this, HttpClient, AuthenticationRepository, DeviceManager, MediaSourceManager); -- cgit v1.2.3