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() public void Close()
{ {
#if NET46 #if NET46

@ -31,7 +31,7 @@ namespace Emby.Common.Implementations.Net
_logger = logger; _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 try
{ {

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

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

@ -13,7 +13,7 @@ using MediaBrowser.Model.MediaInfo;
namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{ {
public class HdHomerunLiveStream : LiveStream, IDirectStreamProvider public class HdHomerunHttpStream : LiveStream, IDirectStreamProvider
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IHttpClient _httpClient; 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 TaskCompletionSource<bool> _liveStreamTaskCompletionSource = new TaskCompletionSource<bool>();
private readonly MulticastStream _multicastStream; 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) : base(mediaSource)
{ {
_fileSystem = fileSystem; _fileSystem = fileSystem;

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

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

@ -30,7 +30,7 @@ namespace MediaBrowser.Model.Net
/// <returns>A <see cref="ISocket"/> implementation.</returns> /// <returns>A <see cref="ISocket"/> implementation.</returns>
ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort); 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 public enum SocketType

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

@ -67,7 +67,7 @@ namespace SocketHttpListener.Net
{ {
try 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) catch (SocketCreateException ex)
{ {
@ -78,7 +78,7 @@ namespace SocketHttpListener.Net
{ {
endpoint = new IpEndPointInfo(IpAddressInfo.Any, endpoint.Port); endpoint = new IpEndPointInfo(IpAddressInfo.Any, endpoint.Port);
_enableDualMode = false; _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 else
{ {

Loading…
Cancel
Save