Browse Source

Merge pull request #1633 from Bond-009/udpclient

Attempt to fix #1391
Anthony Lavado 5 years ago
parent
commit
efaa668158

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

@@ -584,9 +584,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
                     Logger,
                     Config.ApplicationPaths,
                     _appHost,
-                    _socketFactory,
                     _networkManager,
                     _streamHelper);
+
             }
 
             var enableHttpStream = true;
@@ -601,9 +601,19 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
                 {
                     httpUrl += "?transcode=" + profile;
                 }
+
                 mediaSource.Path = httpUrl;
 
-                return new SharedHttpStream(mediaSource, info, streamId, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _streamHelper);
+                return new SharedHttpStream(
+                    mediaSource,
+                    info,
+                    streamId,
+                    FileSystem,
+                    _httpClient,
+                    Logger,
+                    Config.ApplicationPaths,
+                    _appHost,
+                    _streamHelper);
             }
 
             return new HdHomerunUdpStream(
@@ -616,7 +626,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
                 Logger,
                 Config.ApplicationPaths,
                 _appHost,
-                _socketFactory,
                 _networkManager,
                 _streamHelper);
         }

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

@@ -1,5 +1,4 @@
 using System;
-using System.Buffers;
 using System.Collections.Generic;
 using System.IO;
 using System.Net;
@@ -22,8 +21,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
         private const int RtpHeaderBytes = 12;
 
         private readonly IServerApplicationHost _appHost;
-        private readonly MediaBrowser.Model.Net.ISocketFactory _socketFactory;
-
         private readonly IHdHomerunChannelCommands _channelCommands;
         private readonly int _numTuners;
         private readonly INetworkManager _networkManager;
@@ -38,13 +35,11 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
             ILogger logger,
             IServerApplicationPaths appPaths,
             IServerApplicationHost appHost,
-            MediaBrowser.Model.Net.ISocketFactory socketFactory,
             INetworkManager networkManager,
             IStreamHelper streamHelper)
             : base(mediaSource, tunerHostInfo, fileSystem, logger, appPaths, streamHelper)
         {
             _appHost = appHost;
-            _socketFactory = socketFactory;
             _networkManager = networkManager;
             OriginalStreamId = originalStreamId;
             _channelCommands = channelCommands;
@@ -82,7 +77,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
                 }
             }
 
-            var udpClient = _socketFactory.CreateUdpSocket(localPort);
+            var udpClient = new UdpClient(localPort, AddressFamily.InterNetwork);
             var hdHomerunManager = new HdHomerunManager();
 
             try
@@ -133,7 +128,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
             await taskCompletionSource.Task.ConfigureAwait(false);
         }
 
-        private Task StartStreaming(MediaBrowser.Model.Net.ISocket udpClient, HdHomerunManager hdHomerunManager, IPAddress remoteAddress, TaskCompletionSource<bool> openTaskCompletionSource, CancellationToken cancellationToken)
+        private Task StartStreaming(UdpClient udpClient, HdHomerunManager hdHomerunManager, IPAddress remoteAddress, TaskCompletionSource<bool> openTaskCompletionSource, CancellationToken cancellationToken)
         {
             return Task.Run(async () =>
             {
@@ -162,28 +157,37 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
             });
         }
 
-        private async Task CopyTo(MediaBrowser.Model.Net.ISocket udpClient, string file, TaskCompletionSource<bool> openTaskCompletionSource, CancellationToken cancellationToken)
+        private async Task CopyTo(UdpClient udpClient, string file, TaskCompletionSource<bool> openTaskCompletionSource, CancellationToken cancellationToken)
         {
-            byte[] buffer = ArrayPool<byte>.Shared.Rent(StreamDefaults.DefaultCopyToBufferSize);
-            try
+            var resolved = false;
+
+            using (var fileStream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.Read))
             {
-                using (var source = _socketFactory.CreateNetworkStream(udpClient, false))
-                using (var fileStream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.Read))
+                while (true)
                 {
-                    var currentCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, new CancellationTokenSource(TimeSpan.FromSeconds(30)).Token).Token;
-                    int read;
-                    var resolved = false;
-                    while ((read = await source.ReadAsync(buffer, 0, buffer.Length, currentCancellationToken).ConfigureAwait(false)) != 0)
+                    cancellationToken.ThrowIfCancellationRequested();
+                    using (var timeOutSource = new CancellationTokenSource())
+                    using (var linkedSource = CancellationTokenSource.CreateLinkedTokenSource(
+                        cancellationToken,
+                        timeOutSource.Token))
                     {
-                        cancellationToken.ThrowIfCancellationRequested();
+                        var resTask = udpClient.ReceiveAsync();
+                        if (await Task.WhenAny(resTask, Task.Delay(30000, linkedSource.Token)).ConfigureAwait(false) != resTask)
+                        {
+                            resTask.Dispose();
+                            break;
+                        }
 
-                        currentCancellationToken = cancellationToken;
+                        // We don't want all these delay tasks to keep running
+                        timeOutSource.Cancel();
+                        var res = await resTask.ConfigureAwait(false);
+                        var buffer = res.Buffer;
 
-                        read -= RtpHeaderBytes;
+                        var read = buffer.Length - RtpHeaderBytes;
 
                         if (read > 0)
                         {
-                            await fileStream.WriteAsync(buffer, RtpHeaderBytes, read).ConfigureAwait(false);
+                            fileStream.Write(buffer, RtpHeaderBytes, read);
                         }
 
                         if (!resolved)
@@ -195,10 +199,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
                     }
                 }
             }
-            finally
-            {
-                ArrayPool<byte>.Shared.Return(buffer);
-            }
         }
     }
 }

+ 2 - 1
Emby.Server.Implementations/Net/SocketFactory.cs

@@ -19,7 +19,8 @@ namespace Emby.Server.Implementations.Net
                 throw new ArgumentException("localPort cannot be less than zero.", nameof(localPort));
             }
 
-            var retVal = new Socket(AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp);
+            var retVal = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
+
             try
             {
                 retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);