update legacy hdhomerun support

This commit is contained in:
Luke Pulverenti 2017-03-05 21:32:56 -05:00
parent 00fb471162
commit 9e74d834a7
10 changed files with 90 additions and 82 deletions

View File

@ -39,8 +39,16 @@ namespace Emby.Server.Core.Localization
}
}
try
{
return text.Normalize(form);
}
catch (ArgumentException)
{
// if it still fails, return the original text
return text;
}
}
private static string StripInvalidUnicodeCharacters(string str)
{

View File

@ -579,7 +579,7 @@ namespace Emby.Server.Implementations.HttpServer
}
else
{
ErrorHandler(new FileNotFoundException(), httpReq);
ErrorHandler(new FileNotFoundException(), httpReq, false);
}
}
catch (OperationCanceledException ex)
@ -633,7 +633,6 @@ namespace Emby.Server.Implementations.HttpServer
return null;
}
private void Write(IResponse response, string text)
{
var bOutput = Encoding.UTF8.GetBytes(text);

View File

@ -69,9 +69,11 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
private async Task<List<Channels>> GetLineup(TunerHostInfo info, CancellationToken cancellationToken)
{
var model = await GetModelInfo(info, false, cancellationToken).ConfigureAwait(false);
var options = new HttpRequestOptions
{
Url = string.Format("{0}/lineup.json", GetApiUrl(info, false)),
Url = model.LineupURL,
CancellationToken = cancellationToken,
BufferContent = false
};
@ -451,7 +453,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
string nal = null;
var url = info.Url;
var url = GetApiUrl(info, false);
var id = channelId;
id += "_" + url.GetMD5().ToString("N");
@ -586,18 +588,17 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
if (hdhomerunChannel != null && hdhomerunChannel.IsLegacyTuner)
{
var modelInfo = await GetModelInfo(info, false, cancellationToken).ConfigureAwait(false);
var mediaSource = GetLegacyMediaSource(info, hdhrId, channelInfo);
var modelInfo = await GetModelInfo(info, false, cancellationToken).ConfigureAwait(false);
var liveStream = new HdHomerunUdpStream(mediaSource, streamId, hdhomerunChannel.Url, modelInfo.TunerCount, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _socketFactory, _networkManager);
return liveStream;
return new HdHomerunUdpStream(mediaSource, streamId, new LegacyHdHomerunChannelCommands(hdhomerunChannel.Url), modelInfo.TunerCount, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _socketFactory, _networkManager);
}
else
{
var mediaSource = GetMediaSource(info, hdhrId, channelInfo, profile);
var liveStream = new HdHomerunHttpStream(mediaSource, streamId, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost);
return liveStream;
return new HdHomerunHttpStream(mediaSource, streamId, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost);
//return new HdHomerunUdpStream(mediaSource, streamId, new HdHomerunChannelCommands(hdhomerunChannel.Number), modelInfo.TunerCount, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _socketFactory, _networkManager);
}
}

View File

@ -9,6 +9,60 @@ using MediaBrowser.Model.Net;
namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
public interface IHdHomerunChannelCommands
{
IEnumerable<Tuple<string, string>> GetCommands();
}
public class LegacyHdHomerunChannelCommands : IHdHomerunChannelCommands
{
private string _channel;
private string _program;
public LegacyHdHomerunChannelCommands(string url)
{
// parse url for channel and program
var regExp = new Regex(@"\/ch(\d+)-?(\d*)");
var match = regExp.Match(url);
if (match.Success)
{
_channel = match.Groups[1].Value;
_program = match.Groups[2].Value;
}
}
public IEnumerable<Tuple<string, string>> GetCommands()
{
var commands = new List<Tuple<string, string>>();
if (!String.IsNullOrEmpty(_channel))
commands.Add(Tuple.Create("channel", _channel));
if (!String.IsNullOrEmpty(_program))
commands.Add(Tuple.Create("program", _program));
return commands;
}
}
public class HdHomerunChannelCommands : IHdHomerunChannelCommands
{
private string _channel;
public HdHomerunChannelCommands(string channel)
{
_channel = channel;
}
public IEnumerable<Tuple<string, string>> GetCommands()
{
var commands = new List<Tuple<string, string>>();
if (!String.IsNullOrEmpty(_channel))
commands.Add(Tuple.Create("vchannel", _channel));
return commands;
}
}
public class HdHomerunManager : IDisposable
{
public static int HdHomeRunPort = 65001;
@ -57,15 +111,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
return string.Equals(returnVal, "none", StringComparison.OrdinalIgnoreCase);
}
public async Task StartStreaming(IpAddressInfo remoteIp, IpAddressInfo localIp, int localPort, string url, int numTuners, CancellationToken cancellationToken)
public async Task StartStreaming(IpAddressInfo remoteIp, IpAddressInfo localIp, int localPort, IHdHomerunChannelCommands commands, int numTuners, CancellationToken cancellationToken)
{
_remoteIp = remoteIp;
// parse url for channel and program
string frequency, program;
if (!ParseUrl(url, out frequency, out program))
{
return;
}
using (var tcpClient = _socketFactory.CreateTcpSocket(_remoteIp, HdHomeRunPort))
{
@ -92,7 +140,10 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
if (!ParseReturnMessage(response.Buffer, response.ReceivedBytes, out returnVal))
continue;
var channelMsg = CreateSetMessage(i, "channel", frequency, _lockkey.Value);
var commandList = commands.GetCommands();
foreach(Tuple<string,string> command in commandList)
{
var channelMsg = CreateSetMessage(i, command.Item1, command.Item2, _lockkey.Value);
await tcpClient.SendAsync(channelMsg, channelMsg.Length, ipEndPoint, cancellationToken).ConfigureAwait(false);
await tcpClient.ReceiveAsync(cancellationToken).ConfigureAwait(false);
// parse response to make sure it worked
@ -102,17 +153,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
continue;
}
if (program != String.Empty)
{
var programMsg = CreateSetMessage(i, "program", program, _lockkey.Value);
await tcpClient.SendAsync(programMsg, programMsg.Length, ipEndPoint, cancellationToken).ConfigureAwait(false);
await tcpClient.ReceiveAsync(cancellationToken).ConfigureAwait(false);
// parse response to make sure it worked
if (!ParseReturnMessage(response.Buffer, response.ReceivedBytes, out returnVal))
{
await ReleaseLockkey(tcpClient).ConfigureAwait(false);
continue;
}
}
var targetValue = String.Format("rtp://{0}:{1}", localIp, localPort);
@ -154,22 +194,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
await tcpClient.ReceiveAsync(CancellationToken.None).ConfigureAwait(false);
}
private static bool ParseUrl(string url, out string frequency, out string program)
{
frequency = String.Empty;
program = String.Empty;
var regExp = new Regex(@"\/ch(\d+)-?(\d*)");
var match = regExp.Match(url);
if (match.Success)
{
frequency = match.Groups[1].Value;
program = match.Groups[2].Value;
return true;
}
return false;
}
private static byte[] CreateGetMessage(int tuner, string name)
{
var byteName = Encoding.UTF8.GetBytes(String.Format("/tuner{0}/{1}\0", tuner, name));

View File

@ -29,11 +29,11 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
private readonly CancellationTokenSource _liveStreamCancellationTokenSource = new CancellationTokenSource();
private readonly TaskCompletionSource<bool> _liveStreamTaskCompletionSource = new TaskCompletionSource<bool>();
private readonly MulticastStream _multicastStream;
private readonly string _channelUrl;
private readonly IHdHomerunChannelCommands _channelCommands;
private readonly int _numTuners;
private readonly INetworkManager _networkManager;
public HdHomerunUdpStream(MediaSourceInfo mediaSource, string originalStreamId, string channelUrl, int numTuners, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost, ISocketFactory socketFactory, INetworkManager networkManager)
public HdHomerunUdpStream(MediaSourceInfo mediaSource, string originalStreamId, IHdHomerunChannelCommands channelCommands, int numTuners, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost, ISocketFactory socketFactory, INetworkManager networkManager)
: base(mediaSource)
{
_fileSystem = fileSystem;
@ -45,7 +45,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
_networkManager = networkManager;
OriginalStreamId = originalStreamId;
_multicastStream = new MulticastStream(_logger);
_channelUrl = channelUrl;
_channelCommands = channelCommands;
_numTuners = numTuners;
}
@ -118,10 +118,10 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
try
{
// send url to start streaming
await hdHomerunManager.StartStreaming(remoteAddress, localAddress, localPort, _channelUrl, _numTuners, cancellationToken).ConfigureAwait(false);
await hdHomerunManager.StartStreaming(remoteAddress, localAddress, localPort, _channelCommands, _numTuners, cancellationToken).ConfigureAwait(false);
var response = await udpClient.ReceiveAsync(cancellationToken).ConfigureAwait(false);
_logger.Info("Opened HDHR UDP stream from {0}", _channelUrl);
_logger.Info("Opened HDHR UDP stream from {0}", remoteAddress);
if (!cancellationToken.IsCancellationRequested)
{

View File

@ -16,7 +16,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
private const int BufferSize = 81920;
private CancellationToken _cancellationToken;
private readonly ILogger _logger;
private readonly ConcurrentQueue<byte[]> _sharedBuffer = new ConcurrentQueue<byte[]>();
public MulticastStream(ILogger logger)
{
@ -38,14 +37,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
byte[] copy = new byte[bytesRead];
Buffer.BlockCopy(buffer, 0, copy, 0, bytesRead);
_sharedBuffer.Enqueue(copy);
while (_sharedBuffer.Count > 10000)
{
byte[] bytes;
_sharedBuffer.TryDequeue(out bytes);
}
var allStreams = _outputStreams.ToList();
foreach (var stream in allStreams)
{
@ -74,16 +65,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
OnFinished = OnFinished
};
var list = new List<byte>();
foreach (var bytes in _sharedBuffer)
{
list.AddRange(bytes);
}
_logger.Info("QueueStream started with {0} initial bytes", list.Count);
result.Queue(list.ToArray());
_outputStreams.TryAdd(result.Id, result);
result.Start(_cancellationToken);

View File

@ -170,11 +170,6 @@ namespace MediaBrowser.Providers.TV
/// <exception cref="System.ArgumentNullException">seriesId</exception>
internal async Task DownloadSeriesZip(string seriesId, string idType, string seriesDataPath, long? lastTvDbUpdateTime, string preferredMetadataLanguage, CancellationToken cancellationToken)
{
if (string.IsNullOrWhiteSpace(seriesId))
{
throw new ArgumentNullException("seriesId");
}
try
{
await DownloadSeriesZip(seriesId, idType, seriesDataPath, lastTvDbUpdateTime, preferredMetadataLanguage, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false);

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common</id>
<version>3.0.695</version>
<version>3.0.696</version>
<title>Emby.Common</title>
<authors>Emby Team</authors>
<owners>ebr,Luke,scottisafool</owners>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MediaBrowser.Server.Core</id>
<version>3.0.695</version>
<version>3.0.696</version>
<title>Emby.Server.Core</title>
<authors>Emby Team</authors>
<owners>ebr,Luke,scottisafool</owners>
@ -12,7 +12,7 @@
<description>Contains core components required to build plugins for Emby Server.</description>
<copyright>Copyright © Emby 2013</copyright>
<dependencies>
<dependency id="MediaBrowser.Common" version="3.0.695" />
<dependency id="MediaBrowser.Common" version="3.0.696" />
</dependencies>
</metadata>
<files>

View File

@ -1,3 +1,3 @@
using System.Reflection;
[assembly: AssemblyVersion("3.2.5.6")]
[assembly: AssemblyVersion("3.2.5.7")]