commit
747322a7db
|
@ -10,9 +10,11 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.MediaEncoding;
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
||||||
|
@ -23,16 +25,18 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
||||||
protected readonly ILogger Logger;
|
protected readonly ILogger Logger;
|
||||||
protected IJsonSerializer JsonSerializer;
|
protected IJsonSerializer JsonSerializer;
|
||||||
protected readonly IMediaEncoder MediaEncoder;
|
protected readonly IMediaEncoder MediaEncoder;
|
||||||
|
protected readonly IFileSystem FileSystem;
|
||||||
|
|
||||||
private readonly ConcurrentDictionary<string, ChannelCache> _channelCache =
|
private readonly ConcurrentDictionary<string, ChannelCache> _channelCache =
|
||||||
new ConcurrentDictionary<string, ChannelCache>(StringComparer.OrdinalIgnoreCase);
|
new ConcurrentDictionary<string, ChannelCache>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
protected BaseTunerHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder)
|
protected BaseTunerHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem)
|
||||||
{
|
{
|
||||||
Config = config;
|
Config = config;
|
||||||
Logger = logger;
|
Logger = logger;
|
||||||
JsonSerializer = jsonSerializer;
|
JsonSerializer = jsonSerializer;
|
||||||
MediaEncoder = mediaEncoder;
|
MediaEncoder = mediaEncoder;
|
||||||
|
FileSystem = fileSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract Task<List<ChannelInfo>> GetChannelsInternal(TunerHostInfo tuner, CancellationToken cancellationToken);
|
protected abstract Task<List<ChannelInfo>> GetChannelsInternal(TunerHostInfo tuner, CancellationToken cancellationToken);
|
||||||
|
@ -81,16 +85,44 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
||||||
|
|
||||||
foreach (var host in hosts)
|
foreach (var host in hosts)
|
||||||
{
|
{
|
||||||
|
var channelCacheFile = Path.Combine(Config.ApplicationPaths.CachePath, host.Id + "_channels");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var channels = await GetChannels(host, enableCache, cancellationToken).ConfigureAwait(false);
|
var channels = await GetChannels(host, enableCache, cancellationToken).ConfigureAwait(false);
|
||||||
var newChannels = channels.Where(i => !list.Any(l => string.Equals(i.Id, l.Id, StringComparison.OrdinalIgnoreCase))).ToList();
|
var newChannels = channels.Where(i => !list.Any(l => string.Equals(i.Id, l.Id, StringComparison.OrdinalIgnoreCase))).ToList();
|
||||||
|
|
||||||
list.AddRange(newChannels);
|
list.AddRange(newChannels);
|
||||||
|
|
||||||
|
if (!enableCache)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FileSystem.CreateDirectory(FileSystem.GetDirectoryName(channelCacheFile));
|
||||||
|
JsonSerializer.SerializeToFile(channels, channelCacheFile);
|
||||||
|
}
|
||||||
|
catch (IOException)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.ErrorException("Error getting channel list", ex);
|
Logger.ErrorException("Error getting channel list", ex);
|
||||||
|
|
||||||
|
if (enableCache)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var channels = JsonSerializer.DeserializeFromFile<List<ChannelInfo>>(channelCacheFile);
|
||||||
|
list.AddRange(channels);
|
||||||
|
}
|
||||||
|
catch (IOException)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,17 +27,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
public class HdHomerunHost : BaseTunerHost, ITunerHost, IConfigurableTunerHost
|
public class HdHomerunHost : BaseTunerHost, ITunerHost, IConfigurableTunerHost
|
||||||
{
|
{
|
||||||
private readonly IHttpClient _httpClient;
|
private readonly IHttpClient _httpClient;
|
||||||
private readonly IFileSystem _fileSystem;
|
|
||||||
private readonly IServerApplicationHost _appHost;
|
private readonly IServerApplicationHost _appHost;
|
||||||
private readonly ISocketFactory _socketFactory;
|
private readonly ISocketFactory _socketFactory;
|
||||||
private readonly INetworkManager _networkManager;
|
private readonly INetworkManager _networkManager;
|
||||||
private readonly IEnvironmentInfo _environment;
|
private readonly IEnvironmentInfo _environment;
|
||||||
|
|
||||||
public HdHomerunHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IHttpClient httpClient, IFileSystem fileSystem, IServerApplicationHost appHost, ISocketFactory socketFactory, INetworkManager networkManager, IEnvironmentInfo environment)
|
public HdHomerunHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient, IServerApplicationHost appHost, ISocketFactory socketFactory, INetworkManager networkManager, IEnvironmentInfo environment) : base(config, logger, jsonSerializer, mediaEncoder, fileSystem)
|
||||||
: base(config, logger, jsonSerializer, mediaEncoder)
|
|
||||||
{
|
{
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_fileSystem = fileSystem;
|
|
||||||
_appHost = appHost;
|
_appHost = appHost;
|
||||||
_socketFactory = socketFactory;
|
_socketFactory = socketFactory;
|
||||||
_networkManager = networkManager;
|
_networkManager = networkManager;
|
||||||
|
@ -509,7 +506,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.Url), modelInfo.TunerCount, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _socketFactory, _networkManager, _environment);
|
return new HdHomerunUdpStream(mediaSource, streamId, new LegacyHdHomerunChannelCommands(hdhomerunChannel.Url), 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
|
||||||
|
@ -529,10 +526,10 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
}
|
}
|
||||||
mediaSource.Path = httpUrl;
|
mediaSource.Path = httpUrl;
|
||||||
|
|
||||||
return new HdHomerunHttpStream(mediaSource, streamId, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _environment);
|
return new HdHomerunHttpStream(mediaSource, 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, 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)
|
||||||
|
|
|
@ -25,15 +25,12 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
||||||
{
|
{
|
||||||
public class M3UTunerHost : BaseTunerHost, ITunerHost, IConfigurableTunerHost
|
public class M3UTunerHost : BaseTunerHost, ITunerHost, IConfigurableTunerHost
|
||||||
{
|
{
|
||||||
private readonly IFileSystem _fileSystem;
|
|
||||||
private readonly IHttpClient _httpClient;
|
private readonly IHttpClient _httpClient;
|
||||||
private readonly IServerApplicationHost _appHost;
|
private readonly IServerApplicationHost _appHost;
|
||||||
private readonly IEnvironmentInfo _environment;
|
private readonly IEnvironmentInfo _environment;
|
||||||
|
|
||||||
public M3UTunerHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient, IServerApplicationHost appHost, IEnvironmentInfo environment)
|
public M3UTunerHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient, IServerApplicationHost appHost, IEnvironmentInfo environment) : base(config, logger, jsonSerializer, mediaEncoder, fileSystem)
|
||||||
: base(config, logger, jsonSerializer, mediaEncoder)
|
|
||||||
{
|
{
|
||||||
_fileSystem = fileSystem;
|
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_appHost = appHost;
|
_appHost = appHost;
|
||||||
_environment = environment;
|
_environment = environment;
|
||||||
|
@ -51,7 +48,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
||||||
|
|
||||||
protected override async Task<List<ChannelInfo>> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken)
|
protected override async Task<List<ChannelInfo>> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var result = await new M3uParser(Logger, _fileSystem, _httpClient, _appHost).Parse(info.Url, ChannelIdPrefix, info.Id, !info.EnableTvgId, cancellationToken).ConfigureAwait(false);
|
var result = await new M3uParser(Logger, FileSystem, _httpClient, _appHost).Parse(info.Url, ChannelIdPrefix, info.Id, !info.EnableTvgId, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
return result.Cast<ChannelInfo>().ToList();
|
return result.Cast<ChannelInfo>().ToList();
|
||||||
}
|
}
|
||||||
|
@ -76,13 +73,13 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
||||||
{
|
{
|
||||||
var sources = await GetChannelStreamMediaSources(info, channelId, cancellationToken).ConfigureAwait(false);
|
var sources = await GetChannelStreamMediaSources(info, channelId, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
var liveStream = new LiveStream(sources.First(), _environment, _fileSystem);
|
var liveStream = new LiveStream(sources.First(), _environment, FileSystem);
|
||||||
return liveStream;
|
return liveStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Validate(TunerHostInfo info)
|
public async Task Validate(TunerHostInfo info)
|
||||||
{
|
{
|
||||||
using (var stream = await new M3uParser(Logger, _fileSystem, _httpClient, _appHost).GetListingsStream(info.Url, CancellationToken.None).ConfigureAwait(false))
|
using (var stream = await new M3uParser(Logger, FileSystem, _httpClient, _appHost).GetListingsStream(info.Url, CancellationToken.None).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,7 +224,7 @@ namespace MediaBrowser.Api.UserLibrary
|
||||||
[ApiMember(Name = "ParentId", Description = "Specify this to localize the search to a specific item or folder. Omit to use the root", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
|
[ApiMember(Name = "ParentId", Description = "Specify this to localize the search to a specific item or folder. Omit to use the root", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||||
public string ParentId { get; set; }
|
public string ParentId { get; set; }
|
||||||
|
|
||||||
[ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
[ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Chapters, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, SortName, Studios, Taglines", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
||||||
public string Fields { get; set; }
|
public string Fields { get; set; }
|
||||||
|
|
||||||
[ApiMember(Name = "IncludeItemTypes", Description = "Optional. If specified, results will be filtered based on item type. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
[ApiMember(Name = "IncludeItemTypes", Description = "Optional. If specified, results will be filtered based on item type. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
[assembly: AssemblyVersion("3.2.22.3")]
|
[assembly: AssemblyVersion("3.2.22.4")]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user