pull/1154/head
Luke Pulverenti 8 years ago
parent b9c12ca4a7
commit 7cbc76af27

@ -47,6 +47,13 @@ namespace Emby.Common.Implementations.Net
}
}
public void Connect(IpEndPointInfo endPoint)
{
var nativeEndpoint = NetworkManager.ToIPEndPoint(endPoint);
Socket.Connect(nativeEndpoint);
}
public void Close()
{
#if NET46

@ -31,7 +31,7 @@ namespace Emby.Common.Implementations.Net
_logger = logger;
}
public IAcceptSocket CreateAcceptSocket(IpAddressFamily family, MediaBrowser.Model.Net.SocketType socketType, MediaBrowser.Model.Net.ProtocolType protocolType, bool dualMode)
public IAcceptSocket CreateSocket(IpAddressFamily family, MediaBrowser.Model.Net.SocketType socketType, MediaBrowser.Model.Net.ProtocolType protocolType, bool dualMode)
{
try
{

@ -172,8 +172,8 @@
<Compile Include="LiveTv\TunerHosts\HdHomerun\HdHomerunManager.cs" />
<Compile Include="LiveTv\TunerHosts\HdHomerun\HdHomerunDiscovery.cs" />
<Compile Include="LiveTv\TunerHosts\HdHomerun\HdHomerunHost.cs" />
<Compile Include="LiveTv\TunerHosts\HdHomerun\HdHomerunLiveStream.cs" />
<Compile Include="LiveTv\TunerHosts\HdHomerun\LegacyHdHomerunLiveStream.cs" />
<Compile Include="LiveTv\TunerHosts\HdHomerun\HdHomerunHttpStream.cs" />
<Compile Include="LiveTv\TunerHosts\HdHomerun\HdHomerunUdpStream.cs" />
<Compile Include="LiveTv\TunerHosts\M3uParser.cs" />
<Compile Include="LiveTv\TunerHosts\M3UTunerHost.cs" />
<Compile Include="LiveTv\TunerHosts\MulticastStream.cs" />

@ -29,14 +29,16 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
private readonly IFileSystem _fileSystem;
private readonly IServerApplicationHost _appHost;
private readonly ISocketFactory _socketFactory;
private readonly INetworkManager _networkManager;
public HdHomerunHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IHttpClient httpClient, IFileSystem fileSystem, IServerApplicationHost appHost, ISocketFactory socketFactory)
public HdHomerunHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IHttpClient httpClient, IFileSystem fileSystem, IServerApplicationHost appHost, ISocketFactory socketFactory, INetworkManager networkManager)
: base(config, logger, jsonSerializer, mediaEncoder)
{
_httpClient = httpClient;
_fileSystem = fileSystem;
_appHost = appHost;
_socketFactory = socketFactory;
_networkManager = networkManager;
}
public string Name
@ -89,6 +91,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
private class HdHomerunChannelInfo : ChannelInfo
{
public bool IsLegacyTuner { get; set; }
public string Url { get; set; }
}
protected override async Task<List<ChannelInfo>> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken)
@ -106,7 +109,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
AudioCodec = i.AudioCodec,
VideoCodec = i.VideoCodec,
ChannelType = ChannelType.TV,
IsLegacyTuner = (i.URL ?? string.Empty).StartsWith("hdhomerun", StringComparison.OrdinalIgnoreCase)
IsLegacyTuner = (i.URL ?? string.Empty).StartsWith("hdhomerun", StringComparison.OrdinalIgnoreCase),
Url = i.URL
}).Cast<ChannelInfo>().ToList();
}
@ -500,7 +504,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
var hdhrId = GetHdHrIdFromChannelId(channelId);
var channels = await GetChannels(info, true, CancellationToken.None).ConfigureAwait(false);
var channelInfo = channels.FirstOrDefault(i => string.Equals(i.Number, channelId, StringComparison.OrdinalIgnoreCase));
var channelInfo = channels.FirstOrDefault(i => string.Equals(i.Id, channelId, StringComparison.OrdinalIgnoreCase));
var hdHomerunChannelInfo = channelInfo as HdHomerunChannelInfo;
@ -570,24 +574,23 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
var hdhrId = GetHdHrIdFromChannelId(channelId);
var channels = await GetChannels(info, true, CancellationToken.None).ConfigureAwait(false);
var channelInfo = channels.FirstOrDefault(i => string.Equals(i.Number, channelId, StringComparison.OrdinalIgnoreCase));
var channelInfo = channels.FirstOrDefault(i => string.Equals(i.Id, channelId, StringComparison.OrdinalIgnoreCase));
var hdhomerunChannel = channelInfo as HdHomerunChannelInfo;
if (hdhomerunChannel != null && hdhomerunChannel.IsLegacyTuner)
{
var modelInfo = await GetModelInfo(info, false, cancellationToken).ConfigureAwait(false);
var mediaSource = GetLegacyMediaSource(info, hdhrId, channelInfo);
var liveStream = new HdHomerunLiveStream(mediaSource, streamId, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost);
liveStream.EnableStreamSharing = true;
var liveStream = new HdHomerunUdpStream(mediaSource, streamId, hdhomerunChannel.Url, modelInfo.TunerCount, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _socketFactory, _networkManager);
return liveStream;
}
else
{
var mediaSource = GetMediaSource(info, hdhrId, channelInfo, profile);
var liveStream = new HdHomerunLiveStream(mediaSource, streamId, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost);
liveStream.EnableStreamSharing = true;
var liveStream = new HdHomerunHttpStream(mediaSource, streamId, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost);
return liveStream;
}
}

@ -13,7 +13,7 @@ using MediaBrowser.Model.MediaInfo;
namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
public class HdHomerunLiveStream : LiveStream, IDirectStreamProvider
public class HdHomerunHttpStream : LiveStream, IDirectStreamProvider
{
private readonly ILogger _logger;
private readonly IHttpClient _httpClient;
@ -25,7 +25,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
private readonly TaskCompletionSource<bool> _liveStreamTaskCompletionSource = new TaskCompletionSource<bool>();
private readonly MulticastStream _multicastStream;
public HdHomerunLiveStream(MediaSourceInfo mediaSource, string originalStreamId, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost)
public HdHomerunHttpStream(MediaSourceInfo mediaSource, string originalStreamId, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost)
: base(mediaSource)
{
_fileSystem = fileSystem;

@ -17,7 +17,7 @@ using MediaBrowser.Model.Net;
namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
public class LegacyHdHomerunLiveStream : LiveStream, IDirectStreamProvider
public class HdHomerunUdpStream : LiveStream, IDirectStreamProvider
{
private readonly ILogger _logger;
private readonly IHttpClient _httpClient;
@ -33,7 +33,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
private readonly int _numTuners;
private readonly INetworkManager _networkManager;
public LegacyHdHomerunLiveStream(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, string channelUrl, int numTuners, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost, ISocketFactory socketFactory, INetworkManager networkManager)
: base(mediaSource)
{
_fileSystem = fileSystem;
@ -58,7 +58,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
var uri = new Uri(mediaSource.Path);
var localPort = _networkManager.GetRandomUnusedUdpPort();
_logger.Info("Opening Legacy HDHR Live stream from {0}", uri.Host);
_logger.Info("Opening HDHR UDP Live stream from {0}", uri.Host);
var taskCompletionSource = new TaskCompletionSource<bool>();
@ -81,7 +81,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
public override Task Close()
{
_logger.Info("Closing Legacy HDHR live stream");
_logger.Info("Closing HDHR UDP live stream");
_liveStreamCancellationTokenSource.Cancel();
return _liveStreamTaskCompletionSource.Task;
@ -89,74 +89,78 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
private async Task StartStreaming(string remoteIp, int localPort, TaskCompletionSource<bool> openTaskCompletionSource, CancellationToken cancellationToken)
{
//await Task.Run(async () =>
//{
// var isFirstAttempt = true;
// var udpClient = _socketFactory.CreateUdpSocket(localPort);
// using (var legCommand = new HdHomerunManager(_socketFactory))
// {
// var remoteAddress = new IpAddressInfo(remoteIp, IpAddressFamily.InterNetwork);
// IpAddressInfo localAddress = null;
// var tcpSocket = _socketFactory.CreateSocket(IpAddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp, false);
// try
// {
// tcpSocket.Connect(new IpEndPointInfo(remoteAddress, LegacyHdHomerunCommand.HdHomeRunPort));
// localAddress = tcpSocket.LocalEndPoint.IpAddress;
// tcpSocket.Close();
// }
// catch (Exception)
// {
// _logger.Error("Unable to determine local ip address for Legacy HDHomerun stream.");
// return;
// }
// while (!cancellationToken.IsCancellationRequested)
// {
// try
// {
// // send url to start streaming
// await legCommand.StartStreaming(remoteAddress, localAddress, localPort, _channelUrl, _numTuners, cancellationToken).ConfigureAwait(false);
// var response = await udpClient.ReceiveAsync(cancellationToken).ConfigureAwait(false);
// _logger.Info("Opened Legacy HDHR stream from {0}", _channelUrl);
// if (!cancellationToken.IsCancellationRequested)
// {
// Action onStarted = null;
// if (isFirstAttempt)
// {
// onStarted = () => openTaskCompletionSource.TrySetResult(true);
// }
// var stream = new UdpClientStream(udpClient);
// await _multicastStream.CopyUntilCancelled(stream, onStarted, cancellationToken).ConfigureAwait(false);
// }
// }
// catch (OperationCanceledException)
// {
// break;
// }
// catch (Exception ex)
// {
// if (isFirstAttempt)
// {
// _logger.ErrorException("Error opening live stream:", ex);
// openTaskCompletionSource.TrySetException(ex);
// break;
// }
// _logger.ErrorException("Error copying live stream, will reopen", ex);
// }
// isFirstAttempt = false;
// }
// await legCommand.StopStreaming().ConfigureAwait(false);
// udpClient.Dispose();
// _liveStreamTaskCompletionSource.TrySetResult(true);
// }
//}).ConfigureAwait(false);
await Task.Run(async () =>
{
var isFirstAttempt = true;
using (var udpClient = _socketFactory.CreateUdpSocket(localPort))
{
using (var hdHomerunManager = new HdHomerunManager(_socketFactory))
{
var remoteAddress = new IpAddressInfo(remoteIp, IpAddressFamily.InterNetwork);
IpAddressInfo localAddress = null;
using (var tcpSocket = _socketFactory.CreateSocket(IpAddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp, false))
{
try
{
tcpSocket.Connect(new IpEndPointInfo(remoteAddress, HdHomerunManager.HdHomeRunPort));
localAddress = tcpSocket.LocalEndPoint.IpAddress;
tcpSocket.Close();
}
catch (Exception)
{
_logger.Error("Unable to determine local ip address for Legacy HDHomerun stream.");
return;
}
}
while (!cancellationToken.IsCancellationRequested)
{
try
{
// send url to start streaming
await hdHomerunManager.StartStreaming(remoteAddress, localAddress, localPort, _channelUrl, _numTuners, cancellationToken).ConfigureAwait(false);
var response = await udpClient.ReceiveAsync(cancellationToken).ConfigureAwait(false);
_logger.Info("Opened HDHR UDP stream from {0}", _channelUrl);
if (!cancellationToken.IsCancellationRequested)
{
Action onStarted = null;
if (isFirstAttempt)
{
onStarted = () => openTaskCompletionSource.TrySetResult(true);
}
var stream = new UdpClientStream(udpClient);
await _multicastStream.CopyUntilCancelled(stream, onStarted, cancellationToken).ConfigureAwait(false);
}
}
catch (OperationCanceledException)
{
break;
}
catch (Exception ex)
{
if (isFirstAttempt)
{
_logger.ErrorException("Error opening live stream:", ex);
openTaskCompletionSource.TrySetException(ex);
break;
}
_logger.ErrorException("Error copying live stream, will reopen", ex);
}
isFirstAttempt = false;
}
await hdHomerunManager.StopStreaming().ConfigureAwait(false);
udpClient.Dispose();
_liveStreamTaskCompletionSource.TrySetResult(true);
}
}
}).ConfigureAwait(false);
}
public Task CopyToAsync(Stream stream, CancellationToken cancellationToken)

@ -11,7 +11,7 @@ namespace MediaBrowser.Model.Net
void Shutdown(bool both);
void Listen(int backlog);
void Bind(IpEndPointInfo endpoint);
void Connect(IpEndPointInfo endPoint);
void StartAccept(Action<IAcceptSocket> onAccept, Func<bool> isClosed);
}

@ -30,7 +30,7 @@ namespace MediaBrowser.Model.Net
/// <returns>A <see cref="ISocket"/> implementation.</returns>
ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort);
IAcceptSocket CreateAcceptSocket(IpAddressFamily family, SocketType socketType, ProtocolType protocolType, bool dualMode);
IAcceptSocket CreateSocket(IpAddressFamily family, SocketType socketType, ProtocolType protocolType, bool dualMode);
}
public enum SocketType

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

@ -67,7 +67,7 @@ namespace SocketHttpListener.Net
{
try
{
sock = _socketFactory.CreateAcceptSocket(endpoint.IpAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp, _enableDualMode);
sock = _socketFactory.CreateSocket(endpoint.IpAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp, _enableDualMode);
}
catch (SocketCreateException ex)
{
@ -78,7 +78,7 @@ namespace SocketHttpListener.Net
{
endpoint = new IpEndPointInfo(IpAddressInfo.Any, endpoint.Port);
_enableDualMode = false;
sock = _socketFactory.CreateAcceptSocket(endpoint.IpAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp, _enableDualMode);
sock = _socketFactory.CreateSocket(endpoint.IpAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp, _enableDualMode);
}
else
{

Loading…
Cancel
Save