From d5ea8ca3ad378fc7e0a18ad314e1dfce07003ab6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 3 Nov 2016 19:35:19 -0400 Subject: move classes to portable --- .../LiveTv/TunerHosts/MulticastStream.cs | 96 ++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 Emby.Server.Implementations/LiveTv/TunerHosts/MulticastStream.cs (limited to 'Emby.Server.Implementations/LiveTv/TunerHosts/MulticastStream.cs') diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/MulticastStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/MulticastStream.cs new file mode 100644 index 0000000000..360a2cee78 --- /dev/null +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/MulticastStream.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Model.Logging; + +namespace Emby.Server.Implementations.LiveTv.TunerHosts +{ + public class MulticastStream + { + private readonly List _outputStreams = new List(); + private const int BufferSize = 81920; + private CancellationToken _cancellationToken; + private readonly ILogger _logger; + + public MulticastStream(ILogger logger) + { + _logger = logger; + } + + public async Task CopyUntilCancelled(Stream source, Action onStarted, CancellationToken cancellationToken) + { + _cancellationToken = cancellationToken; + + while (!cancellationToken.IsCancellationRequested) + { + byte[] buffer = new byte[BufferSize]; + + var bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false); + + if (bytesRead > 0) + { + byte[] copy = new byte[bytesRead]; + Buffer.BlockCopy(buffer, 0, copy, 0, bytesRead); + + List streams = null; + + lock (_outputStreams) + { + streams = _outputStreams.ToList(); + } + + foreach (var stream in streams) + { + stream.Queue(copy); + } + + if (onStarted != null) + { + var onStartedCopy = onStarted; + onStarted = null; + Task.Run(onStartedCopy); + } + } + + else + { + await Task.Delay(100).ConfigureAwait(false); + } + } + } + + public Task CopyToAsync(Stream stream) + { + var result = new QueueStream(stream, _logger) + { + OnFinished = OnFinished + }; + + lock (_outputStreams) + { + _outputStreams.Add(result); + } + + result.Start(_cancellationToken); + + return result.TaskCompletion.Task; + } + + public void RemoveOutputStream(QueueStream stream) + { + lock (_outputStreams) + { + _outputStreams.Remove(stream); + } + } + + private void OnFinished(QueueStream queueStream) + { + RemoveOutputStream(queueStream); + } + } +} -- cgit v1.2.3