From eeb21cada3be4c57b69f0304c1a069c726afa604 Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Wed, 4 Feb 2026 17:46:01 +0800 Subject: [PATCH] =?UTF-8?q?perf(render=5Fvideo):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E8=A7=86=E9=A2=91=E7=BC=96=E7=A0=81=E7=9A=84=E5=85=B3=E9=94=AE?= =?UTF-8?q?=E5=B8=A7=E9=97=B4=E9=9A=94=E7=AD=96=E7=95=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 根据视频总帧数动态计算 GOP 大小,避免关键帧过多 - 短视频使用全部帧数作为 GOP,确保只在开头有关键帧 - 正常视频保持 2 秒一个关键帧的策略 - 添加强制第一帧为关键帧的设置 - 优化关键帧最小间隔参数,提升编码效率 --- handlers/render_video.py | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/handlers/render_video.py b/handlers/render_video.py index 2369522..638b932 100644 --- a/handlers/render_video.py +++ b/handlers/render_video.py @@ -275,12 +275,24 @@ class RenderSegmentVideoHandler(BaseHandler): cmd.extend(['-vf', ','.join(filters)]) + # 计算总帧数,动态调整 GOP + total_frames = int(actual_duration_sec * fps) + if total_frames <= 1: + gop_size = 1 + elif total_frames < fps: + gop_size = total_frames + else: + gop_size = fps * 2 # 正常情况,2 秒一个关键帧 + # 编码参数 cmd.extend([ '-c:v', 'libx264', '-preset', 'fast', '-crf', '18', '-r', str(fps), + '-g', str(gop_size), + '-keyint_min', str(min(gop_size, fps // 2 or 1)), + '-force_key_frames', 'expr:eq(n,0)', '-an', # 无音频 output_file ]) @@ -357,16 +369,28 @@ class RenderSegmentVideoHandler(BaseHandler): fps = output_spec.fps cmd.extend(['-r', str(fps)]) - # GOP 大小(关键帧间隔) - gop_size = fps * 2 # 2秒一个关键帧 - cmd.extend(['-g', str(gop_size)]) - cmd.extend(['-keyint_min', str(gop_size)]) - # 时长(包含 overlap 区域) total_duration_ms = duration_ms + overlap_head_ms + overlap_tail_ms duration_sec = total_duration_ms / 1000.0 cmd.extend(['-t', str(duration_sec)]) + # 动态调整 GOP 大小:对于短视频,GOP 不能大于总帧数 + total_frames = int(duration_sec * fps) + if total_frames <= 1: + gop_size = 1 + elif total_frames < fps: + # 短于 1 秒的视频,使用全部帧数作为 GOP(整个视频只有开头一个关键帧) + gop_size = total_frames + else: + # 正常情况,2 秒一个关键帧 + gop_size = fps * 2 + + cmd.extend(['-g', str(gop_size)]) + cmd.extend(['-keyint_min', str(min(gop_size, fps // 2 or 1))]) + + # 强制第一帧为关键帧 + cmd.extend(['-force_key_frames', 'expr:eq(n,0)']) + # 无音频(视频片段不包含音频) cmd.append('-an')