Browse Source

Merge pull request #4392 from crobibero/livetv-ts-fix

Fix LiveTV TS playback
Claus Vium 4 years ago
parent
commit
83d7e0a265

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

@@ -131,6 +131,11 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
             await taskCompletionSource.Task.ConfigureAwait(false);
         }
 
+        public string GetFilePath()
+        {
+            return TempFilePath;
+        }
+
         private Task StartStreaming(UdpClient udpClient, HdHomerunManager hdHomerunManager, IPAddress remoteAddress, TaskCompletionSource<bool> openTaskCompletionSource, CancellationToken cancellationToken)
         {
             return Task.Run(async () =>

+ 7 - 1
Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs

@@ -55,7 +55,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
             var typeName = GetType().Name;
             Logger.LogInformation("Opening " + typeName + " Live stream from {0}", url);
 
-            using var response = await _httpClientFactory.CreateClient(NamedClient.Default)
+            // Response stream is disposed manually.
+            var response = await _httpClientFactory.CreateClient(NamedClient.Default)
                 .GetAsync(url, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
                 .ConfigureAwait(false);
 
@@ -121,6 +122,11 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
             }
         }
 
+        public string GetFilePath()
+        {
+            return TempFilePath;
+        }
+
         private Task StartStreaming(HttpResponseMessage response, TaskCompletionSource<bool> openTaskCompletionSource, CancellationToken cancellationToken)
         {
             return Task.Run(async () =>

+ 2 - 5
Jellyfin.Api/Controllers/LiveTvController.cs

@@ -1220,11 +1220,8 @@ namespace Jellyfin.Api.Controllers
                 return NotFound();
             }
 
-            await using var memoryStream = new MemoryStream();
-            await new ProgressiveFileCopier(liveStreamInfo, null, _transcodingJobHelper, CancellationToken.None)
-                .WriteToAsync(memoryStream, CancellationToken.None)
-                .ConfigureAwait(false);
-            return File(memoryStream, MimeTypes.GetMimeType("file." + container));
+            var liveStream = new ProgressiveFileStream(liveStreamInfo.GetFilePath(), null, _transcodingJobHelper);
+            return new FileStreamResult(liveStream, MimeTypes.GetMimeType("file." + container));
         }
 
         private void AssertUserCanManageLiveTv()

+ 8 - 4
Jellyfin.Api/Helpers/ProgressiveFileStream.cs

@@ -82,20 +82,23 @@ namespace Jellyfin.Api.Helpers
             int totalBytesRead = 0;
             int remainingBytesToRead = count;
 
+            int newOffset = offset;
             while (remainingBytesToRead > 0)
             {
                 cancellationToken.ThrowIfCancellationRequested();
                 int bytesRead;
                 if (_allowAsyncFileRead)
                 {
-                    bytesRead = await _fileStream.ReadAsync(buffer, offset, remainingBytesToRead, cancellationToken).ConfigureAwait(false);
+                    bytesRead = await _fileStream.ReadAsync(buffer, newOffset, remainingBytesToRead, cancellationToken).ConfigureAwait(false);
                 }
                 else
                 {
-                    bytesRead = _fileStream.Read(buffer, offset, remainingBytesToRead);
+                    bytesRead = _fileStream.Read(buffer, newOffset, remainingBytesToRead);
                 }
 
                 remainingBytesToRead -= bytesRead;
+                newOffset += bytesRead;
+
                 if (bytesRead > 0)
                 {
                     _bytesWritten += bytesRead;
@@ -108,12 +111,13 @@ namespace Jellyfin.Api.Helpers
                 }
                 else
                 {
-                    if (_job == null || _job.HasExited)
+                    // If the job is null it's a live stream and will require user action to close
+                    if (_job?.HasExited ?? false)
                     {
                         break;
                     }
 
-                    await Task.Delay(100, cancellationToken).ConfigureAwait(false);
+                    await Task.Delay(50, cancellationToken).ConfigureAwait(false);
                 }
             }
 

+ 2 - 0
MediaBrowser.Controller/Library/IMediaSourceManager.cs

@@ -115,5 +115,7 @@ namespace MediaBrowser.Controller.Library
     public interface IDirectStreamProvider
     {
         Task CopyToAsync(Stream stream, CancellationToken cancellationToken);
+
+        string GetFilePath();
     }
 }

+ 1 - 1
MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs

@@ -3085,7 +3085,7 @@ namespace MediaBrowser.Controller.MediaEncoding
                 }
             }
 
-            var whichCodec = videoStream.Codec.ToLowerInvariant();
+            var whichCodec = videoStream.Codec?.ToLowerInvariant();
             switch (whichCodec)
             {
                 case "avc":