update emby tv
This commit is contained in:
parent
f7c1a88166
commit
ba9ed26c4a
|
@ -924,7 +924,7 @@ namespace MediaBrowser.Api.Playback
|
||||||
state.IsoMount = await IsoManager.Mount(state.MediaPath, cancellationTokenSource.Token).ConfigureAwait(false);
|
state.IsoMount = await IsoManager.Mount(state.MediaPath, cancellationTokenSource.Token).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.MediaSource.RequiresOpening)
|
if (state.MediaSource.RequiresOpening ?? false)
|
||||||
{
|
{
|
||||||
var liveStreamResponse = await MediaSourceManager.OpenLiveStream(new LiveStreamRequest
|
var liveStreamResponse = await MediaSourceManager.OpenLiveStream(new LiveStreamRequest
|
||||||
{
|
{
|
||||||
|
|
|
@ -185,7 +185,7 @@ namespace MediaBrowser.Api.Playback
|
||||||
|
|
||||||
private async void DisposeLiveStream()
|
private async void DisposeLiveStream()
|
||||||
{
|
{
|
||||||
if (MediaSource.RequiresClosing && string.IsNullOrWhiteSpace(Request.LiveStreamId))
|
if ((MediaSource.RequiresClosing ?? false) && string.IsNullOrWhiteSpace(Request.LiveStreamId))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -47,6 +47,14 @@ namespace MediaBrowser.Controller.LiveTv
|
||||||
/// <returns>Task<MediaSourceInfo>.</returns>
|
/// <returns>Task<MediaSourceInfo>.</returns>
|
||||||
Task<MediaSourceInfo> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken);
|
Task<MediaSourceInfo> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken);
|
||||||
/// <summary>
|
/// <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);
|
||||||
|
/// <summary>
|
||||||
/// Validates the specified information.
|
/// Validates the specified information.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="info">The information.</param>
|
/// <param name="info">The information.</param>
|
||||||
|
|
|
@ -436,7 +436,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
state.IsoMount = await IsoManager.Mount(state.MediaPath, cancellationToken).ConfigureAwait(false);
|
state.IsoMount = await IsoManager.Mount(state.MediaPath, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.MediaSource.RequiresOpening)
|
if (state.MediaSource.RequiresOpening ?? false)
|
||||||
{
|
{
|
||||||
var liveStreamResponse = await MediaSourceManager.OpenLiveStream(new LiveStreamRequest
|
var liveStreamResponse = await MediaSourceManager.OpenLiveStream(new LiveStreamRequest
|
||||||
{
|
{
|
||||||
|
|
|
@ -137,7 +137,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
|
|
||||||
private async void DisposeLiveStream()
|
private async void DisposeLiveStream()
|
||||||
{
|
{
|
||||||
if (MediaSource.RequiresClosing)
|
if (MediaSource.RequiresClosing ?? false)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,9 +26,9 @@ namespace MediaBrowser.Model.Dto
|
||||||
public bool SupportsDirectStream { get; set; }
|
public bool SupportsDirectStream { get; set; }
|
||||||
public bool SupportsDirectPlay { get; set; }
|
public bool SupportsDirectPlay { get; set; }
|
||||||
|
|
||||||
public bool RequiresOpening { get; set; }
|
public bool? RequiresOpening { get; set; }
|
||||||
public string OpenToken { get; set; }
|
public string OpenToken { get; set; }
|
||||||
public bool RequiresClosing { get; set; }
|
public bool? RequiresClosing { get; set; }
|
||||||
public string LiveStreamId { get; set; }
|
public string LiveStreamId { get; set; }
|
||||||
public int? BufferMs { get; set; }
|
public int? BufferMs { get; set; }
|
||||||
|
|
||||||
|
|
|
@ -34,5 +34,6 @@ namespace MediaBrowser.Model.LiveTv
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
public string ListingsId { get; set; }
|
public string ListingsId { get; set; }
|
||||||
public string ZipCode { get; set; }
|
public string ZipCode { get; set; }
|
||||||
|
public string Country { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -439,7 +439,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
LiveStreamInfo current;
|
LiveStreamInfo current;
|
||||||
if (_openStreams.TryGetValue(id, out current))
|
if (_openStreams.TryGetValue(id, out current))
|
||||||
{
|
{
|
||||||
if (current.MediaSource.RequiresClosing)
|
if (current.MediaSource.RequiresClosing ?? false)
|
||||||
{
|
{
|
||||||
var tuple = GetProvider(id);
|
var tuple = GetProvider(id);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using MediaBrowser.Common;
|
using MediaBrowser.Common;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Controller.Drawing;
|
using MediaBrowser.Controller.Drawing;
|
||||||
using MediaBrowser.Controller.LiveTv;
|
using MediaBrowser.Controller.LiveTv;
|
||||||
|
@ -74,20 +75,17 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
||||||
var status = new LiveTvServiceStatusInfo();
|
var status = new LiveTvServiceStatusInfo();
|
||||||
var list = new List<LiveTvTunerInfo>();
|
var list = new List<LiveTvTunerInfo>();
|
||||||
|
|
||||||
foreach (var host in _liveTvManager.TunerHosts)
|
foreach (var hostInstance in GetTunerHosts())
|
||||||
{
|
{
|
||||||
foreach (var hostInstance in host.GetTunerHosts())
|
try
|
||||||
{
|
{
|
||||||
try
|
var tuners = await hostInstance.Item1.GetTunerInfos(hostInstance.Item2, cancellationToken).ConfigureAwait(false);
|
||||||
{
|
|
||||||
var tuners = await host.GetTunerInfos(hostInstance, cancellationToken).ConfigureAwait(false);
|
|
||||||
|
|
||||||
list.AddRange(tuners);
|
list.AddRange(tuners);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error getting tuners", ex);
|
_logger.ErrorException("Error getting tuners", ex);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,20 +100,23 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
||||||
{
|
{
|
||||||
var list = new List<ChannelInfo>();
|
var list = new List<ChannelInfo>();
|
||||||
|
|
||||||
foreach (var host in _liveTvManager.TunerHosts)
|
foreach (var hostInstance in GetTunerHosts())
|
||||||
{
|
{
|
||||||
foreach (var hostInstance in host.GetTunerHosts())
|
try
|
||||||
{
|
{
|
||||||
try
|
var channels = await hostInstance.Item1.GetChannels(hostInstance.Item2, cancellationToken).ConfigureAwait(false);
|
||||||
{
|
var newChannels = channels.ToList();
|
||||||
var channels = await host.GetChannels(hostInstance, cancellationToken).ConfigureAwait(false);
|
|
||||||
|
|
||||||
list.AddRange(channels);
|
foreach (var channel in newChannels)
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error getting channels", ex);
|
channel.Id = hostInstance.Item1.Type.GetMD5().ToString("N") + "-" + channel.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list.AddRange(newChannels);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.ErrorException("Error getting channels", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,6 +131,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<Tuple<ITunerHost, TunerHostInfo>> GetTunerHosts()
|
||||||
|
{
|
||||||
|
return GetConfiguration().TunerHosts
|
||||||
|
.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)
|
public Task CancelSeriesTimerAsync(string timerId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var remove = _seriesTimerProvider.GetAll().SingleOrDefault(r => r.Id == timerId);
|
var remove = _seriesTimerProvider.GetAll().SingleOrDefault(r => r.Id == timerId);
|
||||||
|
@ -255,14 +269,27 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
||||||
return Task.FromResult((IEnumerable<SeriesTimerInfo>)_seriesTimerProvider.GetAll());
|
return Task.FromResult((IEnumerable<SeriesTimerInfo>)_seriesTimerProvider.GetAll());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetOriginalChannelId(string channelId)
|
||||||
|
{
|
||||||
|
var parts = channelId.Split('-');
|
||||||
|
|
||||||
|
return string.Join("-", parts.Skip(1).ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<ProgramInfo>> GetProgramsAsync(string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)
|
public async Task<IEnumerable<ProgramInfo>> GetProgramsAsync(string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
foreach (var provider in GetListingProviders())
|
foreach (var provider in GetListingProviders())
|
||||||
{
|
{
|
||||||
var programs = await provider.Item1.GetProgramsAsync(provider.Item2, channelId, startDateUtc, endDateUtc, cancellationToken)
|
var programs = await provider.Item1.GetProgramsAsync(provider.Item2, GetOriginalChannelId(channelId), startDateUtc, endDateUtc, cancellationToken)
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
var list = programs.ToList();
|
var list = programs.ToList();
|
||||||
|
|
||||||
|
// Replace the value that came from the provider with a normalized value
|
||||||
|
foreach (var program in list)
|
||||||
|
{
|
||||||
|
program.ChannelId = channelId;
|
||||||
|
}
|
||||||
|
|
||||||
if (list.Count > 0)
|
if (list.Count > 0)
|
||||||
{
|
{
|
||||||
return list;
|
return list;
|
||||||
|
@ -290,14 +317,67 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<MediaSourceInfo> GetChannelStream(string channelId, string streamId, CancellationToken cancellationToken)
|
public async Task<MediaSourceInfo> GetChannelStream(string channelId, string streamId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_logger.Info("Streaming Channel " + channelId);
|
||||||
|
|
||||||
|
var configurationId = channelId.Split('-')[0];
|
||||||
|
|
||||||
|
foreach (var hostInstance in GetTunerHosts())
|
||||||
|
{
|
||||||
|
if (!string.Equals(configurationId, hostInstance.Item1.Type.GetMD5().ToString("N"), StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
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, GetOriginalChannelId(channelId), streamId, cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
catch (ApplicationException e)
|
||||||
|
{
|
||||||
|
_logger.Info(e.Message);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
mediaSourceInfo.Id = Guid.NewGuid().ToString("N");
|
||||||
|
return mediaSourceInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ApplicationException("Tuner not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken)
|
public async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var configurationId = channelId.Split('-')[0];
|
||||||
|
|
||||||
|
foreach (var hostInstance in GetTunerHosts())
|
||||||
|
{
|
||||||
|
if (string.Equals(configurationId, hostInstance.Item1.Type.GetMD5().ToString("N"), StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
var sources = await hostInstance.Item1.GetChannelStreamMediaSources(hostInstance.Item2, GetOriginalChannelId(channelId), cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
foreach (var source in sources)
|
||||||
|
{
|
||||||
|
source.Id = hostInstance.Item2.Id + "-" + source.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sources;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ApplicationException("Tuner not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<List<MediaSourceInfo>> GetRecordingStreamMediaSources(string recordingId, CancellationToken cancellationToken)
|
public Task<List<MediaSourceInfo>> GetRecordingStreamMediaSources(string recordingId, CancellationToken cancellationToken)
|
||||||
|
|
|
@ -68,9 +68,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
||||||
|
|
||||||
private void UpdateList(List<T> newList)
|
private void UpdateList(List<T> newList)
|
||||||
{
|
{
|
||||||
|
var file = _dataPath + ".json";
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(file));
|
||||||
|
|
||||||
lock (_fileDataLock)
|
lock (_fileDataLock)
|
||||||
{
|
{
|
||||||
_jsonSerializer.SerializeToFile(newList, _dataPath + ".json");
|
_jsonSerializer.SerializeToFile(newList, file);
|
||||||
_items = newList;
|
_items = newList;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -218,7 +218,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings
|
||||||
private ProgramInfo GetProgram(string channel, ScheduleDirect.Program programInfo,
|
private ProgramInfo GetProgram(string channel, ScheduleDirect.Program programInfo,
|
||||||
ScheduleDirect.ProgramDetails details)
|
ScheduleDirect.ProgramDetails details)
|
||||||
{
|
{
|
||||||
_logger.Debug("Show type is: " + (details.showType ?? "No ShowType"));
|
//_logger.Debug("Show type is: " + (details.showType ?? "No ShowType"));
|
||||||
DateTime startAt = DateTime.ParseExact(programInfo.airDateTime, "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'",
|
DateTime startAt = DateTime.ParseExact(programInfo.airDateTime, "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'",
|
||||||
CultureInfo.InvariantCulture);
|
CultureInfo.InvariantCulture);
|
||||||
DateTime endAt = startAt.AddSeconds(programInfo.duration);
|
DateTime endAt = startAt.AddSeconds(programInfo.duration);
|
||||||
|
@ -401,7 +401,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings
|
||||||
_logger.Info("Headends on account ");
|
_logger.Info("Headends on account ");
|
||||||
|
|
||||||
var countryParam = string.Equals("ca", country, StringComparison.OrdinalIgnoreCase)
|
var countryParam = string.Equals("ca", country, StringComparison.OrdinalIgnoreCase)
|
||||||
? "Canada"
|
? "can"
|
||||||
: "USA";
|
: "USA";
|
||||||
|
|
||||||
var options = new HttpRequestOptions()
|
var options = new HttpRequestOptions()
|
||||||
|
@ -562,6 +562,44 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings
|
||||||
get { return "SchedulesDirect"; }
|
get { return "SchedulesDirect"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<bool> HasLineup(ListingsProviderInfo info, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var token = await GetToken(info, cancellationToken);
|
||||||
|
|
||||||
|
_logger.Info("Headends on account ");
|
||||||
|
|
||||||
|
var options = new HttpRequestOptions()
|
||||||
|
{
|
||||||
|
Url = ApiUrl + "/lineups",
|
||||||
|
UserAgent = UserAgent,
|
||||||
|
CancellationToken = cancellationToken
|
||||||
|
};
|
||||||
|
|
||||||
|
options.RequestHeaders["token"] = token;
|
||||||
|
|
||||||
|
using (Stream responce = await _httpClient.Get(options).ConfigureAwait(false))
|
||||||
|
{
|
||||||
|
var root = _jsonSerializer.DeserializeFromStream<ScheduleDirect.Lineups>(responce);
|
||||||
|
|
||||||
|
return root.lineups.Any(i => string.Equals(info.ListingsId, i.lineup, StringComparison.OrdinalIgnoreCase));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Validate(ListingsProviderInfo info)
|
||||||
|
{
|
||||||
|
var hasLineup = await HasLineup(info, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (!hasLineup)
|
||||||
|
{
|
||||||
|
await AddLineupToAccount(info, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<List<NameIdPair>> GetLineups(ListingsProviderInfo info, string country, string location)
|
||||||
|
{
|
||||||
|
return GetHeadends(info, country, location, CancellationToken.None);
|
||||||
|
}
|
||||||
|
|
||||||
public class ScheduleDirect
|
public class ScheduleDirect
|
||||||
{
|
{
|
||||||
public class Token
|
public class Token
|
||||||
|
@ -841,14 +879,5 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Validate(ListingsProviderInfo info)
|
|
||||||
{
|
|
||||||
//await AddLineupToAccount(info, CancellationToken.None).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<List<NameIdPair>> GetLineups(ListingsProviderInfo info, string country, string location)
|
|
||||||
{
|
|
||||||
return GetHeadends(info, country, location, CancellationToken.None);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -367,7 +367,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
info = await service.GetChannelStream(channel.ExternalId, mediaSourceId, cancellationToken).ConfigureAwait(false);
|
info = await service.GetChannelStream(channel.ExternalId, mediaSourceId, cancellationToken).ConfigureAwait(false);
|
||||||
info.RequiresClosing = true;
|
info.RequiresClosing = true;
|
||||||
|
|
||||||
if (info.RequiresClosing)
|
if (info.RequiresClosing ?? false)
|
||||||
{
|
{
|
||||||
var idPrefix = service.GetType().FullName.GetMD5().ToString("N") + "_";
|
var idPrefix = service.GetType().FullName.GetMD5().ToString("N") + "_";
|
||||||
|
|
||||||
|
@ -384,7 +384,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
info = await service.GetRecordingStream(recording.ExternalId, null, cancellationToken).ConfigureAwait(false);
|
info = await service.GetRecordingStream(recording.ExternalId, null, cancellationToken).ConfigureAwait(false);
|
||||||
info.RequiresClosing = true;
|
info.RequiresClosing = true;
|
||||||
|
|
||||||
if (info.RequiresClosing)
|
if (info.RequiresClosing ?? false)
|
||||||
{
|
{
|
||||||
var idPrefix = service.GetType().FullName.GetMD5().ToString("N") + "_";
|
var idPrefix = service.GetType().FullName.GetMD5().ToString("N") + "_";
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
|
|
||||||
// Do not use a pipe here because Roku http requests to the server will fail, without any explicit error message.
|
// Do not use a pipe here because Roku http requests to the server will fail, without any explicit error message.
|
||||||
private const char StreamIdDelimeter = '_';
|
private const char StreamIdDelimeter = '_';
|
||||||
private const string StreamIdDelimeterString = "|";
|
private const string StreamIdDelimeterString = "_";
|
||||||
|
|
||||||
private async Task<IEnumerable<MediaSourceInfo>> GetMediaSourcesInternal(ILiveTvItem item, CancellationToken cancellationToken)
|
private async Task<IEnumerable<MediaSourceInfo>> GetMediaSourcesInternal(ILiveTvItem item, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
@ -86,14 +86,22 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
foreach (var source in list)
|
foreach (var source in list)
|
||||||
{
|
{
|
||||||
source.Type = MediaSourceType.Default;
|
source.Type = MediaSourceType.Default;
|
||||||
source.RequiresOpening = true;
|
|
||||||
source.BufferMs = source.BufferMs ?? 1500;
|
|
||||||
|
|
||||||
var openKeys = new List<string>();
|
if (!source.RequiresOpening.HasValue)
|
||||||
openKeys.Add(item.GetType().Name);
|
{
|
||||||
openKeys.Add(item.Id.ToString("N"));
|
source.RequiresOpening = true;
|
||||||
openKeys.Add(source.Id ?? string.Empty);
|
}
|
||||||
source.OpenToken = string.Join(StreamIdDelimeterString, openKeys.ToArray());
|
|
||||||
|
if (source.RequiresOpening.HasValue && source.RequiresOpening.Value)
|
||||||
|
{
|
||||||
|
var openKeys = new List<string>();
|
||||||
|
openKeys.Add(item.GetType().Name);
|
||||||
|
openKeys.Add(item.Id.ToString("N"));
|
||||||
|
openKeys.Add(source.Id ?? string.Empty);
|
||||||
|
source.OpenToken = string.Join(StreamIdDelimeterString, openKeys.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
source.BufferMs = source.BufferMs ?? 1500;
|
||||||
|
|
||||||
// Dummy this up so that direct play checks can still run
|
// Dummy this up so that direct play checks can still run
|
||||||
if (string.IsNullOrEmpty(source.Path) && source.Protocol == MediaProtocol.Http)
|
if (string.IsNullOrEmpty(source.Path) && source.Protocol == MediaProtocol.Http)
|
||||||
|
|
|
@ -72,6 +72,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Strip off the port
|
||||||
|
url = new Uri(url).GetComponents(UriComponents.AbsoluteUri & ~UriComponents.Port, UriFormat.UriEscaped);
|
||||||
|
|
||||||
await _liveTvManager.SaveTunerHost(new TunerHostInfo
|
await _liveTvManager.SaveTunerHost(new TunerHostInfo
|
||||||
{
|
{
|
||||||
Type = HdHomerunHost.DeviceType,
|
Type = HdHomerunHost.DeviceType,
|
||||||
|
@ -103,13 +106,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
|
|
||||||
url = url.TrimEnd('/');
|
url = url.TrimEnd('/');
|
||||||
|
|
||||||
// If there isn't a port, add the default port of 80
|
// Strip off the port
|
||||||
if (url.Split(':').Length < 3)
|
return new Uri(url).GetComponents(UriComponents.AbsoluteUri & ~UriComponents.Port, UriFormat.UriEscaped);
|
||||||
{
|
|
||||||
url += ":80";
|
|
||||||
}
|
|
||||||
|
|
||||||
return url;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private LiveTvOptions GetConfiguration()
|
private LiveTvOptions GetConfiguration()
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
{
|
{
|
||||||
var options = new HttpRequestOptions
|
var options = new HttpRequestOptions
|
||||||
{
|
{
|
||||||
Url = string.Format("{0}/lineup.json", GetApiUrl(info)),
|
Url = string.Format("{0}/lineup.json", GetApiUrl(info, false)),
|
||||||
CancellationToken = cancellationToken
|
CancellationToken = cancellationToken
|
||||||
};
|
};
|
||||||
using (var stream = await _httpClient.Get(options))
|
using (var stream = await _httpClient.Get(options))
|
||||||
|
@ -79,7 +79,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
|
|
||||||
using (var stream = await _httpClient.Get(new HttpRequestOptions()
|
using (var stream = await _httpClient.Get(new HttpRequestOptions()
|
||||||
{
|
{
|
||||||
Url = string.Format("{0}/", GetApiUrl(info)),
|
Url = string.Format("{0}/", GetApiUrl(info, false)),
|
||||||
CancellationToken = cancellationToken
|
CancellationToken = cancellationToken
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
|
@ -97,7 +97,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
|
|
||||||
using (var stream = await _httpClient.Get(new HttpRequestOptions()
|
using (var stream = await _httpClient.Get(new HttpRequestOptions()
|
||||||
{
|
{
|
||||||
Url = string.Format("{0}/tuners.html", GetApiUrl(info)),
|
Url = string.Format("{0}/tuners.html", GetApiUrl(info, false)),
|
||||||
CancellationToken = cancellationToken
|
CancellationToken = cancellationToken
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
|
@ -128,7 +128,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetApiUrl(TunerHostInfo info)
|
private string GetApiUrl(TunerHostInfo info, bool isPlayback)
|
||||||
{
|
{
|
||||||
var url = info.Url;
|
var url = info.Url;
|
||||||
|
|
||||||
|
@ -137,7 +137,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
url = "http://" + url;
|
url = "http://" + url;
|
||||||
}
|
}
|
||||||
|
|
||||||
return url.TrimEnd('/');
|
var uri = new Uri(url);
|
||||||
|
|
||||||
|
if (isPlayback)
|
||||||
|
{
|
||||||
|
var builder = new UriBuilder(uri);
|
||||||
|
builder.Port = 5004;
|
||||||
|
uri = builder.Uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
return uri.AbsoluteUri.TrimEnd('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string StripXML(string source)
|
private static string StripXML(string source)
|
||||||
|
@ -187,21 +196,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
return GetConfiguration().TunerHosts.Where(i => string.Equals(i.Type, Type, StringComparison.OrdinalIgnoreCase)).ToList();
|
return GetConfiguration().TunerHosts.Where(i => string.Equals(i.Type, Type, StringComparison.OrdinalIgnoreCase)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<MediaSourceInfo> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken)
|
private MediaSourceInfo GetMediaSource(TunerHostInfo info, string channelId, string profile)
|
||||||
{
|
{
|
||||||
var channels = await GetChannels(info, cancellationToken).ConfigureAwait(false);
|
var mediaSource = new MediaSourceInfo
|
||||||
var tuners = await GetTunerInfos(info, cancellationToken).ConfigureAwait(false);
|
|
||||||
|
|
||||||
var channel = channels.FirstOrDefault(c => string.Equals(c.Id, channelId, StringComparison.OrdinalIgnoreCase));
|
|
||||||
if (channel != null)
|
|
||||||
{
|
{
|
||||||
if (tuners.FindIndex(t => t.Status == LiveTvTunerStatus.Available) >= 0)
|
Path = GetApiUrl(info, true) + "/auto/v" + channelId,
|
||||||
{
|
Protocol = MediaProtocol.Http,
|
||||||
return new MediaSourceInfo
|
MediaStreams = new List<MediaStream>
|
||||||
{
|
|
||||||
Path = GetApiUrl(info) + "/auto/v" + channelId,
|
|
||||||
Protocol = MediaProtocol.Http,
|
|
||||||
MediaStreams = new List<MediaStream>
|
|
||||||
{
|
{
|
||||||
new MediaStream
|
new MediaStream
|
||||||
{
|
{
|
||||||
|
@ -217,15 +218,28 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
Index = -1
|
Index = -1
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
RequiresOpening = false,
|
||||||
}
|
RequiresClosing = false,
|
||||||
|
BufferMs = 1000
|
||||||
|
};
|
||||||
|
|
||||||
throw new ApplicationException("No tuners avaliable.");
|
return mediaSource;
|
||||||
}
|
|
||||||
throw new ApplicationException("Channel not found.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var list = new List<MediaSourceInfo>();
|
||||||
|
|
||||||
|
list.Add(GetMediaSource(info, channelId, null));
|
||||||
|
|
||||||
|
return Task.FromResult(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<MediaSourceInfo> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
return GetMediaSource(info, channelId, null);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task Validate(TunerHostInfo info)
|
public async Task Validate(TunerHostInfo info)
|
||||||
{
|
{
|
||||||
|
|
|
@ -171,7 +171,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
|
||||||
Index = -1
|
Index = -1
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
RequiresOpening = false,
|
||||||
|
RequiresClosing = false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
throw new ApplicationException("Host doesnt provide this channel");
|
throw new ApplicationException("Host doesnt provide this channel");
|
||||||
|
@ -193,5 +195,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
|
||||||
throw new FileNotFoundException();
|
throw new FileNotFoundException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1489,5 +1489,5 @@
|
||||||
"GuideProviderListingsStep": "Step 2: Select Listings",
|
"GuideProviderListingsStep": "Step 2: Select Listings",
|
||||||
"GuideProviderLoginStep": "Step 1: Login",
|
"GuideProviderLoginStep": "Step 1: Login",
|
||||||
"LabelLineup": "Lineup",
|
"LabelLineup": "Lineup",
|
||||||
"MessageTunerDeviceNotListed": "Is your tuner device not listed? Try installing an external service plugin for more Live TV options."
|
"MessageTunerDeviceNotListed": "Is your tuner device not listed? Try installing an external service provider for more Live TV options."
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user