feat: yt-dlp prefers H.264, falls back to built-in, no pipe hang (v1.0.0.13)
Some checks failed
Publish Release / release (push) Failing after 8s
Some checks failed
Publish Release / release (push) Failing after 8s
- Format string prefers avc1 video + m4a audio, then any codec. The RTX 2070 host can hardware-transcode H.264 but not AV1. - Pass Jellyfin's ffmpeg via --ffmpeg-location instead of relying on PATH. - If yt-dlp fails, retry with the built-in YoutubeExplode downloader. - Read stdout/stderr while yt-dlp runs (and add --no-progress); before, stdout was never read, so a full pipe buffer could block yt-dlp forever. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -3,8 +3,8 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<RootNamespace>Jellyfin.Plugin.CinemaTrailers4Jellyfins</RootNamespace>
|
||||
<AssemblyVersion>1.0.0.12</AssemblyVersion>
|
||||
<FileVersion>1.0.0.12</FileVersion>
|
||||
<AssemblyVersion>1.0.0.13</AssemblyVersion>
|
||||
<FileVersion>1.0.0.13</FileVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateDocumentationFile>false</GenerateDocumentationFile>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
|
||||
@@ -63,8 +63,10 @@ namespace Jellyfin.Plugin.CinemaTrailers4Jellyfins.Services
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(ytDlpPath) && File.Exists(ytDlpPath))
|
||||
{
|
||||
return await DownloadWithYtDlpAsync(youtubeKey, outputPath, preferredHeight, ytDlpPath, ct)
|
||||
.ConfigureAwait(false);
|
||||
if (await DownloadWithYtDlpAsync(youtubeKey, outputPath, preferredHeight, ytDlpPath, ct).ConfigureAwait(false))
|
||||
return true;
|
||||
|
||||
_logger.LogWarning("|CinemaTrailers4Jellyfins| yt-dlp failed for {Key}; falling back to the built-in downloader.", youtubeKey);
|
||||
}
|
||||
|
||||
return await DownloadWithYoutubeExplodeAsync(youtubeKey, outputPath, preferredHeight, ct)
|
||||
@@ -224,13 +226,16 @@ namespace Jellyfin.Plugin.CinemaTrailers4Jellyfins.Services
|
||||
{
|
||||
try
|
||||
{
|
||||
// Format selects the best video at or below preferredHeight merged with the best audio.
|
||||
// --merge-output-format mp4 ensures the output is always an mp4.
|
||||
// Format selects the best video at or below preferredHeight merged with the best audio,
|
||||
// preferring H.264 + AAC (plays or hardware-transcodes on every client; VP9/AV1 often
|
||||
// need a CPU transcode). --merge-output-format mp4 ensures the output is always an mp4.
|
||||
var args = string.Join(" ",
|
||||
$"-f \"bestvideo[height<={preferredHeight}]+bestaudio/best[height<={preferredHeight}]\"",
|
||||
$"-f \"bestvideo[height<={preferredHeight}][vcodec^=avc1]+bestaudio[ext=m4a]/bestvideo[height<={preferredHeight}]+bestaudio/best[height<={preferredHeight}]\"",
|
||||
"--merge-output-format mp4",
|
||||
"--no-playlist",
|
||||
"--no-warnings",
|
||||
"--no-progress",
|
||||
$"--ffmpeg-location \"{FfmpegLocator.Path}\"",
|
||||
$"-o \"{outputPath}\"",
|
||||
$"\"https://www.youtube.com/watch?v={key}\"");
|
||||
|
||||
@@ -252,11 +257,15 @@ namespace Jellyfin.Plugin.CinemaTrailers4Jellyfins.Services
|
||||
};
|
||||
|
||||
process.Start();
|
||||
// Drain both pipes while yt-dlp runs so a full buffer can never block it.
|
||||
var stdoutTask = process.StandardOutput.ReadToEndAsync(ct);
|
||||
var stderrTask = process.StandardError.ReadToEndAsync(ct);
|
||||
await process.WaitForExitAsync(ct).ConfigureAwait(false);
|
||||
await stdoutTask.ConfigureAwait(false);
|
||||
var stderr = await stderrTask.ConfigureAwait(false);
|
||||
|
||||
if (process.ExitCode != 0)
|
||||
{
|
||||
var stderr = await process.StandardError.ReadToEndAsync(ct).ConfigureAwait(false);
|
||||
_logger.LogError("|CinemaTrailers4Jellyfins| yt-dlp exited with code {Code} for {Key}: {Error}",
|
||||
process.ExitCode, key, stderr);
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user