allow specification of m3u stream limit

pull/1154/head
Luke Pulverenti 7 years ago
parent ceee0cdcca
commit 1dc8ff9e91

@ -1052,10 +1052,27 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
{ {
_liveStreamsSemaphore.Release(); _liveStreamsSemaphore.Release();
} }
}
public async Task<List<ILiveStream>> 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<Tuple<ILiveStream, MediaSourceInfo, ITunerHost>> GetChannelStreamInternal(string channelId, string streamId, CancellationToken cancellationToken) private async Task<Tuple<ILiveStream, MediaSourceInfo>> GetChannelStreamInternal(string channelId, string streamId, CancellationToken cancellationToken)
{ {
_logger.Info("Streaming Channel " + channelId); _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); _logger.Info("Live stream {0} consumer count is now {1}", streamId, result.ConsumerCount);
return new Tuple<ILiveStream, MediaSourceInfo, ITunerHost>(result, openedMediaSource, result.TunerHost); return new Tuple<ILiveStream, MediaSourceInfo>(result, openedMediaSource);
} }
foreach (var hostInstance in _liveTvManager.TunerHosts) foreach (var hostInstance in _liveTvManager.TunerHosts)
@ -1086,13 +1103,12 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
result.SharedStreamIds.Add(openedMediaSource.Id); result.SharedStreamIds.Add(openedMediaSource.Id);
_liveStreams.Add(result); _liveStreams.Add(result);
result.TunerHost = hostInstance;
result.OriginalStreamId = streamId; result.OriginalStreamId = streamId;
_logger.Info("Returning mediasource streamId {0}, mediaSource.Id {1}, mediaSource.LiveStreamId {2}", _logger.Info("Returning mediasource streamId {0}, mediaSource.Id {1}, mediaSource.LiveStreamId {2}",
streamId, openedMediaSource.Id, openedMediaSource.LiveStreamId); streamId, openedMediaSource.Id, openedMediaSource.LiveStreamId);
return new Tuple<ILiveStream, MediaSourceInfo, ITunerHost>(result, openedMediaSource, hostInstance); return new Tuple<ILiveStream, MediaSourceInfo>(result, openedMediaSource);
} }
catch (FileNotFoundException) catch (FileNotFoundException)
{ {

@ -598,7 +598,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
if (hdhomerunChannel != null && hdhomerunChannel.IsLegacyTuner) 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 // 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; 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) public async Task Validate(TunerHostInfo info)

@ -11,6 +11,7 @@ using MediaBrowser.Model.Logging;
using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Net; using MediaBrowser.Model.Net;
using MediaBrowser.Model.System; using MediaBrowser.Model.System;
using MediaBrowser.Model.LiveTv;
namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{ {
@ -23,8 +24,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
private readonly int _numTuners; private readonly int _numTuners;
private readonly INetworkManager _networkManager; 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) 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, environment, fileSystem, logger, appPaths) : base(mediaSource, tunerHostInfo, environment, fileSystem, logger, appPaths)
{ {
_appHost = appHost; _appHost = appHost;
_socketFactory = socketFactory; _socketFactory = socketFactory;

@ -10,6 +10,7 @@ using MediaBrowser.Model.Dto;
using MediaBrowser.Model.IO; using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging; using MediaBrowser.Model.Logging;
using MediaBrowser.Model.System; using MediaBrowser.Model.System;
using MediaBrowser.Model.LiveTv;
namespace Emby.Server.Implementations.LiveTv.TunerHosts namespace Emby.Server.Implementations.LiveTv.TunerHosts
{ {
@ -21,7 +22,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
{ {
get { return SharedStreamIds.Count; } get { return SharedStreamIds.Count; }
} }
public ITunerHost TunerHost { get; set; }
public string OriginalStreamId { get; set; } public string OriginalStreamId { get; set; }
public bool EnableStreamSharing { get; set; } public bool EnableStreamSharing { get; set; }
public string UniqueId { get; private set; } public string UniqueId { get; private set; }
@ -35,7 +36,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
protected readonly ILogger Logger; protected readonly ILogger Logger;
protected readonly CancellationTokenSource LiveStreamCancellationTokenSource = new CancellationTokenSource(); 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; OriginalMediaSource = mediaSource;
Environment = environment; Environment = environment;
@ -45,6 +48,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
EnableStreamSharing = true; EnableStreamSharing = true;
SharedStreamIds = new List<string>(); SharedStreamIds = new List<string>();
UniqueId = Guid.NewGuid().ToString("N"); UniqueId = Guid.NewGuid().ToString("N");
TunerHostId = tuner.Id;
AppPaths = appPaths; AppPaths = appPaths;

@ -77,16 +77,28 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
protected override async Task<ILiveStream> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken) protected override async Task<ILiveStream> 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 sources = await GetChannelStreamMediaSources(info, channelId, cancellationToken).ConfigureAwait(false);
var mediaSource = sources.First(); var mediaSource = sources.First();
if (mediaSource.Protocol == MediaProtocol.Http && !mediaSource.RequiresLooping) 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) public async Task Validate(TunerHostInfo info)

@ -14,6 +14,7 @@ using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.System; using MediaBrowser.Model.System;
using System.Globalization; using System.Globalization;
using MediaBrowser.Controller.IO; using MediaBrowser.Controller.IO;
using MediaBrowser.Model.LiveTv;
namespace Emby.Server.Implementations.LiveTv.TunerHosts namespace Emby.Server.Implementations.LiveTv.TunerHosts
{ {
@ -22,8 +23,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
private readonly IHttpClient _httpClient; private readonly IHttpClient _httpClient;
private readonly IServerApplicationHost _appHost; private readonly IServerApplicationHost _appHost;
public SharedHttpStream(MediaSourceInfo mediaSource, string originalStreamId, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost, IEnvironmentInfo environment) public SharedHttpStream(MediaSourceInfo mediaSource, TunerHostInfo tunerHostInfo, string originalStreamId, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost, IEnvironmentInfo environment)
: base(mediaSource, environment, fileSystem, logger, appPaths) : base(mediaSource, tunerHostInfo, environment, fileSystem, logger, appPaths)
{ {
_httpClient = httpClient; _httpClient = httpClient;
_appHost = appHost; _appHost = appHost;

@ -63,8 +63,8 @@ namespace MediaBrowser.Controller.LiveTv
void Close(); void Close();
int ConsumerCount { get; } int ConsumerCount { get; }
string OriginalStreamId { get; set; } string OriginalStreamId { get; set; }
string TunerHostId { get; }
bool EnableStreamSharing { get; set; } bool EnableStreamSharing { get; set; }
ITunerHost TunerHost { get; set; }
MediaSourceInfo OpenedMediaSource { get; set; } MediaSourceInfo OpenedMediaSource { get; set; }
string UniqueId { get; } string UniqueId { get; }
List<string> SharedStreamIds { get; } List<string> SharedStreamIds { get; }

@ -1341,13 +1341,11 @@ namespace MediaBrowser.Model.Dlna
return false; return false;
} }
if (!item.Bitrate.HasValue) // If we don't know the bitrate, then force a transcode if requested max bitrate is under 40 mbps
{ var itemBitrate = item.Bitrate ??
_logger.Info("Cannot " + playMethod + " due to unknown content bitrate"); 40000000;
return false;
}
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)); _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; return false;

@ -47,6 +47,7 @@ namespace MediaBrowser.Model.LiveTv
public bool EnableStreamLooping { get; set; } public bool EnableStreamLooping { get; set; }
public bool EnableNewHdhrChannelIds { get; set; } public bool EnableNewHdhrChannelIds { get; set; }
public string Source { get; set; } public string Source { get; set; }
public int TunerCount { get; set; }
public TunerHostInfo() public TunerHostInfo()
{ {

@ -1,3 +1,3 @@
using System.Reflection; using System.Reflection;
[assembly: AssemblyVersion("3.2.36.11")] [assembly: AssemblyVersion("3.2.36.12")]

Loading…
Cancel
Save