|
@@ -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;
|
|
@@ -82,7 +81,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 +132,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 +161,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)
|
|
if (read > 0)
|
|
{
|
|
{
|
|
- await fileStream.WriteAsync(buffer, RtpHeaderBytes, read).ConfigureAwait(false);
|
|
|
|
|
|
+ fileStream.Write(buffer, RtpHeaderBytes, read);
|
|
}
|
|
}
|
|
|
|
|
|
if (!resolved)
|
|
if (!resolved)
|
|
@@ -195,10 +203,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- finally
|
|
|
|
- {
|
|
|
|
- ArrayPool<byte>.Shared.Return(buffer);
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|