mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-11-15 18:08:53 -07:00
rework guide mappings
This commit is contained in:
parent
ac3ec6d185
commit
851364f84f
@ -393,7 +393,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await provider.Item1.AddMetadata(provider.Item2, enabledChannels, cancellationToken).ConfigureAwait(false);
|
await AddMetadata(provider.Item1, provider.Item2, enabledChannels, enableCache, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (NotSupportedException)
|
catch (NotSupportedException)
|
||||||
{
|
{
|
||||||
@ -409,6 +409,120 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task AddMetadata(IListingsProvider provider, ListingsProviderInfo info, List<ChannelInfo> tunerChannels, bool enableCache, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var epgChannels = await GetEpgChannels(provider, info, enableCache, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
foreach (var tunerChannel in tunerChannels)
|
||||||
|
{
|
||||||
|
var epgChannel = GetEpgChannelFromTunerChannel(info, tunerChannel, epgChannels);
|
||||||
|
|
||||||
|
if (epgChannel != null)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(epgChannel.Name))
|
||||||
|
{
|
||||||
|
tunerChannel.Name = epgChannel.Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly ConcurrentDictionary<string, List<ChannelInfo>> _epgChannels =
|
||||||
|
new ConcurrentDictionary<string, List<ChannelInfo>>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
private async Task<List<ChannelInfo>> GetEpgChannels(IListingsProvider provider, ListingsProviderInfo info, bool enableCache, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
List<ChannelInfo> result;
|
||||||
|
if (!enableCache || !_epgChannels.TryGetValue(info.Id, out result))
|
||||||
|
{
|
||||||
|
result = await provider.GetChannels(info, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
_epgChannels.AddOrUpdate(info.Id, result, (k, v) => result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<ChannelInfo> GetEpgChannelFromTunerChannel(IListingsProvider provider, ListingsProviderInfo info, ChannelInfo tunerChannel, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var epgChannels = await GetEpgChannels(provider, info, true, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
return GetEpgChannelFromTunerChannel(info, tunerChannel, epgChannels);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetMappedChannel(string channelId, List<NameValuePair> mappings)
|
||||||
|
{
|
||||||
|
foreach (NameValuePair mapping in mappings)
|
||||||
|
{
|
||||||
|
if (StringHelper.EqualsIgnoreCase(mapping.Name, channelId))
|
||||||
|
{
|
||||||
|
return mapping.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return channelId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChannelInfo GetEpgChannelFromTunerChannel(ListingsProviderInfo info, ChannelInfo tunerChannel, List<ChannelInfo> epgChannels)
|
||||||
|
{
|
||||||
|
return GetEpgChannelFromTunerChannel(info.ChannelMappings.ToList(), tunerChannel, epgChannels);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChannelInfo GetEpgChannelFromTunerChannel(List<NameValuePair> mappings, ChannelInfo tunerChannel, List<ChannelInfo> epgChannels)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(tunerChannel.TunerChannelId))
|
||||||
|
{
|
||||||
|
var tunerChannelId = GetMappedChannel(tunerChannel.TunerChannelId, mappings);
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(tunerChannelId))
|
||||||
|
{
|
||||||
|
tunerChannelId = tunerChannel.TunerChannelId;
|
||||||
|
}
|
||||||
|
|
||||||
|
var channel = epgChannels.FirstOrDefault(i => string.Equals(tunerChannelId, i.Id, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
|
if (channel != null)
|
||||||
|
{
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(tunerChannel.Number))
|
||||||
|
{
|
||||||
|
var tunerChannelNumber = GetMappedChannel(tunerChannel.Number, mappings);
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(tunerChannelNumber))
|
||||||
|
{
|
||||||
|
tunerChannelNumber = tunerChannel.Number;
|
||||||
|
}
|
||||||
|
|
||||||
|
var channel = epgChannels.FirstOrDefault(i => string.Equals(tunerChannelNumber, i.Number, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
|
if (channel != null)
|
||||||
|
{
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(tunerChannel.Name))
|
||||||
|
{
|
||||||
|
var normalizedName = NormalizeName(tunerChannel.Name);
|
||||||
|
|
||||||
|
var channel = epgChannels.FirstOrDefault(i => string.Equals(normalizedName, NormalizeName(i.Name ?? string.Empty), StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
|
if (channel != null)
|
||||||
|
{
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string NormalizeName(string value)
|
||||||
|
{
|
||||||
|
return value.Replace(" ", string.Empty).Replace("-", string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<List<ChannelInfo>> GetChannelsForListingsProvider(ListingsProviderInfo listingsProvider, CancellationToken cancellationToken)
|
public async Task<List<ChannelInfo>> GetChannelsForListingsProvider(ListingsProviderInfo listingsProvider, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var list = new List<ChannelInfo>();
|
var list = new List<ChannelInfo>();
|
||||||
@ -845,54 +959,37 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|||||||
|
|
||||||
_logger.Debug("Getting programs for channel {0}-{1} from {2}-{3}", channel.Number, channel.Name, provider.Item1.Name, provider.Item2.ListingsId ?? string.Empty);
|
_logger.Debug("Getting programs for channel {0}-{1} from {2}-{3}", channel.Number, channel.Name, provider.Item1.Name, provider.Item2.ListingsId ?? string.Empty);
|
||||||
|
|
||||||
var channelMappings = GetChannelMappings(provider.Item2);
|
var epgChannel = await GetEpgChannelFromTunerChannel(provider.Item1, provider.Item2, channel, cancellationToken).ConfigureAwait(false);
|
||||||
var channelNumber = channel.Number;
|
|
||||||
var tunerChannelId = channel.TunerChannelId;
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(channelNumber))
|
List<ProgramInfo> programs;
|
||||||
|
|
||||||
|
if (epgChannel == null)
|
||||||
{
|
{
|
||||||
string mappedChannelNumber;
|
programs = new List<ProgramInfo>();
|
||||||
if (channelMappings.TryGetValue(channelNumber, out mappedChannelNumber))
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
_logger.Debug("Found mapped channel on provider {0}. Tuner channel number: {1}, Mapped channel number: {2}", provider.Item1.Name, channelNumber, mappedChannelNumber);
|
programs = (await provider.Item1.GetProgramsAsync(provider.Item2, epgChannel.Id, startDateUtc, endDateUtc, cancellationToken)
|
||||||
channelNumber = mappedChannelNumber;
|
.ConfigureAwait(false)).ToList();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var programs = await provider.Item1.GetProgramsAsync(provider.Item2, tunerChannelId, channelNumber, channel.Name, startDateUtc, endDateUtc, cancellationToken)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
var list = programs.ToList();
|
|
||||||
|
|
||||||
// Replace the value that came from the provider with a normalized value
|
// Replace the value that came from the provider with a normalized value
|
||||||
foreach (var program in list)
|
foreach (var program in programs)
|
||||||
{
|
{
|
||||||
program.ChannelId = channelId;
|
program.ChannelId = channelId;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (list.Count > 0)
|
if (programs.Count > 0)
|
||||||
{
|
{
|
||||||
SaveEpgDataForChannel(channelId, list);
|
SaveEpgDataForChannel(channelId, programs);
|
||||||
|
|
||||||
return list;
|
return programs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new List<ProgramInfo>();
|
return new List<ProgramInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Dictionary<string, string> GetChannelMappings(ListingsProviderInfo info)
|
|
||||||
{
|
|
||||||
var dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
foreach (var mapping in info.ChannelMappings)
|
|
||||||
{
|
|
||||||
dict[mapping.Name] = mapping.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Tuple<IListingsProvider, ListingsProviderInfo>> GetListingProviders()
|
private List<Tuple<IListingsProvider, ListingsProviderInfo>> GetListingProviders()
|
||||||
{
|
{
|
||||||
return GetConfiguration().ListingProviders
|
return GetConfiguration().ListingProviders
|
||||||
|
@ -15,6 +15,7 @@ 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.Model.Extensions;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.LiveTv.Listings
|
namespace Emby.Server.Implementations.LiveTv.Listings
|
||||||
{
|
{
|
||||||
@ -60,8 +61,16 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
return dates;
|
return dates;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<ProgramInfo>> GetProgramsAsync(ListingsProviderInfo info, string channelId, string channelNumber, string channelName, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)
|
public async Task<IEnumerable<ProgramInfo>> GetProgramsAsync(ListingsProviderInfo info, string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(channelId))
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("channelId");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalize incoming input
|
||||||
|
channelId = channelId.Replace(".json.schedulesdirect.org", string.Empty, StringComparison.OrdinalIgnoreCase).TrimStart('I');
|
||||||
|
|
||||||
List<ProgramInfo> programsInfo = new List<ProgramInfo>();
|
List<ProgramInfo> programsInfo = new List<ProgramInfo>();
|
||||||
|
|
||||||
var token = await GetToken(info, cancellationToken).ConfigureAwait(false);
|
var token = await GetToken(info, cancellationToken).ConfigureAwait(false);
|
||||||
@ -80,15 +89,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
|
|
||||||
var dates = GetScheduleRequestDates(startDateUtc, endDateUtc);
|
var dates = GetScheduleRequestDates(startDateUtc, endDateUtc);
|
||||||
|
|
||||||
ScheduleDirect.Station station = GetStation(info.ListingsId, channelNumber, channelName);
|
string stationID = channelId;
|
||||||
|
|
||||||
if (station == null)
|
|
||||||
{
|
|
||||||
_logger.Info("No Schedules Direct Station found for channel {0} with name {1}", channelNumber, channelName);
|
|
||||||
return programsInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
string stationID = station.stationID;
|
|
||||||
|
|
||||||
_logger.Info("Channel Station ID is: " + stationID);
|
_logger.Info("Channel Station ID is: " + stationID);
|
||||||
List<ScheduleDirect.RequestScheduleForChannel> requestList =
|
List<ScheduleDirect.RequestScheduleForChannel> requestList =
|
||||||
@ -122,7 +123,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
StreamReader reader = new StreamReader(response.Content);
|
StreamReader reader = new StreamReader(response.Content);
|
||||||
string responseString = reader.ReadToEnd();
|
string responseString = reader.ReadToEnd();
|
||||||
var dailySchedules = _jsonSerializer.DeserializeFromString<List<ScheduleDirect.Day>>(responseString);
|
var dailySchedules = _jsonSerializer.DeserializeFromString<List<ScheduleDirect.Day>>(responseString);
|
||||||
_logger.Debug("Found " + dailySchedules.Count + " programs on " + channelNumber + " ScheduleDirect");
|
_logger.Debug("Found " + dailySchedules.Count + " programs on " + stationID + " ScheduleDirect");
|
||||||
|
|
||||||
httpOptions = new HttpRequestOptions()
|
httpOptions = new HttpRequestOptions()
|
||||||
{
|
{
|
||||||
@ -180,7 +181,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
programsInfo.Add(GetProgram(channelNumber, schedule, programDict[schedule.programID]));
|
programsInfo.Add(GetProgram(channelId, schedule, programDict[schedule.programID]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -202,127 +203,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly object _channelCacheLock = new object();
|
private string GetChannelNumber(ScheduleDirect.Map map)
|
||||||
private ScheduleDirect.Station GetStation(string listingsId, string channelNumber, string channelName)
|
|
||||||
{
|
|
||||||
lock (_channelCacheLock)
|
|
||||||
{
|
|
||||||
Dictionary<string, ScheduleDirect.Station> channelPair;
|
|
||||||
if (_channelPairingCache.TryGetValue(listingsId, out channelPair))
|
|
||||||
{
|
|
||||||
ScheduleDirect.Station station;
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(channelNumber) && channelPair.TryGetValue(channelNumber, out station))
|
|
||||||
{
|
|
||||||
return station;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(channelName))
|
|
||||||
{
|
|
||||||
channelName = NormalizeName(channelName);
|
|
||||||
|
|
||||||
var result = channelPair.Values.FirstOrDefault(i => string.Equals(NormalizeName(i.callsign ?? string.Empty), channelName, StringComparison.OrdinalIgnoreCase));
|
|
||||||
|
|
||||||
if (result != null)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(channelNumber))
|
|
||||||
{
|
|
||||||
return channelPair.Values.FirstOrDefault(i => string.Equals(NormalizeName(i.stationID ?? string.Empty), channelNumber, StringComparison.OrdinalIgnoreCase));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddToChannelPairCache(string listingsId, string channelNumber, ScheduleDirect.Station schChannel)
|
|
||||||
{
|
|
||||||
lock (_channelCacheLock)
|
|
||||||
{
|
|
||||||
Dictionary<string, ScheduleDirect.Station> cache;
|
|
||||||
if (_channelPairingCache.TryGetValue(listingsId, out cache))
|
|
||||||
{
|
|
||||||
cache[channelNumber] = schChannel;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cache = new Dictionary<string, ScheduleDirect.Station>();
|
|
||||||
cache[channelNumber] = schChannel;
|
|
||||||
_channelPairingCache[listingsId] = cache;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ClearPairCache(string listingsId)
|
|
||||||
{
|
|
||||||
lock (_channelCacheLock)
|
|
||||||
{
|
|
||||||
Dictionary<string, ScheduleDirect.Station> cache;
|
|
||||||
if (_channelPairingCache.TryGetValue(listingsId, out cache))
|
|
||||||
{
|
|
||||||
cache.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int GetChannelPairCacheCount(string listingsId)
|
|
||||||
{
|
|
||||||
lock (_channelCacheLock)
|
|
||||||
{
|
|
||||||
Dictionary<string, ScheduleDirect.Station> cache;
|
|
||||||
if (_channelPairingCache.TryGetValue(listingsId, out cache))
|
|
||||||
{
|
|
||||||
return cache.Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string NormalizeName(string value)
|
|
||||||
{
|
|
||||||
return value.Replace(" ", string.Empty).Replace("-", string.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task AddMetadata(ListingsProviderInfo info, List<ChannelInfo> channels,
|
|
||||||
CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var listingsId = info.ListingsId;
|
|
||||||
if (string.IsNullOrWhiteSpace(listingsId))
|
|
||||||
{
|
|
||||||
throw new Exception("ListingsId required");
|
|
||||||
}
|
|
||||||
|
|
||||||
var token = await GetToken(info, cancellationToken);
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(token))
|
|
||||||
{
|
|
||||||
throw new Exception("token required");
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearPairCache(listingsId);
|
|
||||||
|
|
||||||
var httpOptions = new HttpRequestOptions()
|
|
||||||
{
|
|
||||||
Url = ApiUrl + "/lineups/" + listingsId,
|
|
||||||
UserAgent = UserAgent,
|
|
||||||
CancellationToken = cancellationToken,
|
|
||||||
LogErrorResponseBody = true,
|
|
||||||
// The data can be large so give it some extra time
|
|
||||||
TimeoutMs = 60000
|
|
||||||
};
|
|
||||||
|
|
||||||
httpOptions.RequestHeaders["token"] = token;
|
|
||||||
|
|
||||||
using (var response = await Get(httpOptions, true, info).ConfigureAwait(false))
|
|
||||||
{
|
|
||||||
var root = _jsonSerializer.DeserializeFromStream<ScheduleDirect.Channel>(response);
|
|
||||||
|
|
||||||
foreach (ScheduleDirect.Map map in root.map)
|
|
||||||
{
|
{
|
||||||
var channelNumber = map.logicalChannelNumber;
|
var channelNumber = map.logicalChannelNumber;
|
||||||
|
|
||||||
@ -336,49 +217,10 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
}
|
}
|
||||||
channelNumber = channelNumber.TrimStart('0');
|
channelNumber = channelNumber.TrimStart('0');
|
||||||
|
|
||||||
_logger.Debug("Found channel: " + channelNumber + " in Schedules Direct");
|
return channelNumber;
|
||||||
|
|
||||||
var schChannel = (root.stations ?? new List<ScheduleDirect.Station>()).FirstOrDefault(item => string.Equals(item.stationID, map.stationID, StringComparison.OrdinalIgnoreCase));
|
|
||||||
if (schChannel != null)
|
|
||||||
{
|
|
||||||
AddToChannelPairCache(listingsId, channelNumber, schChannel);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddToChannelPairCache(listingsId, channelNumber, new ScheduleDirect.Station
|
|
||||||
{
|
|
||||||
stationID = map.stationID
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (ChannelInfo channel in channels)
|
private ProgramInfo GetProgram(string channelId, ScheduleDirect.Program programInfo, ScheduleDirect.ProgramDetails details)
|
||||||
{
|
|
||||||
var station = GetStation(listingsId, channel.Number, channel.Name);
|
|
||||||
|
|
||||||
if (station != null)
|
|
||||||
{
|
|
||||||
if (station.logo != null)
|
|
||||||
{
|
|
||||||
channel.ImageUrl = station.logo.URL;
|
|
||||||
channel.HasImage = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(station.name))
|
|
||||||
{
|
|
||||||
channel.Name = station.name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.Info("Schedules Direct doesnt have data for channel: " + channel.Number + " " + channel.Name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ProgramInfo GetProgram(string channel, ScheduleDirect.Program programInfo,
|
|
||||||
ScheduleDirect.ProgramDetails details)
|
|
||||||
{
|
{
|
||||||
//_logger.Debug("Show type is: " + (details.showType ?? "No ShowType"));
|
//_logger.Debug("Show type is: " + (details.showType ?? "No ShowType"));
|
||||||
DateTime startAt = GetDate(programInfo.airDateTime);
|
DateTime startAt = GetDate(programInfo.airDateTime);
|
||||||
@ -386,7 +228,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
ProgramAudio audioType = ProgramAudio.Stereo;
|
ProgramAudio audioType = ProgramAudio.Stereo;
|
||||||
|
|
||||||
bool repeat = programInfo.@new == null;
|
bool repeat = programInfo.@new == null;
|
||||||
string newID = programInfo.programID + "T" + startAt.Ticks + "C" + channel;
|
string newID = programInfo.programID + "T" + startAt.Ticks + "C" + channelId;
|
||||||
|
|
||||||
if (programInfo.audioProperties != null)
|
if (programInfo.audioProperties != null)
|
||||||
{
|
{
|
||||||
@ -422,7 +264,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
|
|
||||||
var info = new ProgramInfo
|
var info = new ProgramInfo
|
||||||
{
|
{
|
||||||
ChannelId = channel,
|
ChannelId = channelId,
|
||||||
Id = newID,
|
Id = newID,
|
||||||
StartDate = startAt,
|
StartDate = startAt,
|
||||||
EndDate = endAt,
|
EndDate = endAt,
|
||||||
@ -969,8 +811,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
throw new Exception("ListingsId required");
|
throw new Exception("ListingsId required");
|
||||||
}
|
}
|
||||||
|
|
||||||
await AddMetadata(info, new List<ChannelInfo>(), cancellationToken).ConfigureAwait(false);
|
|
||||||
|
|
||||||
var token = await GetToken(info, cancellationToken);
|
var token = await GetToken(info, cancellationToken);
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(token))
|
if (string.IsNullOrWhiteSpace(token))
|
||||||
@ -997,39 +837,81 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
var root = _jsonSerializer.DeserializeFromStream<ScheduleDirect.Channel>(response);
|
var root = _jsonSerializer.DeserializeFromStream<ScheduleDirect.Channel>(response);
|
||||||
_logger.Info("Found " + root.map.Count + " channels on the lineup on ScheduleDirect");
|
_logger.Info("Found " + root.map.Count + " channels on the lineup on ScheduleDirect");
|
||||||
_logger.Info("Mapping Stations to Channel");
|
_logger.Info("Mapping Stations to Channel");
|
||||||
|
|
||||||
|
var allStations = root.stations ?? new List<ScheduleDirect.Station>();
|
||||||
|
|
||||||
foreach (ScheduleDirect.Map map in root.map)
|
foreach (ScheduleDirect.Map map in root.map)
|
||||||
{
|
{
|
||||||
var channelNumber = map.logicalChannelNumber;
|
var channelNumber = GetChannelNumber(map);
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(channelNumber))
|
var station = allStations.FirstOrDefault(item => string.Equals(item.stationID, map.stationID, StringComparison.OrdinalIgnoreCase));
|
||||||
|
if (station == null)
|
||||||
{
|
{
|
||||||
channelNumber = map.channel;
|
station = new ScheduleDirect.Station
|
||||||
}
|
|
||||||
if (string.IsNullOrWhiteSpace(channelNumber))
|
|
||||||
{
|
{
|
||||||
channelNumber = map.atscMajor + "." + map.atscMinor;
|
stationID = map.stationID
|
||||||
|
};
|
||||||
}
|
}
|
||||||
channelNumber = channelNumber.TrimStart('0');
|
|
||||||
|
|
||||||
var name = channelNumber;
|
var name = channelNumber;
|
||||||
var station = GetStation(listingsId, channelNumber, null);
|
|
||||||
|
|
||||||
if (station != null && !string.IsNullOrWhiteSpace(station.name))
|
var channelInfo = new ChannelInfo
|
||||||
{
|
|
||||||
name = station.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
list.Add(new ChannelInfo
|
|
||||||
{
|
{
|
||||||
Number = channelNumber,
|
Number = channelNumber,
|
||||||
Name = name
|
Name = name
|
||||||
});
|
};
|
||||||
|
|
||||||
|
if (station != null)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(station.name))
|
||||||
|
{
|
||||||
|
channelInfo.Name = station.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
channelInfo.Id = station.stationID;
|
||||||
|
channelInfo.CallSign = station.callsign;
|
||||||
|
|
||||||
|
if (station.logo != null)
|
||||||
|
{
|
||||||
|
channelInfo.ImageUrl = station.logo.URL;
|
||||||
|
channelInfo.HasImage = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list.Add(channelInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ScheduleDirect.Station GetStation(List<ScheduleDirect.Station> allStations, string channelNumber, string channelName)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(channelName))
|
||||||
|
{
|
||||||
|
channelName = NormalizeName(channelName);
|
||||||
|
|
||||||
|
var result = allStations.FirstOrDefault(i => string.Equals(NormalizeName(i.callsign ?? string.Empty), channelName, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(channelNumber))
|
||||||
|
{
|
||||||
|
return allStations.FirstOrDefault(i => string.Equals(NormalizeName(i.stationID ?? string.Empty), channelNumber, StringComparison.OrdinalIgnoreCase));
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string NormalizeName(string value)
|
||||||
|
{
|
||||||
|
return value.Replace(" ", string.Empty).Replace("-", string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
public class ScheduleDirect
|
public class ScheduleDirect
|
||||||
{
|
{
|
||||||
public class Token
|
public class Token
|
||||||
|
@ -106,8 +106,13 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
return cacheFile;
|
return cacheFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<ProgramInfo>> GetProgramsAsync(ListingsProviderInfo info, string channelId, string channelNumber, string channelName, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)
|
public async Task<IEnumerable<ProgramInfo>> GetProgramsAsync(ListingsProviderInfo info, string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(channelId))
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("channelId");
|
||||||
|
}
|
||||||
|
|
||||||
if (!await EmbyTV.EmbyTVRegistration.Instance.EnableXmlTv().ConfigureAwait(false))
|
if (!await EmbyTV.EmbyTVRegistration.Instance.EnableXmlTv().ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
var length = endDateUtc - startDateUtc;
|
var length = endDateUtc - startDateUtc;
|
||||||
@ -120,7 +125,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
var path = await GetXml(info.Path, cancellationToken).ConfigureAwait(false);
|
var path = await GetXml(info.Path, cancellationToken).ConfigureAwait(false);
|
||||||
var reader = new XmlTvReader(path, GetLanguage());
|
var reader = new XmlTvReader(path, GetLanguage());
|
||||||
|
|
||||||
var results = reader.GetProgrammes(channelNumber, startDateUtc, endDateUtc, cancellationToken);
|
var results = reader.GetProgrammes(channelId, startDateUtc, endDateUtc, cancellationToken);
|
||||||
return results.Select(p => GetProgramInfo(p, info));
|
return results.Select(p => GetProgramInfo(p, info));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,28 +199,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|||||||
return date;
|
return date;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task AddMetadata(ListingsProviderInfo info, List<ChannelInfo> channels, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
// Add the channel image url
|
|
||||||
var path = await GetXml(info.Path, cancellationToken).ConfigureAwait(false);
|
|
||||||
var reader = new XmlTvReader(path, GetLanguage());
|
|
||||||
var results = reader.GetChannels().ToList();
|
|
||||||
|
|
||||||
if (channels != null)
|
|
||||||
{
|
|
||||||
foreach (var c in channels)
|
|
||||||
{
|
|
||||||
var channelNumber = info.GetMappedChannel(c.Number);
|
|
||||||
var match = results.FirstOrDefault(r => string.Equals(r.Id, channelNumber, StringComparison.OrdinalIgnoreCase));
|
|
||||||
|
|
||||||
if (match != null && match.Icon != null && !String.IsNullOrEmpty(match.Icon.Source))
|
|
||||||
{
|
|
||||||
c.ImageUrl = match.Icon.Source;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings)
|
public Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings)
|
||||||
{
|
{
|
||||||
// Assume all urls are valid. check files for existence
|
// Assume all urls are valid. check files for existence
|
||||||
|
@ -2884,20 +2884,20 @@ namespace Emby.Server.Implementations.LiveTv
|
|||||||
_taskManager.CancelIfRunningAndQueue<RefreshChannelsScheduledTask>();
|
_taskManager.CancelIfRunningAndQueue<RefreshChannelsScheduledTask>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<TunerChannelMapping> SetChannelMapping(string providerId, string tunerChannelNumber, string providerChannelNumber)
|
public async Task<TunerChannelMapping> SetChannelMapping(string providerId, string tunerChannelId, string providerChannelId)
|
||||||
{
|
{
|
||||||
var config = GetConfiguration();
|
var config = GetConfiguration();
|
||||||
|
|
||||||
var listingsProviderInfo = config.ListingProviders.First(i => string.Equals(providerId, i.Id, StringComparison.OrdinalIgnoreCase));
|
var listingsProviderInfo = config.ListingProviders.First(i => string.Equals(providerId, i.Id, StringComparison.OrdinalIgnoreCase));
|
||||||
listingsProviderInfo.ChannelMappings = listingsProviderInfo.ChannelMappings.Where(i => !string.Equals(i.Name, tunerChannelNumber, StringComparison.OrdinalIgnoreCase)).ToArray();
|
listingsProviderInfo.ChannelMappings = listingsProviderInfo.ChannelMappings.Where(i => !string.Equals(i.Name, tunerChannelId, StringComparison.OrdinalIgnoreCase)).ToArray();
|
||||||
|
|
||||||
if (!string.Equals(tunerChannelNumber, providerChannelNumber, StringComparison.OrdinalIgnoreCase))
|
if (!string.Equals(tunerChannelId, providerChannelId, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
var list = listingsProviderInfo.ChannelMappings.ToList();
|
var list = listingsProviderInfo.ChannelMappings.ToList();
|
||||||
list.Add(new NameValuePair
|
list.Add(new NameValuePair
|
||||||
{
|
{
|
||||||
Name = tunerChannelNumber,
|
Name = tunerChannelId,
|
||||||
Value = providerChannelNumber
|
Value = providerChannelId
|
||||||
});
|
});
|
||||||
listingsProviderInfo.ChannelMappings = list.ToArray();
|
listingsProviderInfo.ChannelMappings = list.ToArray();
|
||||||
}
|
}
|
||||||
@ -2917,31 +2917,33 @@ namespace Emby.Server.Implementations.LiveTv
|
|||||||
|
|
||||||
_taskManager.CancelIfRunningAndQueue<RefreshChannelsScheduledTask>();
|
_taskManager.CancelIfRunningAndQueue<RefreshChannelsScheduledTask>();
|
||||||
|
|
||||||
return tunerChannelMappings.First(i => string.Equals(i.Number, tunerChannelNumber, StringComparison.OrdinalIgnoreCase));
|
return tunerChannelMappings.First(i => string.Equals(i.Id, tunerChannelId, StringComparison.OrdinalIgnoreCase));
|
||||||
}
|
}
|
||||||
|
|
||||||
public TunerChannelMapping GetTunerChannelMapping(ChannelInfo channel, List<NameValuePair> mappings, List<ChannelInfo> providerChannels)
|
public TunerChannelMapping GetTunerChannelMapping(ChannelInfo tunerChannel, List<NameValuePair> mappings, List<ChannelInfo> epgChannels)
|
||||||
{
|
{
|
||||||
var result = new TunerChannelMapping
|
var result = new TunerChannelMapping
|
||||||
{
|
{
|
||||||
Name = channel.Number + " " + channel.Name,
|
Name = tunerChannel.Name,
|
||||||
Number = channel.Number
|
Id = tunerChannel.TunerChannelId
|
||||||
};
|
};
|
||||||
|
|
||||||
var mapping = mappings.FirstOrDefault(i => string.Equals(i.Name, channel.Number, StringComparison.OrdinalIgnoreCase));
|
if (!string.IsNullOrWhiteSpace(tunerChannel.Number))
|
||||||
var providerChannelNumber = channel.Number;
|
|
||||||
|
|
||||||
if (mapping != null)
|
|
||||||
{
|
{
|
||||||
providerChannelNumber = mapping.Value;
|
result.Name = tunerChannel.Number + " " + result.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
var providerChannel = providerChannels.FirstOrDefault(i => string.Equals(i.Number, providerChannelNumber, StringComparison.OrdinalIgnoreCase));
|
if (string.IsNullOrWhiteSpace(result.Id))
|
||||||
|
{
|
||||||
|
result.Id = tunerChannel.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
var providerChannel = EmbyTV.EmbyTV.Current.GetEpgChannelFromTunerChannel(mappings, tunerChannel, epgChannels);
|
||||||
|
|
||||||
if (providerChannel != null)
|
if (providerChannel != null)
|
||||||
{
|
{
|
||||||
result.ProviderChannelNumber = providerChannel.Number;
|
|
||||||
result.ProviderChannelName = providerChannel.Name;
|
result.ProviderChannelName = providerChannel.Name;
|
||||||
|
result.ProviderChannelId = providerChannel.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -113,17 +113,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var startingNumber = 1;
|
|
||||||
foreach (var channel in channels)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrWhiteSpace(channel.Number))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
channel.Number = startingNumber.ToString(CultureInfo.InvariantCulture);
|
|
||||||
startingNumber++;
|
|
||||||
}
|
|
||||||
return channels;
|
return channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,10 +136,11 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
channel.Name = GetChannelName(extInf, attributes);
|
channel.Name = GetChannelName(extInf, attributes);
|
||||||
channel.Number = GetChannelNumber(extInf, attributes, mediaUrl);
|
channel.Number = GetChannelNumber(extInf, attributes, mediaUrl);
|
||||||
|
|
||||||
if (attributes.TryGetValue("tvg-id", out value))
|
var channelId = GetTunerChannelId(attributes);
|
||||||
|
if (!string.IsNullOrWhiteSpace(channelId))
|
||||||
{
|
{
|
||||||
channel.Id = value;
|
channel.Id = channelId;
|
||||||
channel.TunerChannelId = value;
|
channel.TunerChannelId = channelId;
|
||||||
}
|
}
|
||||||
|
|
||||||
return channel;
|
return channel;
|
||||||
@ -186,9 +176,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
numberString = numberString.Trim();
|
numberString = numberString.Trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(numberString) ||
|
if (!IsValidChannelNumber(numberString))
|
||||||
string.Equals(numberString, "-1", StringComparison.OrdinalIgnoreCase) ||
|
|
||||||
string.Equals(numberString, "0", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
{
|
||||||
string value;
|
string value;
|
||||||
if (attributes.TryGetValue("tvg-id", out value))
|
if (attributes.TryGetValue("tvg-id", out value))
|
||||||
@ -206,9 +194,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
numberString = numberString.Trim();
|
numberString = numberString.Trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(numberString) ||
|
if (!IsValidChannelNumber(numberString))
|
||||||
string.Equals(numberString, "-1", StringComparison.OrdinalIgnoreCase) ||
|
|
||||||
string.Equals(numberString, "0", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
{
|
||||||
string value;
|
string value;
|
||||||
if (attributes.TryGetValue("channel-id", out value))
|
if (attributes.TryGetValue("channel-id", out value))
|
||||||
@ -222,9 +208,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
numberString = numberString.Trim();
|
numberString = numberString.Trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(numberString) ||
|
if (!IsValidChannelNumber(numberString))
|
||||||
string.Equals(numberString, "-1", StringComparison.OrdinalIgnoreCase) ||
|
|
||||||
string.Equals(numberString, "0", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
{
|
||||||
numberString = null;
|
numberString = null;
|
||||||
}
|
}
|
||||||
@ -239,8 +223,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
{
|
{
|
||||||
numberString = Path.GetFileNameWithoutExtension(mediaUrl.Split('/').Last());
|
numberString = Path.GetFileNameWithoutExtension(mediaUrl.Split('/').Last());
|
||||||
|
|
||||||
double value;
|
if (!IsValidChannelNumber(numberString))
|
||||||
if (!double.TryParse(numberString, NumberStyles.Any, CultureInfo.InvariantCulture, out value))
|
|
||||||
{
|
{
|
||||||
numberString = null;
|
numberString = null;
|
||||||
}
|
}
|
||||||
@ -250,6 +233,24 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
return numberString;
|
return numberString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool IsValidChannelNumber(string numberString)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(numberString) ||
|
||||||
|
string.Equals(numberString, "-1", StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
string.Equals(numberString, "0", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
double value;
|
||||||
|
if (!double.TryParse(numberString, NumberStyles.Any, CultureInfo.InvariantCulture, out value))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private string GetChannelName(string extInf, Dictionary<string, string> attributes)
|
private string GetChannelName(string extInf, Dictionary<string, string> attributes)
|
||||||
{
|
{
|
||||||
var nameParts = extInf.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
var nameParts = extInf.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
@ -295,6 +296,19 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetTunerChannelId(Dictionary<string, string> attributes)
|
||||||
|
{
|
||||||
|
string result;
|
||||||
|
attributes.TryGetValue("tvg-id", out result);
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(result))
|
||||||
|
{
|
||||||
|
attributes.TryGetValue("channel-id", out result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private Dictionary<string, string> ParseExtInf(string line, out string remaining)
|
private Dictionary<string, string> ParseExtInf(string line, out string remaining)
|
||||||
{
|
{
|
||||||
var dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
var dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
@ -640,8 +640,8 @@ namespace MediaBrowser.Api.LiveTv
|
|||||||
{
|
{
|
||||||
[ApiMember(Name = "Id", Description = "Provider id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
|
[ApiMember(Name = "Id", Description = "Provider id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||||
public string ProviderId { get; set; }
|
public string ProviderId { get; set; }
|
||||||
public string TunerChannelNumber { get; set; }
|
public string TunerChannelId { get; set; }
|
||||||
public string ProviderChannelNumber { get; set; }
|
public string ProviderChannelId { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ChannelMappingOptions
|
public class ChannelMappingOptions
|
||||||
@ -765,7 +765,7 @@ namespace MediaBrowser.Api.LiveTv
|
|||||||
|
|
||||||
public async Task<object> Post(SetChannelMapping request)
|
public async Task<object> Post(SetChannelMapping request)
|
||||||
{
|
{
|
||||||
return await _liveTvManager.SetChannelMapping(request.ProviderId, request.TunerChannelNumber, request.ProviderChannelNumber).ConfigureAwait(false);
|
return await _liveTvManager.SetChannelMapping(request.ProviderId, request.TunerChannelId, request.ProviderChannelId).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<object> Get(GetChannelMappingOptions request)
|
public async Task<object> Get(GetChannelMappingOptions request)
|
||||||
@ -791,7 +791,7 @@ namespace MediaBrowser.Api.LiveTv
|
|||||||
ProviderChannels = providerChannels.Select(i => new NameIdPair
|
ProviderChannels = providerChannels.Select(i => new NameIdPair
|
||||||
{
|
{
|
||||||
Name = i.Name,
|
Name = i.Name,
|
||||||
Id = i.Number
|
Id = i.TunerChannelId
|
||||||
|
|
||||||
}).ToList(),
|
}).ToList(),
|
||||||
|
|
||||||
|
@ -27,6 +27,8 @@ namespace MediaBrowser.Controller.LiveTv
|
|||||||
|
|
||||||
public string TunerChannelId { get; set; }
|
public string TunerChannelId { get; set; }
|
||||||
|
|
||||||
|
public string CallSign { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the tuner host identifier.
|
/// Gets or sets the tuner host identifier.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -11,8 +11,7 @@ namespace MediaBrowser.Controller.LiveTv
|
|||||||
{
|
{
|
||||||
string Name { get; }
|
string Name { get; }
|
||||||
string Type { get; }
|
string Type { get; }
|
||||||
Task<IEnumerable<ProgramInfo>> GetProgramsAsync(ListingsProviderInfo info, string channelId, string channelNumber, string channelName, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken);
|
Task<IEnumerable<ProgramInfo>> GetProgramsAsync(ListingsProviderInfo info, string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken);
|
||||||
Task AddMetadata(ListingsProviderInfo info, List<ChannelInfo> channels, CancellationToken cancellationToken);
|
|
||||||
Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings);
|
Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings);
|
||||||
Task<List<NameIdPair>> GetLineups(ListingsProviderInfo info, string country, string location);
|
Task<List<NameIdPair>> GetLineups(ListingsProviderInfo info, string country, string location);
|
||||||
Task<List<ChannelInfo>> GetChannels(ListingsProviderInfo info, CancellationToken cancellationToken);
|
Task<List<ChannelInfo>> GetChannels(ListingsProviderInfo info, CancellationToken cancellationToken);
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
public class TunerChannelMapping
|
public class TunerChannelMapping
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string Number { get; set; }
|
|
||||||
public string ProviderChannelNumber { get; set; }
|
|
||||||
public string ProviderChannelName { get; set; }
|
public string ProviderChannelName { get; set; }
|
||||||
|
public string ProviderChannelId { get; set; }
|
||||||
|
public string Id { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,17 +96,5 @@ namespace MediaBrowser.Model.LiveTv
|
|||||||
EnableAllTuners = true;
|
EnableAllTuners = true;
|
||||||
ChannelMappings = new NameValuePair[] {};
|
ChannelMappings = new NameValuePair[] {};
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetMappedChannel(string channelNumber)
|
|
||||||
{
|
|
||||||
foreach (NameValuePair mapping in ChannelMappings)
|
|
||||||
{
|
|
||||||
if (StringHelper.EqualsIgnoreCase(mapping.Name, channelNumber))
|
|
||||||
{
|
|
||||||
return mapping.Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return channelNumber;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user