Merge pull request #1633 from Bond-009/udpclient

Attempt to fix #1391
This commit is contained in:
Anthony Lavado 2019-08-28 09:41:11 -04:00 committed by GitHub
commit efaa668158
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 28 deletions

View File

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

View File

@ -1,5 +1,4 @@
using System; using System;
using System.Buffers;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Net; using System.Net;
@ -22,8 +21,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
private const int RtpHeaderBytes = 12; private const int RtpHeaderBytes = 12;
private readonly IServerApplicationHost _appHost; private readonly IServerApplicationHost _appHost;
private readonly MediaBrowser.Model.Net.ISocketFactory _socketFactory;
private readonly IHdHomerunChannelCommands _channelCommands; private readonly IHdHomerunChannelCommands _channelCommands;
private readonly int _numTuners; private readonly int _numTuners;
private readonly INetworkManager _networkManager; private readonly INetworkManager _networkManager;
@ -38,13 +35,11 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
ILogger logger, ILogger logger,
IServerApplicationPaths appPaths, IServerApplicationPaths appPaths,
IServerApplicationHost appHost, IServerApplicationHost appHost,
MediaBrowser.Model.Net.ISocketFactory socketFactory,
INetworkManager networkManager, INetworkManager networkManager,
IStreamHelper streamHelper) IStreamHelper streamHelper)
: base(mediaSource, tunerHostInfo, fileSystem, logger, appPaths, streamHelper) : base(mediaSource, tunerHostInfo, fileSystem, logger, appPaths, streamHelper)
{ {
_appHost = appHost; _appHost = appHost;
_socketFactory = socketFactory;
_networkManager = networkManager; _networkManager = networkManager;
OriginalStreamId = originalStreamId; OriginalStreamId = originalStreamId;
_channelCommands = channelCommands; _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(); var hdHomerunManager = new HdHomerunManager();
try try
@ -133,7 +128,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
await taskCompletionSource.Task.ConfigureAwait(false); 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 () => 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); var resolved = false;
try
using (var fileStream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.Read))
{ {
using (var source = _socketFactory.CreateNetworkStream(udpClient, false)) while (true)
using (var fileStream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.Read))
{ {
var currentCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, new CancellationTokenSource(TimeSpan.FromSeconds(30)).Token).Token; cancellationToken.ThrowIfCancellationRequested();
int read; using (var timeOutSource = new CancellationTokenSource())
var resolved = false; using (var linkedSource = CancellationTokenSource.CreateLinkedTokenSource(
while ((read = await source.ReadAsync(buffer, 0, buffer.Length, currentCancellationToken).ConfigureAwait(false)) != 0) 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) if (read > 0)
{ {
await fileStream.WriteAsync(buffer, RtpHeaderBytes, read).ConfigureAwait(false); fileStream.Write(buffer, RtpHeaderBytes, read);
} }
if (!resolved) if (!resolved)
@ -195,10 +199,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
} }
} }
} }
finally
{
ArrayPool<byte>.Shared.Return(buffer);
}
} }
} }
} }

View File

@ -19,7 +19,8 @@ namespace Emby.Server.Implementations.Net
throw new ArgumentException("localPort cannot be less than zero.", nameof(localPort)); 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 try
{ {
retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);