diff --git a/handlers/render_video.py b/handlers/render_video.py index 25f176c..9b2f2a6 100644 --- a/handlers/render_video.py +++ b/handlers/render_video.py @@ -725,8 +725,11 @@ class RenderSegmentTsHandler(BaseHandler): break combined_pts_factor = (1.0 / speed) * ospeed_factor + # 统一归零视频起始时间戳,避免源素材非 0 起始 PTS 造成封装后首帧冻结 if combined_pts_factor != 1.0: - filters.append(f"setpts={combined_pts_factor}*PTS") + filters.append(f"setpts={combined_pts_factor}*(PTS-STARTPTS)") + else: + filters.append("setpts=PTS-STARTPTS") # 2. LUT 调色 if lut_file: diff --git a/tests/unit/test_render_video_effects.py b/tests/unit/test_render_video_effects.py index 0a2aa1d..a8498f5 100644 --- a/tests/unit/test_render_video_effects.py +++ b/tests/unit/test_render_video_effects.py @@ -137,7 +137,22 @@ def test_ospeed_does_not_trigger_filter_complex(tmp_path): # 验证 setpts 滤镜 vf_idx = command.index('-vf') vf_value = command[vf_idx + 1] - assert 'setpts=2.0*PTS' in vf_value + assert 'setpts=2.0*(PTS-STARTPTS)' in vf_value + + +def test_default_speed_always_normalizes_pts(tmp_path): + handler = _create_handler(tmp_path) + render_spec = RenderSpec() + output_spec = OutputSpec(width=1080, height=1920, fps=30) + + filters = handler._build_video_filters( + render_spec=render_spec, + output_spec=output_spec, + duration_ms=6000, + source_duration_sec=10.0, + ) + + assert 'setpts=PTS-STARTPTS' in filters def test_ospeed_combined_with_speed(tmp_path): @@ -153,7 +168,7 @@ def test_ospeed_combined_with_speed(tmp_path): source_duration_sec=10.0, ) - assert 'setpts=1.5*PTS' in filters + assert 'setpts=1.5*(PTS-STARTPTS)' in filters def test_ospeed_with_complex_effects(tmp_path): @@ -171,7 +186,7 @@ def test_ospeed_with_complex_effects(tmp_path): # zoom 触发 filter_complex assert '[v_base]' in filters # setpts 在 base_chain 中 - assert 'setpts=2.0*PTS' in filters + assert 'setpts=2.0*(PTS-STARTPTS)' in filters # zoom 正常处理 assert "overlay=0:0:enable='between(t,1.0,3.0)'" in filters @@ -188,8 +203,8 @@ def test_only_first_ospeed_is_used(tmp_path): source_duration_sec=10.0, ) - assert 'setpts=2.0*PTS' in filters - assert 'setpts=5.0*PTS' not in filters + assert 'setpts=2.0*(PTS-STARTPTS)' in filters + assert 'setpts=5.0*(PTS-STARTPTS)' not in filters def test_ospeed_affects_tpad_calculation(tmp_path): diff --git a/tests/unit/test_video_encode_args.py b/tests/unit/test_video_encode_args.py new file mode 100644 index 0000000..527d355 --- /dev/null +++ b/tests/unit/test_video_encode_args.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +from constant import HW_ACCEL_CUDA, HW_ACCEL_NONE, HW_ACCEL_QSV +from handlers.base import get_video_encode_args + + +def _assert_bframe_disabled(args): + assert '-bf' in args + bf_index = args.index('-bf') + assert args[bf_index + 1] == '0' + + +def test_get_video_encode_args_disable_b_frames_for_software(): + args = get_video_encode_args(HW_ACCEL_NONE) + _assert_bframe_disabled(args) + + +def test_get_video_encode_args_disable_b_frames_for_qsv(): + args = get_video_encode_args(HW_ACCEL_QSV) + _assert_bframe_disabled(args) + + +def test_get_video_encode_args_disable_b_frames_for_cuda(): + args = get_video_encode_args(HW_ACCEL_CUDA) + _assert_bframe_disabled(args)