ba9837986e
- unified_render_service filter_complex Step1 trim 时长改为 effective-freeze(与直通路径同口径,tpad 补冻结) - test_duration_compensation / render_audio_utils / render_audio_pure / 两处 render_layer_utils:min(duration,actual) 断言改为目标段长为准 - estimate_total_duration 测试:cut 零重叠、非 cut 逐处扣转场(FakeClip 加 transition_effect/duration) - test_generation_tasks/preview:voice_ids kwarg/字段移除,配音改 voice_library_id
99 lines
3.4 KiB
Python
99 lines
3.4 KiB
Python
"""Tests for duration compensation when source video is shorter than configured duration."""
|
||
|
||
from pathlib import Path
|
||
|
||
import pytest
|
||
|
||
from apps.worker.video_processing.unified_render_service import ResolvedClip, UnifiedRenderService
|
||
|
||
|
||
class TestClipEffectiveDurationWithSpeedCompensation:
|
||
"""Test _clip_effective_duration handles speed < 1 correctly."""
|
||
|
||
def test_normal_speed_returns_target_duration(self):
|
||
"""#1749:speed=1.0 时 effective_duration 始终为目标段长 duration。
|
||
|
||
素材短于段长不再慢放补偿,差值由末帧冻结 tpad / 音频 apad 铺满。
|
||
"""
|
||
clip = ResolvedClip(
|
||
clip_id="c1",
|
||
asset_id="a1",
|
||
local_path=Path("/tmp/fake.mp4"),
|
||
clip_type="main",
|
||
order=0,
|
||
start_time=0.0,
|
||
duration=4.0,
|
||
actual_duration=3.0, # shorter than configured
|
||
playback_speed=1.0,
|
||
)
|
||
assert UnifiedRenderService._clip_effective_duration(clip) == 4.0
|
||
|
||
def test_explicit_speed_does_not_change_effective_duration(self):
|
||
"""#1749:effective_duration 只认目标段长,与 playback_speed 无关(慢放补偿已删除)。"""
|
||
clip = ResolvedClip(
|
||
clip_id="c1",
|
||
asset_id="a1",
|
||
local_path=Path("/tmp/fake.mp4"),
|
||
clip_type="main",
|
||
order=0,
|
||
start_time=0.0,
|
||
duration=4.0,
|
||
actual_duration=3.0, # shorter than configured
|
||
playback_speed=0.75,
|
||
)
|
||
assert UnifiedRenderService._clip_effective_duration(clip) == 4.0
|
||
|
||
def test_zero_actual_duration_returns_configured(self):
|
||
"""When actual_duration=0, effective_duration = configured duration."""
|
||
clip = ResolvedClip(
|
||
clip_id="c1",
|
||
asset_id="a1",
|
||
local_path=Path("/tmp/fake.mp4"),
|
||
clip_type="main",
|
||
order=0,
|
||
start_time=0.0,
|
||
duration=4.0,
|
||
actual_duration=0.0,
|
||
playback_speed=1.0,
|
||
)
|
||
assert UnifiedRenderService._clip_effective_duration(clip) == 4.0
|
||
|
||
def test_compensated_speed_with_actual_zero(self):
|
||
"""When speed < 1 and actual=0, still returns configured duration."""
|
||
clip = ResolvedClip(
|
||
clip_id="c1",
|
||
asset_id="a1",
|
||
local_path=Path("/tmp/fake.mp4"),
|
||
clip_type="main",
|
||
order=0,
|
||
start_time=0.0,
|
||
duration=4.0,
|
||
actual_duration=0.0,
|
||
playback_speed=0.5,
|
||
)
|
||
assert UnifiedRenderService._clip_effective_duration(clip) == 4.0
|
||
|
||
|
||
class TestClipAdjustedDurationWithSpeedCompensation:
|
||
"""Test _clip_adjusted_duration accounts for compensated speed."""
|
||
|
||
def test_adjusted_duration_with_explicit_speed(self):
|
||
"""#1749:adjusted duration = 目标段长 / speed(用户显式调速仍生效;短素材不再自动慢放)。
|
||
|
||
4.0 / 0.75 ≈ 5.333。
|
||
"""
|
||
clip = ResolvedClip(
|
||
clip_id="c1",
|
||
asset_id="a1",
|
||
local_path=Path("/tmp/fake.mp4"),
|
||
clip_type="main",
|
||
order=0,
|
||
start_time=0.0,
|
||
duration=4.0,
|
||
actual_duration=3.0,
|
||
playback_speed=0.75,
|
||
)
|
||
adjusted = UnifiedRenderService._clip_adjusted_duration(clip)
|
||
# 4.0 / 0.75 = 5.333...
|
||
assert abs(adjusted - (4.0 / 0.75)) < 0.01
|