diff options
16 files changed, 145 insertions, 38 deletions
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 917d7faa9..5999a2b55 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1427,13 +1427,12 @@ namespace MediaBrowser.Api.Playback } else if (item is IChannelMediaItem) { - var channelMediaSources = await ChannelManager.GetChannelItemMediaSources(request.Id, CancellationToken.None).ConfigureAwait(false); - - var source = channelMediaSources.First(); + var source = await GetChannelMediaInfo(request.Id, CancellationToken.None).ConfigureAwait(false); state.IsInputVideo = string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase); state.IsRemote = source.IsRemote; state.MediaPath = source.Path; state.RunTimeTicks = item.RunTimeTicks; + mediaStreams = GetMediaStreams(source).ToList(); } else { @@ -1479,28 +1478,7 @@ namespace MediaBrowser.Api.Playback }).ToList(); - if (videoRequest != null) - { - if (string.IsNullOrEmpty(videoRequest.VideoCodec)) - { - videoRequest.VideoCodec = InferVideoCodec(url); - } - - state.VideoStream = GetMediaStream(mediaStreams, videoRequest.VideoStreamIndex, MediaStreamType.Video); - state.SubtitleStream = GetMediaStream(mediaStreams, videoRequest.SubtitleStreamIndex, MediaStreamType.Subtitle, false); - state.AudioStream = GetMediaStream(mediaStreams, videoRequest.AudioStreamIndex, MediaStreamType.Audio); - - if (state.VideoStream != null && state.VideoStream.IsInterlaced) - { - state.DeInterlace = true; - } - - EnforceResolutionLimit(state, videoRequest); - } - else - { - state.AudioStream = GetMediaStream(mediaStreams, null, MediaStreamType.Audio, true); - } + AttachMediaStreamInfo(state, mediaStreams, videoRequest, url); state.SegmentLength = state.ReadInputAtNativeFramerate ? 5 : 10; state.HlsListSize = state.ReadInputAtNativeFramerate ? 100 : 1440; @@ -1538,6 +1516,96 @@ namespace MediaBrowser.Api.Playback return state; } + private void AttachMediaStreamInfo(StreamState state, + List<MediaStream> mediaStreams, + VideoStreamRequest videoRequest, + string requestedUrl) + { + if (videoRequest != null) + { + if (string.IsNullOrEmpty(videoRequest.VideoCodec)) + { + videoRequest.VideoCodec = InferVideoCodec(requestedUrl); + } + + state.VideoStream = GetMediaStream(mediaStreams, videoRequest.VideoStreamIndex, MediaStreamType.Video); + state.SubtitleStream = GetMediaStream(mediaStreams, videoRequest.SubtitleStreamIndex, MediaStreamType.Subtitle, false); + state.AudioStream = GetMediaStream(mediaStreams, videoRequest.AudioStreamIndex, MediaStreamType.Audio); + + if (state.VideoStream != null && state.VideoStream.IsInterlaced) + { + state.DeInterlace = true; + } + + EnforceResolutionLimit(state, videoRequest); + } + else + { + state.AudioStream = GetMediaStream(mediaStreams, null, MediaStreamType.Audio, true); + } + } + + private IEnumerable<MediaStream> GetMediaStreams(ChannelMediaInfo info) + { + var list = new List<MediaStream>(); + + if (!string.IsNullOrWhiteSpace(info.VideoCodec) && + !string.IsNullOrWhiteSpace(info.AudioCodec)) + { + list.Add(new MediaStream + { + Type = MediaStreamType.Video, + Width = info.Width, + RealFrameRate = info.Framerate, + Profile = info.VideoProfile, + Level = info.VideoLevel, + Index = -1, + Height = info.Height, + Codec = info.VideoCodec, + BitRate = info.VideoBitrate, + AverageFrameRate = info.Framerate + }); + + list.Add(new MediaStream + { + Type = MediaStreamType.Audio, + Index = -1, + Codec = info.AudioCodec, + BitRate = info.AudioBitrate, + Channels = info.AudioChannels, + SampleRate = info.AudioSampleRate + }); + } + + return list; + } + + private async Task<ChannelMediaInfo> GetChannelMediaInfo(string id, CancellationToken cancellationToken) + { + var channelMediaSources = await ChannelManager.GetChannelItemMediaSources(id, cancellationToken) + .ConfigureAwait(false); + + var list = channelMediaSources.ToList(); + + var preferredWidth = ServerConfigurationManager.Configuration.ChannelOptions.PreferredStreamingWidth; + + if (preferredWidth.HasValue) + { + var val = preferredWidth.Value; + + return list + .OrderBy(i => Math.Abs(i.Width ?? 0 - val)) + .ThenByDescending(i => i.Width ?? 0) + .ThenBy(list.IndexOf) + .First(); + } + + return list + .OrderByDescending(i => i.Width ?? 0) + .ThenBy(list.IndexOf) + .First(); + } + private bool CanStreamCopyVideo(VideoStreamRequest request, MediaStream videoStream) { if (videoStream.IsInterlaced) diff --git a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs b/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs index e4ea186bd..895c43076 100644 --- a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs +++ b/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs @@ -170,7 +170,7 @@ namespace MediaBrowser.Common.Implementations.Updates // Let dev users get results more often for testing purposes var cacheLength = _config.CommonConfiguration.SystemUpdateLevel == PackageVersionClass.Dev ? TimeSpan.FromMinutes(3) - : TimeSpan.FromHours(4); + : TimeSpan.FromHours(6); if ((DateTime.UtcNow - _lastPackageListResult.Item2) < cacheLength) { diff --git a/MediaBrowser.Controller/Channels/ChannelMediaInfo.cs b/MediaBrowser.Controller/Channels/ChannelMediaInfo.cs index 363034267..b38ef363a 100644 --- a/MediaBrowser.Controller/Channels/ChannelMediaInfo.cs +++ b/MediaBrowser.Controller/Channels/ChannelMediaInfo.cs @@ -17,9 +17,14 @@ namespace MediaBrowser.Controller.Channels public int? Width { get; set; } public int? Height { get; set; } public int? AudioChannels { get; set; } + public int? AudioSampleRate { get; set; } public bool IsRemote { get; set; } + public string VideoProfile { get; set; } + public float? VideoLevel { get; set; } + public float? Framerate { get; set; } + public ChannelMediaInfo() { RequiredHttpHeaders = new Dictionary<string, string>(); diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs index 3ffdf1a93..eac2e0d9b 100644 --- a/MediaBrowser.Model/ApiClient/IApiClient.cs +++ b/MediaBrowser.Model/ApiClient/IApiClient.cs @@ -218,7 +218,7 @@ namespace MediaBrowser.Model.ApiClient /// </summary> /// <param name="itemId">The item identifier.</param> /// <returns>Task{BaseItemDto[]}.</returns> - Task<BaseItemDto[]> GetAdditionalParts(string itemId, string userId); + Task<ItemsResult> GetAdditionalParts(string itemId, string userId); /// <summary> /// Gets the users async. @@ -443,8 +443,9 @@ namespace MediaBrowser.Model.ApiClient /// <summary> /// Gets the system status async. /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{SystemInfo}.</returns> - Task<SystemInfo> GetSystemInfoAsync(); + Task<SystemInfo> GetSystemInfoAsync(CancellationToken cancellationToken); /// <summary> /// Gets a person diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 4fe5c8bcf..17c7e8b55 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -226,6 +226,8 @@ namespace MediaBrowser.Model.Configuration [Obsolete] public string[] ManualLoginClients { get; set; } + public ChannelOptions ChannelOptions { get; set; } + /// <summary> /// Initializes a new instance of the <see cref="ServerConfiguration" /> class. /// </summary> @@ -293,6 +295,13 @@ namespace MediaBrowser.Model.Configuration NotificationOptions = new NotificationOptions(); SubtitleOptions = new SubtitleOptions(); + + ChannelOptions = new ChannelOptions(); } } + + public class ChannelOptions + { + public int? PreferredStreamingWidth { get; set; } + } } diff --git a/MediaBrowser.Model/Extensions/DoubleHelper.cs b/MediaBrowser.Model/Extensions/DoubleHelper.cs index 203f2b7df..bcaf2d780 100644 --- a/MediaBrowser.Model/Extensions/DoubleHelper.cs +++ b/MediaBrowser.Model/Extensions/DoubleHelper.cs @@ -2,6 +2,9 @@ namespace MediaBrowser.Model.Extensions { + /// <summary> + /// Isolating these helpers allow this entire project to be easily converted to Java + /// </summary> public static class DoubleHelper { /// <summary> diff --git a/MediaBrowser.Model/Extensions/IntHelper.cs b/MediaBrowser.Model/Extensions/IntHelper.cs index 4a96e19d4..6c5f26080 100644 --- a/MediaBrowser.Model/Extensions/IntHelper.cs +++ b/MediaBrowser.Model/Extensions/IntHelper.cs @@ -2,6 +2,9 @@ namespace MediaBrowser.Model.Extensions { + /// <summary> + /// Isolating these helpers allow this entire project to be easily converted to Java + /// </summary> public static class IntHelper { /// <summary> diff --git a/MediaBrowser.Model/Extensions/StringHelper.cs b/MediaBrowser.Model/Extensions/StringHelper.cs index b3ebc3f22..1c086655f 100644 --- a/MediaBrowser.Model/Extensions/StringHelper.cs +++ b/MediaBrowser.Model/Extensions/StringHelper.cs @@ -3,6 +3,9 @@ using System.Globalization; namespace MediaBrowser.Model.Extensions { + /// <summary> + /// Isolating these helpers allow this entire project to be easily converted to Java + /// </summary> public static class StringHelper { /// <summary> diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs index 335366077..b9b9b8327 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs @@ -1,5 +1,4 @@ -using System.Globalization; -using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; @@ -519,7 +518,7 @@ namespace MediaBrowser.Server.Implementations.Channels { // Increment this as needed to force new downloads // Incorporate Name because it's being used to convert channel entity to provider - return externalId + (channelProvider.DataVersion ?? string.Empty) + (channelProvider.Name ?? string.Empty) + "13"; + return externalId + (channelProvider.DataVersion ?? string.Empty) + (channelProvider.Name ?? string.Empty) + "14"; } private async Task<BaseItem> GetChannelItemEntity(ChannelItemInfo info, IChannel channelProvider, Channel internalChannel, CancellationToken cancellationToken) diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index dae0470cf..88bf902db 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -1171,7 +1171,12 @@ namespace MediaBrowser.Server.Implementations.Dto LocationType = item.LocationType, Name = item.Name, Path = GetMappedPath(item), - MediaStreams = _itemRepo.GetMediaStreams(new MediaStreamQuery { ItemId = item.Id }).ToList(), + MediaStreams = _itemRepo.GetMediaStreams(new MediaStreamQuery + { + ItemId = item.Id + + }).ToList(), + RunTimeTicks = item.RunTimeTicks } }; diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index a31c53b50..a920b8e57 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -563,6 +563,7 @@ "LabelDefaultUser": "Default user:", "LabelDefaultUserHelp": "Determines which user library should be displayed on connected devices. This can be overridden for each device using profiles.", "TitleDlna": "DLNA", + "TitleChannels": "Channels", "HeaderServerSettings": "Server Settings", "LabelWeatherDisplayLocation": "Weather display location:", "LabelWeatherDisplayLocationHelp": "US zip code / City, State, Country / City, Country", @@ -796,5 +797,8 @@ "HeaderWelcomeToMediaBrowserWebClient": "Welcome to the Media Browser Web Client", "ButtonDismiss": "Dismiss", "MessageLearnHowToCustomize": "Learn how to customize this page to your own personal tastes. Click your user icon in the top right corner of the screen to view and update your preferences.", - "ButtonEditOtherUserPreferences": "Edit this user's personal preferences." + "ButtonEditOtherUserPreferences": "Edit this user's personal preferences.", + "ChannelStreamOptionBestAvailable": "Best available", + "LabelChannelStreamOptionBestAvailable": "Preferred streaming quality:", + "LabelChannelStreamOptionBestAvailableHelp": "Determines the selected quality when channel content is available in multiple resolutions." }
\ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 3f89c976c..7946e7319 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -539,6 +539,7 @@ namespace MediaBrowser.WebDashboard.Api "autoorganizelog.js", "channels.js", "channelitems.js", + "channelsettings.js", "dashboardgeneral.js", "dashboardinfo.js", "dashboardpage.js", diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index c4854ad11..d8fa2c9be 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -103,6 +103,9 @@ <Content Include="dashboard-ui\channels.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\channelsettings.html">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\css\chromecast.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -613,6 +616,9 @@ <Content Include="dashboard-ui\scripts\channels.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\scripts\channelsettings.js">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\scripts\chromecast.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index e934b1252..265b00dfc 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <metadata> <id>MediaBrowser.Common.Internal</id> - <version>3.0.388</version> + <version>3.0.391</version> <title>MediaBrowser.Common.Internal</title> <authors>Luke</authors> <owners>ebr,Luke,scottisafool</owners> @@ -12,7 +12,7 @@ <description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description> <copyright>Copyright © Media Browser 2013</copyright> <dependencies> - <dependency id="MediaBrowser.Common" version="3.0.388" /> + <dependency id="MediaBrowser.Common" version="3.0.391" /> <dependency id="NLog" version="2.1.0" /> <dependency id="SimpleInjector" version="2.5.0" /> <dependency id="sharpcompress" version="0.10.2" /> diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 3fe966d18..f2d4e4eec 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <metadata> <id>MediaBrowser.Common</id> - <version>3.0.388</version> + <version>3.0.391</version> <title>MediaBrowser.Common</title> <authors>Media Browser Team</authors> <owners>ebr,Luke,scottisafool</owners> diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index 3e186e60c..6a8991ae2 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <metadata> <id>MediaBrowser.Server.Core</id> - <version>3.0.388</version> + <version>3.0.391</version> <title>Media Browser.Server.Core</title> <authors>Media Browser Team</authors> <owners>ebr,Luke,scottisafool</owners> @@ -12,7 +12,7 @@ <description>Contains core components required to build plugins for Media Browser Server.</description> <copyright>Copyright © Media Browser 2013</copyright> <dependencies> - <dependency id="MediaBrowser.Common" version="3.0.388" /> + <dependency id="MediaBrowser.Common" version="3.0.391" /> </dependencies> </metadata> <files> |
