From 3add1872c860cae14f85b339fef843ff962574aa Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 28 Mar 2015 14:55:00 -0400 Subject: make sure appVersion is set --- MediaBrowser.Server.Implementations/Session/SessionManager.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Session/SessionManager.cs') diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index f88e21aea..201e86fe2 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -1225,7 +1225,7 @@ namespace MediaBrowser.Server.Implementations.Session throw new UnauthorizedAccessException("Invalid user or password entered."); } - var token = await GetAuthorizationToken(user.Id.ToString("N"), request.DeviceId, request.App, request.DeviceName).ConfigureAwait(false); + var token = await GetAuthorizationToken(user.Id.ToString("N"), request.DeviceId, request.App, request.AppVersion, request.DeviceName).ConfigureAwait(false); EventHelper.FireEventIfNotNull(AuthenticationSucceeded, this, new GenericEventArgs(request), _logger); @@ -1246,7 +1246,7 @@ namespace MediaBrowser.Server.Implementations.Session }; } - private async Task GetAuthorizationToken(string userId, string deviceId, string app, string deviceName) + private async Task GetAuthorizationToken(string userId, string deviceId, string app, string appVersion, string deviceName) { var existing = _authRepo.Get(new AuthenticationInfoQuery { @@ -1265,6 +1265,7 @@ namespace MediaBrowser.Server.Implementations.Session var newToken = new AuthenticationInfo { AppName = app, + AppVersion = appVersion, DateCreated = DateTime.UtcNow, DeviceId = deviceId, DeviceName = deviceName, @@ -1690,6 +1691,12 @@ namespace MediaBrowser.Server.Implementations.Session deviceId = info.DeviceId; } + // Prevent argument exception + if (string.IsNullOrWhiteSpace(appVersion)) + { + appVersion = "1"; + } + return LogSessionActivity(appName, appVersion, deviceId, deviceName, remoteEndpoint, user); } -- cgit v1.2.3 From 87bf3bbb8fca91d254b5e9eab4a143cf96af4cac Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 29 Mar 2015 11:04:33 -0400 Subject: add device null check --- MediaBrowser.Server.Implementations/Session/SessionManager.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Session/SessionManager.cs') diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 201e86fe2..ec93ae876 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -432,9 +432,12 @@ namespace MediaBrowser.Server.Implementations.Session device = device ?? _deviceManager.GetDevice(deviceId); - if (!string.IsNullOrEmpty(device.CustomName)) + if (device != null) { - deviceName = device.CustomName; + if (!string.IsNullOrEmpty(device.CustomName)) + { + deviceName = device.CustomName; + } } sessionInfo.DeviceName = deviceName; -- 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.Server.Implementations/Session/SessionManager.cs') diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 2e7c9a5a7..5a4cdaaa9 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 b166bc319..4f7c0444b 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 d954c5b19..6f8c2cc50 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 292205c03..9cbbabc8d 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 ab77dc271..fdedc51a2 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 b772e1753..3618aa972 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 84a815dfc..f8837f15d 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 fe67038df..067309512 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 000000000..8078219d8 --- /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 000000000..e79e37a71 --- /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 3dbcf4aad..64b1f2c89 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 ec93ae876..16fc42063 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 039c5edf3..aad88d022 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 From dd8dd1938a990d9c4c9bac384665dc9d82c4bc35 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 29 Mar 2015 14:16:40 -0400 Subject: update live stream generation --- MediaBrowser.Api/ApiEntryPoint.cs | 2 +- MediaBrowser.Api/Playback/BaseStreamingService.cs | 4 ++++ MediaBrowser.Controller/LiveTv/LiveTvChannel.cs | 9 ++++++++ MediaBrowser.Model/ApiClient/IApiClient.cs | 7 +++++++ MediaBrowser.Model/Dlna/StreamInfo.cs | 3 +++ MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs | 19 +++++++++++++++++ MediaBrowser.Model/Session/PlaybackProgressInfo.cs | 5 +++++ MediaBrowser.Model/Session/PlaybackStopInfo.cs | 5 +++++ .../LiveTv/LiveTvManager.cs | 12 +++++++++-- .../Session/SessionManager.cs | 24 ++++++++++++++++++++++ Nuget/MediaBrowser.Common.Internal.nuspec | 4 ++-- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Model.Signed.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 ++-- 14 files changed, 93 insertions(+), 9 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Session/SessionManager.cs') diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index a6958b95d..9f4ad5893 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -187,7 +187,7 @@ namespace MediaBrowser.Api if (!string.IsNullOrWhiteSpace(deviceId)) { - var audioCodec = state.ActualOutputVideoCodec; + var audioCodec = state.ActualOutputAudioCodec; var videoCodec = state.ActualOutputVideoCodec; _sessionManager.ReportTranscodingInfo(deviceId, new TranscodingInfo diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 5a4cdaaa9..34c5e5f7c 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1513,6 +1513,10 @@ namespace MediaBrowser.Api.Playback { request.StreamId = val; } + else if (i == 22) + { + request.LiveStreamId = val; + } } } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs index 1e13d8f3f..cb10003ed 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs @@ -82,6 +82,15 @@ namespace MediaBrowser.Controller.LiveTv /// null if [has image] contains no value, true if [has image]; otherwise, false. public bool? HasProviderImage { get; set; } + public override LocationType LocationType + { + get + { + // TODO: This should be removed + return LocationType.Remote; + } + } + protected override string CreateSortName() { double number = 0; diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs index 19d6acf33..58af01615 100644 --- a/MediaBrowser.Model/ApiClient/IApiClient.cs +++ b/MediaBrowser.Model/ApiClient/IApiClient.cs @@ -1486,5 +1486,12 @@ namespace MediaBrowser.Model.ApiClient /// The query. /// Task<List<RecommendationDto>>. Task> GetMovieRecommendations(MovieRecommendationQuery query); + /// + /// Opens the live stream. + /// + /// The request. + /// The cancellation token. + /// Task<LiveStreamResponse>. + Task OpenLiveStream(LiveStreamRequest request, CancellationToken cancellationToken); } } \ No newline at end of file diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index 60615d1da..dc2462796 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -210,6 +210,9 @@ namespace MediaBrowser.Model.Dlna list.Add(new NameValuePair("StreamId", streamId ?? string.Empty)); list.Add(new NameValuePair("api_key", accessToken ?? string.Empty)); + string liveStreamId = item.MediaSource == null ? null : item.MediaSource.LiveStreamId; + list.Add(new NameValuePair("LiveStreamId", liveStreamId ?? string.Empty)); + return list; } diff --git a/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs b/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs index 8078219d8..563006a4d 100644 --- a/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs +++ b/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs @@ -12,5 +12,24 @@ namespace MediaBrowser.Model.MediaInfo public int? SubtitleStreamIndex { get; set; } public string ItemId { get; set; } public DeviceProfile DeviceProfile { get; set; } + + public LiveStreamRequest() + { + + } + + public LiveStreamRequest(AudioOptions options) + { + MaxStreamingBitrate = options.MaxBitrate; + ItemId = options.ItemId; + DeviceProfile = options.Profile; + + VideoOptions videoOptions = options as VideoOptions; + if (videoOptions != null) + { + AudioStreamIndex = videoOptions.AudioStreamIndex; + SubtitleStreamIndex = videoOptions.SubtitleStreamIndex; + } + } } } diff --git a/MediaBrowser.Model/Session/PlaybackProgressInfo.cs b/MediaBrowser.Model/Session/PlaybackProgressInfo.cs index f04dea1ea..a029df4a9 100644 --- a/MediaBrowser.Model/Session/PlaybackProgressInfo.cs +++ b/MediaBrowser.Model/Session/PlaybackProgressInfo.cs @@ -78,5 +78,10 @@ namespace MediaBrowser.Model.Session /// /// The play method. public PlayMethod PlayMethod { get; set; } + /// + /// Gets or sets the live stream identifier. + /// + /// The live stream identifier. + public string LiveStreamId { get; set; } } } \ No newline at end of file diff --git a/MediaBrowser.Model/Session/PlaybackStopInfo.cs b/MediaBrowser.Model/Session/PlaybackStopInfo.cs index 38025f183..a3bdc9a96 100644 --- a/MediaBrowser.Model/Session/PlaybackStopInfo.cs +++ b/MediaBrowser.Model/Session/PlaybackStopInfo.cs @@ -36,5 +36,10 @@ namespace MediaBrowser.Model.Session /// /// The position ticks. public long? PositionTicks { get; set; } + /// + /// Gets or sets the live stream identifier. + /// + /// The live stream identifier. + public string LiveStreamId { get; set; } } } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 86b31e0e5..b30db6092 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -356,7 +356,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv _logger.Info("Opening channel stream from {0}, external channel Id: {1}", service.Name, channel.ExternalId); info = await service.GetChannelStream(channel.ExternalId, null, cancellationToken).ConfigureAwait(false); info.RequiresClosing = true; - info.LiveStreamId = info.Id; + + if (info.RequiresClosing) + { + info.LiveStreamId = info.Id; + } } else { @@ -367,7 +371,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv _logger.Info("Opening recording stream from {0}, external recording Id: {1}", service.Name, recording.RecordingInfo.Id); info = await service.GetRecordingStream(recording.RecordingInfo.Id, null, cancellationToken).ConfigureAwait(false); info.RequiresClosing = true; - info.LiveStreamId = info.Id; + + if (info.RequiresClosing) + { + info.LiveStreamId = info.Id; + } } _logger.Info("Live stream info: {0}", _jsonSerializer.SerializeToString(info)); diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 16fc42063..cc5aef54a 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -679,6 +679,18 @@ namespace MediaBrowser.Server.Implementations.Session } } + if (!string.IsNullOrWhiteSpace(info.LiveStreamId)) + { + try + { + await _mediaSourceManager.PingLiveStream(info.LiveStreamId, CancellationToken.None).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error closing live stream", ex); + } + } + EventHelper.FireEventIfNotNull(PlaybackProgress, this, new PlaybackProgressEventArgs { Item = libraryItem, @@ -769,6 +781,18 @@ namespace MediaBrowser.Server.Implementations.Session } } + if (!string.IsNullOrWhiteSpace(info.LiveStreamId)) + { + try + { + await _mediaSourceManager.CloseLiveStream(info.LiveStreamId, CancellationToken.None).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error closing live stream", ex); + } + } + EventHelper.QueueEventIfNotNull(PlaybackStopped, this, new PlaybackStopEventArgs { Item = libraryItem, diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index e1659bfb2..ee3bdd2b6 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.603 + 3.0.606 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption. Copyright © Emby 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 294bc519e..a8f3ea1f3 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.603 + 3.0.606 MediaBrowser.Common Emby Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Model.Signed.nuspec b/Nuget/MediaBrowser.Model.Signed.nuspec index bcbd1d5be..7bd4a090d 100644 --- a/Nuget/MediaBrowser.Model.Signed.nuspec +++ b/Nuget/MediaBrowser.Model.Signed.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Model.Signed - 3.0.603 + 3.0.606 MediaBrowser.Model - Signed Edition Emby Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index ee3925db5..3f39ace9d 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.603 + 3.0.606 Media Browser.Server.Core Emby Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Emby Server. Copyright © Emby 2013 - + -- cgit v1.2.3 From 72023207a43d66035d8868f986ceabdc8f1912f4 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 2 Apr 2015 12:24:59 -0400 Subject: fix hasMediaSources exception --- .../Session/SessionManager.cs | 35 ++++++++++++++-------- 1 file changed, 23 insertions(+), 12 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Session/SessionManager.cs') diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index cc5aef54a..7f5033b98 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -305,7 +305,7 @@ namespace MediaBrowser.Server.Implementations.Session } } - private async Task GetMediaSource(BaseItem item, string mediaSourceId) + private async Task GetMediaSource(IHasMediaSources item, string mediaSourceId) { var sources = await _mediaSourceManager.GetPlayackMediaSources(item.Id.ToString("N"), false, CancellationToken.None) .ConfigureAwait(false); @@ -334,11 +334,16 @@ namespace MediaBrowser.Server.Implementations.Session { var runtimeTicks = libraryItem.RunTimeTicks; - var mediaSource = await GetMediaSource(libraryItem, info.MediaSourceId).ConfigureAwait(false); - - if (mediaSource != null) + MediaSourceInfo mediaSource = null; + var hasMediaSources = libraryItem as IHasMediaSources; + if (hasMediaSources != null) { - runtimeTicks = mediaSource.RunTimeTicks; + mediaSource = await GetMediaSource(hasMediaSources, info.MediaSourceId).ConfigureAwait(false); + + if (mediaSource != null) + { + runtimeTicks = mediaSource.RunTimeTicks; + } } info.Item = GetItemInfo(libraryItem, libraryItem, mediaSource); @@ -414,12 +419,12 @@ namespace MediaBrowser.Server.Implementations.Session if (!_activeConnections.TryGetValue(key, out sessionInfo)) { sessionInfo = new SessionInfo - { - Client = appName, - DeviceId = deviceId, - ApplicationVersion = appVersion, - Id = key.GetMD5().ToString("N") - }; + { + Client = appName, + DeviceId = deviceId, + ApplicationVersion = appVersion, + Id = key.GetMD5().ToString("N") + }; sessionInfo.DeviceName = deviceName; sessionInfo.UserId = userId; @@ -756,7 +761,13 @@ namespace MediaBrowser.Server.Implementations.Session if (current == null || !string.Equals(current.Id, info.ItemId, StringComparison.OrdinalIgnoreCase)) { - var mediaSource = await GetMediaSource(libraryItem, info.MediaSourceId).ConfigureAwait(false); + MediaSourceInfo mediaSource = null; + + var hasMediaSources = libraryItem as IHasMediaSources; + if (hasMediaSources != null) + { + mediaSource = await GetMediaSource(hasMediaSources, info.MediaSourceId).ConfigureAwait(false); + } info.Item = GetItemInfo(libraryItem, libraryItem, mediaSource); } -- cgit v1.2.3