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

Fix LiveTV TS playback
This commit is contained in:
Claus Vium 2020-11-06 15:27:51 +01:00 committed by GitHub
commit 83d7e0a265
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 25 additions and 11 deletions

View File

@ -131,6 +131,11 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
await taskCompletionSource.Task.ConfigureAwait(false); await taskCompletionSource.Task.ConfigureAwait(false);
} }
public string GetFilePath()
{
return TempFilePath;
}
private Task StartStreaming(UdpClient 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 () =>

View File

@ -55,7 +55,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
var typeName = GetType().Name; var typeName = GetType().Name;
Logger.LogInformation("Opening " + typeName + " Live stream from {0}", url); 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) .GetAsync(url, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
.ConfigureAwait(false); .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) private Task StartStreaming(HttpResponseMessage response, TaskCompletionSource<bool> openTaskCompletionSource, CancellationToken cancellationToken)
{ {
return Task.Run(async () => return Task.Run(async () =>

View File

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

View File

@ -82,20 +82,23 @@ namespace Jellyfin.Api.Helpers
int totalBytesRead = 0; int totalBytesRead = 0;
int remainingBytesToRead = count; int remainingBytesToRead = count;
int newOffset = offset;
while (remainingBytesToRead > 0) while (remainingBytesToRead > 0)
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
int bytesRead; int bytesRead;
if (_allowAsyncFileRead) if (_allowAsyncFileRead)
{ {
bytesRead = await _fileStream.ReadAsync(buffer, offset, remainingBytesToRead, cancellationToken).ConfigureAwait(false); bytesRead = await _fileStream.ReadAsync(buffer, newOffset, remainingBytesToRead, cancellationToken).ConfigureAwait(false);
} }
else else
{ {
bytesRead = _fileStream.Read(buffer, offset, remainingBytesToRead); bytesRead = _fileStream.Read(buffer, newOffset, remainingBytesToRead);
} }
remainingBytesToRead -= bytesRead; remainingBytesToRead -= bytesRead;
newOffset += bytesRead;
if (bytesRead > 0) if (bytesRead > 0)
{ {
_bytesWritten += bytesRead; _bytesWritten += bytesRead;
@ -108,12 +111,13 @@ namespace Jellyfin.Api.Helpers
} }
else 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; break;
} }
await Task.Delay(100, cancellationToken).ConfigureAwait(false); await Task.Delay(50, cancellationToken).ConfigureAwait(false);
} }
} }

View File

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

View File

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