From e2b38112771e313868cd257968dc3cde33d88e6b Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Mon, 10 Aug 2026 11:37:22 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20FFmpeg=20mjpeg=20=E7=BC=A9=E7=95=A5?= =?UTF-8?q?=E5=9B=BE/=E5=B0=81=E9=9D=A2=E7=94=9F=E6=88=90=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=20format=3Dyuvj420p?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复 FFmpeg 新版中 mjpeg 编码器拒绝非全范围 YUV 输入的问题: - thumbnail_generator.py: scale filter 添加 format=yuvj420p - processor.py: 添加 pix_fmt=yuvj420p - cover_generator.py: 两处 vf filter 添加 format=yuvj420p - cover_service.py: vf filter + simple fallback 添加 pix_fmt - asset_analyzer.py: 添加 -pix_fmt yuvj420p 修复错误: Non full-range YUV is non-standard, set strict_std_compliance to at most unofficial to use it. --- apps/api/app/services/cover_service.py | 4 +++- apps/worker/video_processing/cover_generator.py | 4 ++-- apps/worker/video_processing/processor.py | 2 +- apps/worker/video_processing/thumbnail_generator.py | 2 +- apps/worker/worker_app/tasks/asset_analyzer.py | 2 ++ 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/apps/api/app/services/cover_service.py b/apps/api/app/services/cover_service.py index b9453bee5..a99ca8961 100644 --- a/apps/api/app/services/cover_service.py +++ b/apps/api/app/services/cover_service.py @@ -215,7 +215,7 @@ class CoverService: import subprocess # scale + crop 实现 cover 裁剪 - vf = f"scale={width}:{height}:force_original_aspect_ratio=increase," f"crop={width}:{height}" + vf = f"scale={width}:{height}:force_original_aspect_ratio=increase," f"crop={width}:{height},format=yuvj420p" command = [ "ffmpeg", @@ -258,6 +258,8 @@ class CoverService: "1", "-q:v", str(quality), + "-pix_fmt", + "yuvj420p", "-f", "mjpeg", str(output_path), diff --git a/apps/worker/video_processing/cover_generator.py b/apps/worker/video_processing/cover_generator.py index 8e656e6d2..5d945c529 100755 --- a/apps/worker/video_processing/cover_generator.py +++ b/apps/worker/video_processing/cover_generator.py @@ -93,7 +93,7 @@ class CoverGenerator: time_sec = 0 # scale + crop 实现 cover 裁剪(铺满输出尺寸) - vf = f"scale={width}:{height}:force_original_aspect_ratio=increase," f"crop={width}:{height}" + vf = f"scale={width}:{height}:force_original_aspect_ratio=increase," f"crop={width}:{height},format=yuvj420p" command = [ FFMPEG_BIN, @@ -281,7 +281,7 @@ class CoverGenerator: output_path.parent.mkdir(parents=True, exist_ok=True) # scale + crop 实现 cover 裁剪 - vf = f"scale={width}:{height}:force_original_aspect_ratio=increase," f"crop={width}:{height}" + vf = f"scale={width}:{height}:force_original_aspect_ratio=increase," f"crop={width}:{height},format=yuvj420p" command = [ FFMPEG_BIN, diff --git a/apps/worker/video_processing/processor.py b/apps/worker/video_processing/processor.py index 5b2e3e7ca..af44a0d6e 100644 --- a/apps/worker/video_processing/processor.py +++ b/apps/worker/video_processing/processor.py @@ -159,7 +159,7 @@ class VideoProcessor: try: ( ffmpeg.input(video_path, ss=timestamp) - .output(output_path, vframes=1, format="image2", vcodec="mjpeg") + .output(output_path, vframes=1, format="image2", vcodec="mjpeg", pix_fmt="yuvj420p") .overwrite_output() .run(capture_stdout=True, capture_stderr=True) ) diff --git a/apps/worker/video_processing/thumbnail_generator.py b/apps/worker/video_processing/thumbnail_generator.py index 5429587cd..eecdc2244 100755 --- a/apps/worker/video_processing/thumbnail_generator.py +++ b/apps/worker/video_processing/thumbnail_generator.py @@ -60,7 +60,7 @@ def extract_first_frame( # -ss 放在 -i 前面(input seeking,更快但精度稍低,缩略图够用) # -vframes 1 只取一帧 # -q:v 2 jpeg 高质量 - scale_filter = f"scale={width}:{height}:force_original_aspect_ratio=decrease" + scale_filter = f"scale={width}:{height}:force_original_aspect_ratio=decrease,format=yuvj420p" cmd = [ FFMPEG_BIN, "-y", diff --git a/apps/worker/worker_app/tasks/asset_analyzer.py b/apps/worker/worker_app/tasks/asset_analyzer.py index 3899deb79..949d59819 100755 --- a/apps/worker/worker_app/tasks/asset_analyzer.py +++ b/apps/worker/worker_app/tasks/asset_analyzer.py @@ -157,6 +157,8 @@ class AssetAnalyzer: "1", "-q:v", "2", # 高质量 + "-pix_fmt", + "yuvj420p", # mjpeg 需要全范围 YUV "-f", "image2", output_path, -- 2.54.0