mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-03-13 21:56:20 +00:00
Merge pull request #14809 from lostb1t/fix/subtitleencoder
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled
fix: prevent premature disposal of HTTP subtitle streams
This commit is contained in:
@@ -172,23 +172,25 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
||||
|
||||
private async Task<Stream> GetSubtitleStream(SubtitleInfo fileInfo, CancellationToken cancellationToken)
|
||||
{
|
||||
if (fileInfo.IsExternal)
|
||||
if (fileInfo.Protocol == MediaProtocol.Http)
|
||||
{
|
||||
var stream = await GetStream(fileInfo.Path, fileInfo.Protocol, cancellationToken).ConfigureAwait(false);
|
||||
await using (stream.ConfigureAwait(false))
|
||||
var result = await DetectCharset(fileInfo.Path, fileInfo.Protocol, cancellationToken).ConfigureAwait(false);
|
||||
var detected = result.Detected;
|
||||
|
||||
if (detected is not null)
|
||||
{
|
||||
var result = await CharsetDetector.DetectFromStreamAsync(stream, cancellationToken).ConfigureAwait(false);
|
||||
var detected = result.Detected;
|
||||
stream.Position = 0;
|
||||
_logger.LogDebug("charset {CharSet} detected for {Path}", detected.EncodingName, fileInfo.Path);
|
||||
|
||||
if (detected is not null)
|
||||
using var stream = await _httpClientFactory.CreateClient(NamedClient.Default)
|
||||
.GetStreamAsync(new Uri(fileInfo.Path), cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
await using (stream.ConfigureAwait(false))
|
||||
{
|
||||
_logger.LogDebug("charset {CharSet} detected for {Path}", detected.EncodingName, fileInfo.Path);
|
||||
using var reader = new StreamReader(stream, detected.Encoding);
|
||||
var text = await reader.ReadToEndAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
using var reader = new StreamReader(stream, detected.Encoding);
|
||||
var text = await reader.ReadToEndAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes(text));
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes(text));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -218,7 +220,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
||||
};
|
||||
}
|
||||
|
||||
var currentFormat = (Path.GetExtension(subtitleStream.Path) ?? subtitleStream.Codec)
|
||||
var currentFormat = subtitleStream.Codec ?? Path.GetExtension(subtitleStream.Path)
|
||||
.TrimStart('.');
|
||||
|
||||
// Handle PGS subtitles as raw streams for the client to render
|
||||
@@ -941,42 +943,44 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var stream = await GetStream(path, mediaSource.Protocol, cancellationToken).ConfigureAwait(false);
|
||||
await using (stream.ConfigureAwait(false))
|
||||
var result = await DetectCharset(path, mediaSource.Protocol, cancellationToken).ConfigureAwait(false);
|
||||
var charset = result.Detected?.EncodingName ?? string.Empty;
|
||||
|
||||
// UTF16 is automatically converted to UTF8 by FFmpeg, do not specify a character encoding
|
||||
if ((path.EndsWith(".ass", StringComparison.Ordinal) || path.EndsWith(".ssa", StringComparison.Ordinal) || path.EndsWith(".srt", StringComparison.Ordinal))
|
||||
&& (string.Equals(charset, "utf-16le", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(charset, "utf-16be", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
var result = await CharsetDetector.DetectFromStreamAsync(stream, cancellationToken).ConfigureAwait(false);
|
||||
var charset = result.Detected?.EncodingName ?? string.Empty;
|
||||
|
||||
// UTF16 is automatically converted to UTF8 by FFmpeg, do not specify a character encoding
|
||||
if ((path.EndsWith(".ass", StringComparison.Ordinal) || path.EndsWith(".ssa", StringComparison.Ordinal) || path.EndsWith(".srt", StringComparison.Ordinal))
|
||||
&& (string.Equals(charset, "utf-16le", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(charset, "utf-16be", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
charset = string.Empty;
|
||||
}
|
||||
|
||||
_logger.LogDebug("charset {0} detected for {Path}", charset, path);
|
||||
|
||||
return charset;
|
||||
charset = string.Empty;
|
||||
}
|
||||
|
||||
_logger.LogDebug("charset {0} detected for {Path}", charset, path);
|
||||
|
||||
return charset;
|
||||
}
|
||||
|
||||
private async Task<Stream> GetStream(string path, MediaProtocol protocol, CancellationToken cancellationToken)
|
||||
private async Task<DetectionResult> DetectCharset(string path, MediaProtocol protocol, CancellationToken cancellationToken)
|
||||
{
|
||||
switch (protocol)
|
||||
{
|
||||
case MediaProtocol.Http:
|
||||
{
|
||||
using var response = await _httpClientFactory.CreateClient(NamedClient.Default)
|
||||
.GetAsync(new Uri(path), cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
{
|
||||
using var stream = await _httpClientFactory
|
||||
.CreateClient(NamedClient.Default)
|
||||
.GetStreamAsync(new Uri(path), cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return await CharsetDetector.DetectFromStreamAsync(stream, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
case MediaProtocol.File:
|
||||
return AsyncFile.OpenRead(path);
|
||||
{
|
||||
return await CharsetDetector.DetectFromFileAsync(path, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(protocol));
|
||||
throw new ArgumentOutOfRangeException(nameof(protocol), protocol, "Unsupported protocol");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user