update tuner pooling
This commit is contained in:
parent
2c050d05f8
commit
8c32aefb53
|
@ -33,20 +33,18 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
/// <summary>
|
||||
/// Gets the channel stream.
|
||||
/// </summary>
|
||||
/// <param name="info">The information.</param>
|
||||
/// <param name="channelId">The channel identifier.</param>
|
||||
/// <param name="streamId">The stream identifier.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task<MediaSourceInfo>.</returns>
|
||||
Task<MediaSourceInfo> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken);
|
||||
Task<MediaSourceInfo> GetChannelStream(string channelId, string streamId, CancellationToken cancellationToken);
|
||||
/// <summary>
|
||||
/// Gets the channel stream media sources.
|
||||
/// </summary>
|
||||
/// <param name="info">The information.</param>
|
||||
/// <param name="channelId">The channel identifier.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task<List<MediaSourceInfo>>.</returns>
|
||||
Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken);
|
||||
Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken);
|
||||
/// <summary>
|
||||
/// Validates the specified information.
|
||||
/// </summary>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using MediaBrowser.Common;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Drawing;
|
||||
|
@ -13,7 +12,6 @@ using MediaBrowser.Model.Serialization;
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
@ -161,20 +159,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
return GetChannelsAsync(false, cancellationToken);
|
||||
}
|
||||
|
||||
private List<Tuple<ITunerHost, TunerHostInfo>> GetTunerHosts()
|
||||
{
|
||||
return GetConfiguration().TunerHosts
|
||||
.Where(i => i.IsEnabled)
|
||||
.Select(i =>
|
||||
{
|
||||
var provider = _liveTvManager.TunerHosts.FirstOrDefault(l => string.Equals(l.Type, i.Type, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
return provider == null ? null : new Tuple<ITunerHost, TunerHostInfo>(provider, i);
|
||||
})
|
||||
.Where(i => i != null)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public Task CancelSeriesTimerAsync(string timerId, CancellationToken cancellationToken)
|
||||
{
|
||||
var timers = _timerProvider.GetAll().Where(i => string.Equals(i.SeriesTimerId, timerId, StringComparison.OrdinalIgnoreCase));
|
||||
|
@ -409,22 +393,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
{
|
||||
_logger.Info("Streaming Channel " + channelId);
|
||||
|
||||
foreach (var hostInstance in GetTunerHosts())
|
||||
foreach (var hostInstance in _liveTvManager.TunerHosts)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(streamId))
|
||||
{
|
||||
var originalStreamId = string.Join("-", streamId.Split('-').Skip(1).ToArray());
|
||||
|
||||
if (!string.Equals(hostInstance.Item2.Id, originalStreamId, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
MediaSourceInfo mediaSourceInfo = null;
|
||||
try
|
||||
{
|
||||
mediaSourceInfo = await hostInstance.Item1.GetChannelStream(hostInstance.Item2, channelId, streamId, cancellationToken).ConfigureAwait(false);
|
||||
mediaSourceInfo = await hostInstance.GetChannelStream(channelId, streamId, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -443,16 +417,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
|
||||
public async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken)
|
||||
{
|
||||
foreach (var hostInstance in GetTunerHosts())
|
||||
foreach (var hostInstance in _liveTvManager.TunerHosts)
|
||||
{
|
||||
try
|
||||
{
|
||||
var sources = await hostInstance.Item1.GetChannelStreamMediaSources(hostInstance.Item2, channelId, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
foreach (var source in sources)
|
||||
{
|
||||
source.Id = hostInstance.Item2.Id + "-" + source.Id;
|
||||
}
|
||||
var sources = await hostInstance.GetChannelStreamMediaSources(channelId, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (sources.Count > 0)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.LiveTv;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.LiveTv;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System;
|
||||
|
@ -83,6 +84,110 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
|
|||
return list;
|
||||
}
|
||||
|
||||
protected abstract Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken);
|
||||
|
||||
public async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken)
|
||||
{
|
||||
if (IsValidChannelId(channelId))
|
||||
{
|
||||
var hosts = GetTunerHosts();
|
||||
|
||||
var hostsWithChannel = new List<TunerHostInfo>();
|
||||
|
||||
foreach (var host in hosts)
|
||||
{
|
||||
var channels = await GetChannels(host, true, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (channels.Any(i => string.Equals(i.Id, channelId, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
hostsWithChannel.Add(host);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var host in hostsWithChannel)
|
||||
{
|
||||
// Check to make sure the tuner is available
|
||||
// If there's only one tuner, don't bother with the check and just let the tuner be the one to throw an error
|
||||
if (hostsWithChannel.Count > 1 && !await IsAvailable(host, channelId, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
Logger.Error("Tuner is not currently available");
|
||||
continue;
|
||||
}
|
||||
|
||||
var mediaSources = await GetChannelStreamMediaSources(host, channelId, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// Prefix the id with the host Id so that we can easily find it
|
||||
foreach (var mediaSource in mediaSources)
|
||||
{
|
||||
mediaSource.Id = host.Id + mediaSource.Id;
|
||||
}
|
||||
|
||||
return mediaSources;
|
||||
}
|
||||
}
|
||||
|
||||
return new List<MediaSourceInfo>();
|
||||
}
|
||||
|
||||
protected abstract Task<MediaSourceInfo> GetChannelStream(TunerHostInfo tuner, string channelId, string streamId, CancellationToken cancellationToken);
|
||||
|
||||
public async Task<MediaSourceInfo> GetChannelStream(string channelId, string streamId, CancellationToken cancellationToken)
|
||||
{
|
||||
if (IsValidChannelId(channelId))
|
||||
{
|
||||
var hosts = GetTunerHosts();
|
||||
|
||||
var hostsWithChannel = new List<TunerHostInfo>();
|
||||
|
||||
foreach (var host in hosts)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(streamId))
|
||||
{
|
||||
var channels = await GetChannels(host, true, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (channels.Any(i => string.Equals(i.Id, channelId, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
hostsWithChannel.Add(host);
|
||||
}
|
||||
}
|
||||
else if (streamId.StartsWith(host.Id, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
hostsWithChannel = new List<TunerHostInfo> { host };
|
||||
streamId = streamId.Substring(host.Id.Length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var host in hostsWithChannel)
|
||||
{
|
||||
// Check to make sure the tuner is available
|
||||
// If there's only one tuner, don't bother with the check and just let the tuner be the one to throw an error
|
||||
// If a streamId is specified then availibility has already been checked in GetChannelStreamMediaSources
|
||||
if (string.IsNullOrWhiteSpace(streamId) && hostsWithChannel.Count > 1)
|
||||
{
|
||||
if (!await IsAvailable(host, channelId, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
Logger.Error("Tuner is not currently available");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
var stream = await GetChannelStream(host, channelId, streamId, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (stream != null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new LiveTvConflictException();
|
||||
}
|
||||
|
||||
protected abstract Task<bool> IsAvailable(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken);
|
||||
|
||||
protected abstract bool IsValidChannelId(string channelId);
|
||||
|
||||
protected LiveTvOptions GetConfiguration()
|
||||
{
|
||||
return Config.GetConfiguration<LiveTvOptions>("livetv");
|
||||
|
|
|
@ -329,7 +329,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||
return mediaSource;
|
||||
}
|
||||
|
||||
public async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken)
|
||||
protected override async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken)
|
||||
{
|
||||
var list = new List<MediaSourceInfo>();
|
||||
|
||||
|
@ -364,7 +364,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||
return list;
|
||||
}
|
||||
|
||||
public async Task<MediaSourceInfo> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken)
|
||||
protected override bool IsValidChannelId(string channelId)
|
||||
{
|
||||
return channelId.StartsWith(ChannelIdPrefix, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
protected override async Task<MediaSourceInfo> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken)
|
||||
{
|
||||
if (!channelId.StartsWith(ChannelIdPrefix, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
|
@ -379,5 +384,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||
{
|
||||
await GetChannels(info, false, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
protected override async Task<bool> IsAvailable(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken)
|
||||
{
|
||||
// TODO
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
|
|||
{
|
||||
public class M3UTunerHost : BaseTunerHost, ITunerHost
|
||||
{
|
||||
public M3UTunerHost(IConfigurationManager config, ILogger logger) : base(config, logger)
|
||||
public M3UTunerHost(IConfigurationManager config, ILogger logger)
|
||||
: base(config, logger)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -31,6 +32,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
|
|||
get { return "M3U Tuner"; }
|
||||
}
|
||||
|
||||
private const string ChannelIdPrefix = "m3u_";
|
||||
|
||||
protected override async Task<IEnumerable<ChannelInfo>> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken)
|
||||
{
|
||||
var url = info.Url;
|
||||
|
@ -88,7 +91,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
|
|||
switch (list[0])
|
||||
{
|
||||
case "tvg-id":
|
||||
channels.Last().Id = urlHash + list[1];
|
||||
channels.Last().Id = ChannelIdPrefix + urlHash + list[1];
|
||||
channels.Last().Number = list[1];
|
||||
break;
|
||||
case "tvg-name":
|
||||
|
@ -121,15 +124,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
|
|||
return Task.FromResult(list);
|
||||
}
|
||||
|
||||
public async Task<MediaSourceInfo> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken)
|
||||
protected override async Task<MediaSourceInfo> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken)
|
||||
{
|
||||
var urlHash = info.Url.GetMD5().ToString("N");
|
||||
if (!channelId.StartsWith(urlHash, StringComparison.OrdinalIgnoreCase))
|
||||
var prefix = ChannelIdPrefix + urlHash;
|
||||
if (!channelId.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
channelId = channelId.Substring(urlHash.Length);
|
||||
channelId = channelId.Substring(prefix.Length);
|
||||
|
||||
var channels = await GetChannels(info, true, cancellationToken).ConfigureAwait(false);
|
||||
var m3uchannels = channels.Cast<M3UChannel>();
|
||||
|
@ -196,9 +200,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
|
|||
}
|
||||
}
|
||||
|
||||
public Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken)
|
||||
protected override bool IsValidChannelId(string channelId)
|
||||
{
|
||||
return channelId.StartsWith(ChannelIdPrefix, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
protected override Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Task<bool> IsAvailable(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user