diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index e7885a3f8..8505b5d3a 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -924,7 +924,7 @@ namespace MediaBrowser.Api.Playback
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
{
diff --git a/MediaBrowser.Api/Playback/StreamState.cs b/MediaBrowser.Api/Playback/StreamState.cs
index 02b7720a4..4df696096 100644
--- a/MediaBrowser.Api/Playback/StreamState.cs
+++ b/MediaBrowser.Api/Playback/StreamState.cs
@@ -185,7 +185,7 @@ namespace MediaBrowser.Api.Playback
private async void DisposeLiveStream()
{
- if (MediaSource.RequiresClosing && string.IsNullOrWhiteSpace(Request.LiveStreamId))
+ if ((MediaSource.RequiresClosing ?? false) && string.IsNullOrWhiteSpace(Request.LiveStreamId))
{
try
{
diff --git a/MediaBrowser.Controller/LiveTv/ITunerHost.cs b/MediaBrowser.Controller/LiveTv/ITunerHost.cs
index 38ed43bd9..c9a96a9ca 100644
--- a/MediaBrowser.Controller/LiveTv/ITunerHost.cs
+++ b/MediaBrowser.Controller/LiveTv/ITunerHost.cs
@@ -47,6 +47,14 @@ namespace MediaBrowser.Controller.LiveTv
/// Task<MediaSourceInfo>.
Task GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken);
///
+ /// Gets the channel stream media sources.
+ ///
+ /// The information.
+ /// The channel identifier.
+ /// The cancellation token.
+ /// Task<List<MediaSourceInfo>>.
+ Task> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken);
+ ///
/// Validates the specified information.
///
/// The information.
diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
index fbfe79272..9153045e6 100644
--- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
@@ -436,7 +436,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
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
{
diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs
index efce5abb0..bb32ac95b 100644
--- a/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs
@@ -137,7 +137,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
private async void DisposeLiveStream()
{
- if (MediaSource.RequiresClosing)
+ if (MediaSource.RequiresClosing ?? false)
{
try
{
diff --git a/MediaBrowser.Model/Dto/MediaSourceInfo.cs b/MediaBrowser.Model/Dto/MediaSourceInfo.cs
index 8897edcbd..75edc6a52 100644
--- a/MediaBrowser.Model/Dto/MediaSourceInfo.cs
+++ b/MediaBrowser.Model/Dto/MediaSourceInfo.cs
@@ -26,9 +26,9 @@ namespace MediaBrowser.Model.Dto
public bool SupportsDirectStream { get; set; }
public bool SupportsDirectPlay { get; set; }
- public bool RequiresOpening { get; set; }
+ public bool? RequiresOpening { get; set; }
public string OpenToken { get; set; }
- public bool RequiresClosing { get; set; }
+ public bool? RequiresClosing { get; set; }
public string LiveStreamId { get; set; }
public int? BufferMs { get; set; }
diff --git a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
index 90cd8924d..3fc841645 100644
--- a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
+++ b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
@@ -34,5 +34,6 @@ namespace MediaBrowser.Model.LiveTv
public string Password { get; set; }
public string ListingsId { get; set; }
public string ZipCode { get; set; }
+ public string Country { get; set; }
}
}
\ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
index 9b46a8057..765acd578 100644
--- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
@@ -439,7 +439,7 @@ namespace MediaBrowser.Server.Implementations.Library
LiveStreamInfo current;
if (_openStreams.TryGetValue(id, out current))
{
- if (current.MediaSource.RequiresClosing)
+ if (current.MediaSource.RequiresClosing ?? false)
{
var tuple = GetProvider(id);
diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
index 37b6bf086..c32b8da10 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Common;
using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.LiveTv;
@@ -74,20 +75,17 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
var status = new LiveTvServiceStatusInfo();
var list = new List();
- foreach (var host in _liveTvManager.TunerHosts)
+ foreach (var hostInstance in GetTunerHosts())
{
- foreach (var hostInstance in host.GetTunerHosts())
+ try
{
- try
- {
- var tuners = await host.GetTunerInfos(hostInstance, cancellationToken).ConfigureAwait(false);
+ var tuners = await hostInstance.Item1.GetTunerInfos(hostInstance.Item2, cancellationToken).ConfigureAwait(false);
- list.AddRange(tuners);
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error getting tuners", ex);
- }
+ list.AddRange(tuners);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error getting tuners", ex);
}
}
@@ -102,20 +100,23 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{
var list = new List();
- foreach (var host in _liveTvManager.TunerHosts)
+ foreach (var hostInstance in GetTunerHosts())
{
- foreach (var hostInstance in host.GetTunerHosts())
+ try
{
- try
- {
- var channels = await host.GetChannels(hostInstance, cancellationToken).ConfigureAwait(false);
+ var channels = await hostInstance.Item1.GetChannels(hostInstance.Item2, cancellationToken).ConfigureAwait(false);
+ var newChannels = channels.ToList();
- list.AddRange(channels);
- }
- catch (Exception ex)
+ foreach (var channel in newChannels)
{
- _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;
}
+ private List> 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(provider, i);
+ })
+ .Where(i => i != null)
+ .ToList();
+ }
+
public Task CancelSeriesTimerAsync(string timerId, CancellationToken cancellationToken)
{
var remove = _seriesTimerProvider.GetAll().SingleOrDefault(r => r.Id == timerId);
@@ -255,14 +269,27 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
return Task.FromResult((IEnumerable)_seriesTimerProvider.GetAll());
}
+ private string GetOriginalChannelId(string channelId)
+ {
+ var parts = channelId.Split('-');
+
+ return string.Join("-", parts.Skip(1).ToArray());
+ }
+
public async Task> GetProgramsAsync(string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)
{
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);
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)
{
return list;
@@ -290,14 +317,67 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
throw new NotImplementedException();
}
- public Task GetChannelStream(string channelId, string streamId, CancellationToken cancellationToken)
+ public async Task 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> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken)
+ public async Task> 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> GetRecordingStreamMediaSources(string recordingId, CancellationToken cancellationToken)
diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs
index e7feeee5a..75dec5f97 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs
@@ -68,9 +68,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
private void UpdateList(List newList)
{
+ var file = _dataPath + ".json";
+ Directory.CreateDirectory(Path.GetDirectoryName(file));
+
lock (_fileDataLock)
{
- _jsonSerializer.SerializeToFile(newList, _dataPath + ".json");
+ _jsonSerializer.SerializeToFile(newList, file);
_items = newList;
}
}
diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
index ed265d416..72a965c6a 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
@@ -218,7 +218,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings
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 = DateTime.ParseExact(programInfo.airDateTime, "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'",
CultureInfo.InvariantCulture);
DateTime endAt = startAt.AddSeconds(programInfo.duration);
@@ -401,7 +401,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings
_logger.Info("Headends on account ");
var countryParam = string.Equals("ca", country, StringComparison.OrdinalIgnoreCase)
- ? "Canada"
+ ? "can"
: "USA";
var options = new HttpRequestOptions()
@@ -562,6 +562,44 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings
get { return "SchedulesDirect"; }
}
+ private async Task 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(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> GetLineups(ListingsProviderInfo info, string country, string location)
+ {
+ return GetHeadends(info, country, location, CancellationToken.None);
+ }
+
public class ScheduleDirect
{
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> GetLineups(ListingsProviderInfo info, string country, string location)
- {
- return GetHeadends(info, country, location, CancellationToken.None);
- }
}
}
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
index 5be90e6cc..6ef565129 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -367,7 +367,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
info = await service.GetChannelStream(channel.ExternalId, mediaSourceId, cancellationToken).ConfigureAwait(false);
info.RequiresClosing = true;
- if (info.RequiresClosing)
+ if (info.RequiresClosing ?? false)
{
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.RequiresClosing = true;
- if (info.RequiresClosing)
+ if (info.RequiresClosing ?? false)
{
var idPrefix = service.GetType().FullName.GetMD5().ToString("N") + "_";
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
index 5ebb79629..cf34b6b99 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
@@ -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.
private const char StreamIdDelimeter = '_';
- private const string StreamIdDelimeterString = "|";
+ private const string StreamIdDelimeterString = "_";
private async Task> GetMediaSourcesInternal(ILiveTvItem item, CancellationToken cancellationToken)
{
@@ -86,14 +86,22 @@ namespace MediaBrowser.Server.Implementations.LiveTv
foreach (var source in list)
{
source.Type = MediaSourceType.Default;
- source.RequiresOpening = true;
- source.BufferMs = source.BufferMs ?? 1500;
- var openKeys = new List();
- openKeys.Add(item.GetType().Name);
- openKeys.Add(item.Id.ToString("N"));
- openKeys.Add(source.Id ?? string.Empty);
- source.OpenToken = string.Join(StreamIdDelimeterString, openKeys.ToArray());
+ if (!source.RequiresOpening.HasValue)
+ {
+ source.RequiresOpening = true;
+ }
+
+ if (source.RequiresOpening.HasValue && source.RequiresOpening.Value)
+ {
+ var openKeys = new List();
+ 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
if (string.IsNullOrEmpty(source.Path) && source.Protocol == MediaProtocol.Http)
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs
index 4777003d6..cc2bb2d52 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs
@@ -72,6 +72,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
return;
}
+ // Strip off the port
+ url = new Uri(url).GetComponents(UriComponents.AbsoluteUri & ~UriComponents.Port, UriFormat.UriEscaped);
+
await _liveTvManager.SaveTunerHost(new TunerHostInfo
{
Type = HdHomerunHost.DeviceType,
@@ -103,13 +106,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
url = url.TrimEnd('/');
- // If there isn't a port, add the default port of 80
- if (url.Split(':').Length < 3)
- {
- url += ":80";
- }
-
- return url;
+ // Strip off the port
+ return new Uri(url).GetComponents(UriComponents.AbsoluteUri & ~UriComponents.Port, UriFormat.UriEscaped);
}
private LiveTvOptions GetConfiguration()
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
index 187569ab4..d9f1541c8 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
@@ -51,7 +51,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
var options = new HttpRequestOptions
{
- Url = string.Format("{0}/lineup.json", GetApiUrl(info)),
+ Url = string.Format("{0}/lineup.json", GetApiUrl(info, false)),
CancellationToken = cancellationToken
};
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()
{
- Url = string.Format("{0}/", GetApiUrl(info)),
+ Url = string.Format("{0}/", GetApiUrl(info, false)),
CancellationToken = cancellationToken
}))
{
@@ -97,7 +97,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
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
}))
{
@@ -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;
@@ -137,7 +137,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
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)
@@ -187,21 +196,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
return GetConfiguration().TunerHosts.Where(i => string.Equals(i.Type, Type, StringComparison.OrdinalIgnoreCase)).ToList();
}
- public async Task 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 tuners = await GetTunerInfos(info, cancellationToken).ConfigureAwait(false);
-
- var channel = channels.FirstOrDefault(c => string.Equals(c.Id, channelId, StringComparison.OrdinalIgnoreCase));
- if (channel != null)
+ var mediaSource = new MediaSourceInfo
{
- if (tuners.FindIndex(t => t.Status == LiveTvTunerStatus.Available) >= 0)
- {
- return new MediaSourceInfo
- {
- Path = GetApiUrl(info) + "/auto/v" + channelId,
- Protocol = MediaProtocol.Http,
- MediaStreams = new List
+ Path = GetApiUrl(info, true) + "/auto/v" + channelId,
+ Protocol = MediaProtocol.Http,
+ MediaStreams = new List
{
new MediaStream
{
@@ -217,15 +218,28 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
Index = -1
}
- }
- };
- }
+ },
+ RequiresOpening = false,
+ RequiresClosing = false,
+ BufferMs = 1000
+ };
- throw new ApplicationException("No tuners avaliable.");
- }
- throw new ApplicationException("Channel not found.");
+ return mediaSource;
}
+ public Task> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken)
+ {
+ var list = new List();
+
+ list.Add(GetMediaSource(info, channelId, null));
+
+ return Task.FromResult(list);
+ }
+
+ public async Task GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken)
+ {
+ return GetMediaSource(info, channelId, null);
+ }
public async Task Validate(TunerHostInfo info)
{
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
index e91bd0f0b..91f25bbee 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
@@ -171,7 +171,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
Index = -1
}
- }
+ },
+ RequiresOpening = false,
+ RequiresClosing = false
};
}
throw new ApplicationException("Host doesnt provide this channel");
@@ -193,5 +195,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
throw new FileNotFoundException();
}
}
+
+
+ public Task> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken)
+ {
+ throw new NotImplementedException();
+ }
}
}
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json
index 24df7c983..194d406f3 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/server.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json
@@ -1489,5 +1489,5 @@
"GuideProviderListingsStep": "Step 2: Select Listings",
"GuideProviderLoginStep": "Step 1: Login",
"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."
}