aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs')
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs145
1 files changed, 145 insertions, 0 deletions
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
new file mode 100644
index 000000000..a33b0945b
--- /dev/null
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
@@ -0,0 +1,145 @@
+using System;
+using System.IO;
+using System.Threading;
+using System.Threading.Tasks;
+using Emby.Server.Implementations.IO;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.LiveTv;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.MediaInfo;
+using MediaBrowser.Model.System;
+using System.Globalization;
+using MediaBrowser.Controller.IO;
+
+namespace Emby.Server.Implementations.LiveTv.TunerHosts
+{
+ public class SharedHttpStream : LiveStream, IDirectStreamProvider
+ {
+ private readonly IHttpClient _httpClient;
+ private readonly IServerApplicationHost _appHost;
+
+ public SharedHttpStream(MediaSourceInfo mediaSource, string originalStreamId, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost, IEnvironmentInfo environment)
+ : base(mediaSource, environment, fileSystem, logger, appPaths)
+ {
+ _httpClient = httpClient;
+ _appHost = appHost;
+ OriginalStreamId = originalStreamId;
+ EnableStreamSharing = true;
+ }
+
+ public override async Task Open(CancellationToken openCancellationToken)
+ {
+ LiveStreamCancellationTokenSource.Token.ThrowIfCancellationRequested();
+
+ var mediaSource = OriginalMediaSource;
+
+ var url = mediaSource.Path;
+
+ FileSystem.CreateDirectory(FileSystem.GetDirectoryName(TempFilePath));
+
+ var typeName = GetType().Name;
+ Logger.Info("Opening " + typeName + " Live stream from {0}", url);
+
+ var response = await _httpClient.SendAsync(new HttpRequestOptions
+ {
+ Url = url,
+ CancellationToken = CancellationToken.None,
+ BufferContent = false,
+
+ // Increase a little bit
+ TimeoutMs = 30000,
+
+ EnableHttpCompression = false,
+
+ LogResponse = true,
+ LogResponseHeaders = true
+
+ }, "GET").ConfigureAwait(false);
+
+ var extension = "ts";
+ var requiresRemux = false;
+
+ var contentType = response.ContentType ?? string.Empty;
+ if (contentType.IndexOf("mp4", StringComparison.OrdinalIgnoreCase) != -1 ||
+ contentType.IndexOf("matroska", StringComparison.OrdinalIgnoreCase) != -1 ||
+ contentType.IndexOf("dash", StringComparison.OrdinalIgnoreCase) != -1 ||
+ contentType.IndexOf("mpegURL", StringComparison.OrdinalIgnoreCase) != -1)
+ {
+ requiresRemux = true;
+ }
+
+ // Close the stream without any sharing features
+ if (requiresRemux)
+ {
+ using (response)
+ {
+ return;
+ }
+ }
+
+ SetTempFilePath(extension);
+
+ var taskCompletionSource = new TaskCompletionSource<bool>();
+ StartStreaming(response, taskCompletionSource, LiveStreamCancellationTokenSource.Token);
+
+ //OpenedMediaSource.Protocol = MediaProtocol.File;
+ //OpenedMediaSource.Path = tempFile;
+ //OpenedMediaSource.ReadAtNativeFramerate = true;
+
+ OpenedMediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1") + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
+ OpenedMediaSource.Protocol = MediaProtocol.Http;
+
+ //OpenedMediaSource.Path = _tempFilePath;
+ //OpenedMediaSource.Protocol = MediaProtocol.File;
+ //OpenedMediaSource.SupportsDirectPlay = false;
+ //OpenedMediaSource.SupportsDirectStream = true;
+ //OpenedMediaSource.SupportsTranscoding = true;
+ await taskCompletionSource.Task.ConfigureAwait(false);
+ }
+
+ protected override void CloseInternal()
+ {
+ LiveStreamCancellationTokenSource.Cancel();
+ }
+
+ private Task StartStreaming(HttpResponseInfo response, TaskCompletionSource<bool> openTaskCompletionSource, CancellationToken cancellationToken)
+ {
+ return Task.Run(async () =>
+ {
+ try
+ {
+ using (response)
+ {
+ using (var stream = response.Content)
+ {
+ Logger.Info("Beginning {0} stream to {1}", GetType().Name, TempFilePath);
+
+ using (var fileStream = FileSystem.GetFileStream(TempFilePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, FileOpenOptions.None))
+ {
+ StreamHelper.CopyTo(stream, fileStream, 81920, () => Resolve(openTaskCompletionSource), cancellationToken);
+ }
+ }
+ }
+ }
+ catch (OperationCanceledException)
+ {
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error copying live stream.", ex);
+ }
+ EnableStreamSharing = false;
+ await DeleteTempFile(TempFilePath).ConfigureAwait(false);
+ });
+ }
+
+ private void Resolve(TaskCompletionSource<bool> openTaskCompletionSource)
+ {
+ openTaskCompletionSource.TrySetResult(true);
+ }
+ }
+}