Explorar o código

Fix HD Home Run streaming.

* Use LocalEndPoint instead of RemoteEndPoint when determining local address.
* HdHomerunUdpStream.StartStreaming is meant to run until stream is closed, however HdHomerunUdpStream.Open needs to return as soon as stream is open to send stream url back to client. Therefore, StartStreaming should not be awaited on.
* TcpClient(IPEndPoint) treats endpoint as the local endpoint; use TcpClient(string, int) instead as it treats endpoint as the remote endpoint.
Ryan Petris %!s(int64=4) %!d(string=hai) anos
pai
achega
0496e18179

+ 3 - 3
Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunManager.cs

@@ -111,7 +111,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
 
         public async Task<bool> CheckTunerAvailability(IPAddress remoteIp, int tuner, CancellationToken cancellationToken)
         {
-            using (var client = new TcpClient(new IPEndPoint(remoteIp, HdHomeRunPort)))
+            using (var client = new TcpClient(remoteIp.ToString(), HdHomeRunPort))
             using (var stream = client.GetStream())
             {
                 return await CheckTunerAvailability(stream, tuner, cancellationToken).ConfigureAwait(false);
@@ -142,7 +142,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
         {
             _remoteEndPoint = new IPEndPoint(remoteIp, HdHomeRunPort);
 
-            _tcpClient = new TcpClient(_remoteEndPoint);
+            _tcpClient = new TcpClient(_remoteEndPoint.Address.ToString(), _remoteEndPoint.Port);
 
             if (!_lockkey.HasValue)
             {
@@ -221,7 +221,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
                 return;
             }
 
-            using (var tcpClient = new TcpClient(_remoteEndPoint))
+            using (var tcpClient = new TcpClient(_remoteEndPoint.Address.ToString(), _remoteEndPoint.Port))
             using (var stream = tcpClient.GetStream())
             {
                 var commandList = commands.GetCommands();

+ 26 - 25
Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs

@@ -70,7 +70,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
                 try
                 {
                     await tcpClient.ConnectAsync(remoteAddress, HdHomerunManager.HdHomeRunPort).ConfigureAwait(false);
-                    localAddress = ((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address;
+                    localAddress = ((IPEndPoint)tcpClient.Client.LocalEndPoint).Address;
                     tcpClient.Close();
                 }
                 catch (Exception ex)
@@ -80,6 +80,10 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
                 }
             }
 
+            if (localAddress.IsIPv4MappedToIPv6) {
+                localAddress = localAddress.MapToIPv4();
+            }
+
             var udpClient = new UdpClient(localPort, AddressFamily.InterNetwork);
             var hdHomerunManager = new HdHomerunManager();
 
@@ -110,12 +114,12 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
 
             var taskCompletionSource = new TaskCompletionSource<bool>();
 
-            await StartStreaming(
+            StartStreaming(
                 udpClient,
                 hdHomerunManager,
                 remoteAddress,
                 taskCompletionSource,
-                LiveStreamCancellationTokenSource.Token).ConfigureAwait(false);
+                LiveStreamCancellationTokenSource.Token);
 
             // OpenedMediaSource.Protocol = MediaProtocol.File;
             // OpenedMediaSource.Path = tempFile;
@@ -131,33 +135,30 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
             await taskCompletionSource.Task.ConfigureAwait(false);
         }
 
-        private Task StartStreaming(UdpClient udpClient, HdHomerunManager hdHomerunManager, IPAddress remoteAddress, TaskCompletionSource<bool> openTaskCompletionSource, CancellationToken cancellationToken)
+        private async void StartStreaming(UdpClient udpClient, HdHomerunManager hdHomerunManager, IPAddress remoteAddress, TaskCompletionSource<bool> openTaskCompletionSource, CancellationToken cancellationToken)
         {
-            return Task.Run(async () =>
+            using (udpClient)
+            using (hdHomerunManager)
             {
-                using (udpClient)
-                using (hdHomerunManager)
+                try
                 {
-                    try
-                    {
-                        await CopyTo(udpClient, TempFilePath, openTaskCompletionSource, cancellationToken).ConfigureAwait(false);
-                    }
-                    catch (OperationCanceledException ex)
-                    {
-                        Logger.LogInformation("HDHR UDP stream cancelled or timed out from {0}", remoteAddress);
-                        openTaskCompletionSource.TrySetException(ex);
-                    }
-                    catch (Exception ex)
-                    {
-                        Logger.LogError(ex, "Error opening live stream:");
-                        openTaskCompletionSource.TrySetException(ex);
-                    }
-
-                    EnableStreamSharing = false;
+                    await CopyTo(udpClient, TempFilePath, openTaskCompletionSource, cancellationToken).ConfigureAwait(false);
+                }
+                catch (OperationCanceledException ex)
+                {
+                    Logger.LogInformation("HDHR UDP stream cancelled or timed out from {0}", remoteAddress);
+                    openTaskCompletionSource.TrySetException(ex);
                 }
+                catch (Exception ex)
+                {
+                    Logger.LogError(ex, "Error opening live stream:");
+                    openTaskCompletionSource.TrySetException(ex);
+                }
+
+                EnableStreamSharing = false;
+            }
 
-                await DeleteTempFiles(new List<string> { TempFilePath }).ConfigureAwait(false);
-            });
+            await DeleteTempFiles(new List<string> { TempFilePath }).ConfigureAwait(false);
         }
 
         private async Task CopyTo(UdpClient udpClient, string file, TaskCompletionSource<bool> openTaskCompletionSource, CancellationToken cancellationToken)