From 1dc8ff9e910c3bd34960a2b2e8f9b3e633c28620 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 17 Nov 2017 16:54:33 -0500 Subject: [PATCH] allow specification of m3u stream limit --- .../LiveTv/EmbyTV/EmbyTV.cs | 24 +++++++++++++++---- .../TunerHosts/HdHomerun/HdHomerunHost.cs | 6 ++--- .../HdHomerun/HdHomerunUdpStream.cs | 5 ++-- .../LiveTv/TunerHosts/LiveStream.cs | 8 +++++-- .../LiveTv/TunerHosts/M3UTunerHost.cs | 16 +++++++++++-- .../LiveTv/TunerHosts/SharedHttpStream.cs | 5 ++-- MediaBrowser.Controller/LiveTv/ITunerHost.cs | 2 +- MediaBrowser.Model/Dlna/StreamBuilder.cs | 10 ++++---- MediaBrowser.Model/LiveTv/LiveTvOptions.cs | 1 + SharedVersion.cs | 2 +- 10 files changed, 56 insertions(+), 23 deletions(-) diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index b469966f5c..9992c71ecf 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -1052,10 +1052,27 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV { _liveStreamsSemaphore.Release(); } + } + + public async Task> GetLiveStreams(TunerHostInfo host, CancellationToken cancellationToken) + { + //await _liveStreamsSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); + + //try + //{ + var hostId = host.Id; + return _liveStreams + .Where(i => string.Equals(i.TunerHostId, hostId, StringComparison.OrdinalIgnoreCase)) + .ToList(); + //} + //finally + //{ + // _liveStreamsSemaphore.Release(); + //} } - private async Task> GetChannelStreamInternal(string channelId, string streamId, CancellationToken cancellationToken) + private async Task> GetChannelStreamInternal(string channelId, string streamId, CancellationToken cancellationToken) { _logger.Info("Streaming Channel " + channelId); @@ -1072,7 +1089,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV _logger.Info("Live stream {0} consumer count is now {1}", streamId, result.ConsumerCount); - return new Tuple(result, openedMediaSource, result.TunerHost); + return new Tuple(result, openedMediaSource); } foreach (var hostInstance in _liveTvManager.TunerHosts) @@ -1086,13 +1103,12 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV result.SharedStreamIds.Add(openedMediaSource.Id); _liveStreams.Add(result); - result.TunerHost = hostInstance; result.OriginalStreamId = streamId; _logger.Info("Returning mediasource streamId {0}, mediaSource.Id {1}, mediaSource.LiveStreamId {2}", streamId, openedMediaSource.Id, openedMediaSource.LiveStreamId); - return new Tuple(result, openedMediaSource, hostInstance); + return new Tuple(result, openedMediaSource); } catch (FileNotFoundException) { diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 08eab9a35b..74758e906c 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -598,7 +598,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun if (hdhomerunChannel != null && hdhomerunChannel.IsLegacyTuner) { - return new HdHomerunUdpStream(mediaSource, streamId, new LegacyHdHomerunChannelCommands(hdhomerunChannel.Path), modelInfo.TunerCount, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _socketFactory, _networkManager, _environment); + return new HdHomerunUdpStream(mediaSource, info, streamId, new LegacyHdHomerunChannelCommands(hdhomerunChannel.Path), modelInfo.TunerCount, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _socketFactory, _networkManager, _environment); } // The UDP method is not working reliably on OSX, and on BSD it hasn't been tested yet @@ -618,10 +618,10 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun } mediaSource.Path = httpUrl; - return new SharedHttpStream(mediaSource, streamId, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _environment); + return new SharedHttpStream(mediaSource, info, streamId, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _environment); } - return new HdHomerunUdpStream(mediaSource, streamId, new HdHomerunChannelCommands(hdhomerunChannel.Number, profile), modelInfo.TunerCount, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _socketFactory, _networkManager, _environment); + return new HdHomerunUdpStream(mediaSource, info, streamId, new HdHomerunChannelCommands(hdhomerunChannel.Number, profile), modelInfo.TunerCount, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _socketFactory, _networkManager, _environment); } public async Task Validate(TunerHostInfo info) diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs index a329300804..6e93055be0 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs @@ -11,6 +11,7 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.Net; using MediaBrowser.Model.System; +using MediaBrowser.Model.LiveTv; namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun { @@ -23,8 +24,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun private readonly int _numTuners; private readonly INetworkManager _networkManager; - public HdHomerunUdpStream(MediaSourceInfo mediaSource, string originalStreamId, IHdHomerunChannelCommands channelCommands, int numTuners, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost, ISocketFactory socketFactory, INetworkManager networkManager, IEnvironmentInfo environment) - : base(mediaSource, environment, fileSystem, logger, appPaths) + public HdHomerunUdpStream(MediaSourceInfo mediaSource, TunerHostInfo tunerHostInfo, string originalStreamId, IHdHomerunChannelCommands channelCommands, int numTuners, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost, ISocketFactory socketFactory, INetworkManager networkManager, IEnvironmentInfo environment) + : base(mediaSource, tunerHostInfo, environment, fileSystem, logger, appPaths) { _appHost = appHost; _socketFactory = socketFactory; diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs index bec92716bb..f6758e94e2 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs @@ -10,6 +10,7 @@ using MediaBrowser.Model.Dto; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.System; +using MediaBrowser.Model.LiveTv; namespace Emby.Server.Implementations.LiveTv.TunerHosts { @@ -21,7 +22,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts { get { return SharedStreamIds.Count; } } - public ITunerHost TunerHost { get; set; } + public string OriginalStreamId { get; set; } public bool EnableStreamSharing { get; set; } public string UniqueId { get; private set; } @@ -35,7 +36,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts protected readonly ILogger Logger; protected readonly CancellationTokenSource LiveStreamCancellationTokenSource = new CancellationTokenSource(); - public LiveStream(MediaSourceInfo mediaSource, IEnvironmentInfo environment, IFileSystem fileSystem, ILogger logger, IServerApplicationPaths appPaths) + public string TunerHostId { get; private set; } + + public LiveStream(MediaSourceInfo mediaSource, TunerHostInfo tuner, IEnvironmentInfo environment, IFileSystem fileSystem, ILogger logger, IServerApplicationPaths appPaths) { OriginalMediaSource = mediaSource; Environment = environment; @@ -45,6 +48,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts EnableStreamSharing = true; SharedStreamIds = new List(); UniqueId = Guid.NewGuid().ToString("N"); + TunerHostId = tuner.Id; AppPaths = appPaths; diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index e41fb7fbeb..c96d1f3592 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -77,16 +77,28 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts protected override async Task GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken) { + var tunerCount = info.TunerCount; + + if (tunerCount > 0) + { + var liveStreams = await EmbyTV.EmbyTV.Current.GetLiveStreams(info, cancellationToken).ConfigureAwait(false); + + if (liveStreams.Count >= info.TunerCount) + { + throw new LiveTvConflictException(); + } + } + var sources = await GetChannelStreamMediaSources(info, channelId, cancellationToken).ConfigureAwait(false); var mediaSource = sources.First(); if (mediaSource.Protocol == MediaProtocol.Http && !mediaSource.RequiresLooping) { - return new SharedHttpStream(mediaSource, streamId, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _environment); + return new SharedHttpStream(mediaSource, info, streamId, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _environment); } - return new LiveStream(mediaSource, _environment, FileSystem, Logger, Config.ApplicationPaths); + return new LiveStream(mediaSource, info, _environment, FileSystem, Logger, Config.ApplicationPaths); } public async Task Validate(TunerHostInfo info) diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs index a33b0945b9..a3bfff7c17 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs @@ -14,6 +14,7 @@ using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.System; using System.Globalization; using MediaBrowser.Controller.IO; +using MediaBrowser.Model.LiveTv; namespace Emby.Server.Implementations.LiveTv.TunerHosts { @@ -22,8 +23,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts private readonly IHttpClient _httpClient; private readonly IServerApplicationHost _appHost; - public SharedHttpStream(MediaSourceInfo mediaSource, string originalStreamId, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost, IEnvironmentInfo environment) - : base(mediaSource, environment, fileSystem, logger, appPaths) + public SharedHttpStream(MediaSourceInfo mediaSource, TunerHostInfo tunerHostInfo, string originalStreamId, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost, IEnvironmentInfo environment) + : base(mediaSource, tunerHostInfo, environment, fileSystem, logger, appPaths) { _httpClient = httpClient; _appHost = appHost; diff --git a/MediaBrowser.Controller/LiveTv/ITunerHost.cs b/MediaBrowser.Controller/LiveTv/ITunerHost.cs index 523eec24ac..242011db06 100644 --- a/MediaBrowser.Controller/LiveTv/ITunerHost.cs +++ b/MediaBrowser.Controller/LiveTv/ITunerHost.cs @@ -63,8 +63,8 @@ namespace MediaBrowser.Controller.LiveTv void Close(); int ConsumerCount { get; } string OriginalStreamId { get; set; } + string TunerHostId { get; } bool EnableStreamSharing { get; set; } - ITunerHost TunerHost { get; set; } MediaSourceInfo OpenedMediaSource { get; set; } string UniqueId { get; } List SharedStreamIds { get; } diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index cf4cd99258..b80a2baa9f 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -1341,13 +1341,11 @@ namespace MediaBrowser.Model.Dlna return false; } - if (!item.Bitrate.HasValue) - { - _logger.Info("Cannot " + playMethod + " due to unknown content bitrate"); - return false; - } + // If we don't know the bitrate, then force a transcode if requested max bitrate is under 40 mbps + var itemBitrate = item.Bitrate ?? + 40000000; - if (item.Bitrate.Value > maxBitrate.Value) + if (itemBitrate > maxBitrate.Value) { _logger.Info("Bitrate exceeds " + playMethod + " limit: media bitrate: {0}, max bitrate: {1}", item.Bitrate.Value.ToString(CultureInfo.InvariantCulture), maxBitrate.Value.ToString(CultureInfo.InvariantCulture)); return false; diff --git a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs index f177233f9b..75edf05aa8 100644 --- a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs +++ b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs @@ -47,6 +47,7 @@ namespace MediaBrowser.Model.LiveTv public bool EnableStreamLooping { get; set; } public bool EnableNewHdhrChannelIds { get; set; } public string Source { get; set; } + public int TunerCount { get; set; } public TunerHostInfo() { diff --git a/SharedVersion.cs b/SharedVersion.cs index 6e59ea964c..070f8b1755 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,3 +1,3 @@ using System.Reflection; -[assembly: AssemblyVersion("3.2.36.11")] +[assembly: AssemblyVersion("3.2.36.12")]