fix: address AI code review - probe defaults to no audio, safe af filter
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 35s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 40s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 29s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m32s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m46s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m51s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m22s
AI Code Review / AI Code Review (pull_request) Failing after 2m36s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 2m44s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m33s
CI/CD Pipeline / Validate - Code Quality (pull_request) Has been cancelled
CI/CD Pipeline / Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Build Production API Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been cancelled
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / CI Gate (pull_request) Has been cancelled

- render_audio.py: simple mode builds af_parts list then joins into single -af (defensive against future multi-clip)
- unified_render_service.py: probe_has_audio exception now defaults to False with warning log (was unsafe True)
- test: add test_pass_through_probe_exception_defaults_to_no_audio
This commit is contained in:
xiaoxia
2026-08-24 00:10:07 +08:00
parent e3420610a3
commit 2f76509a5b
3 changed files with 29 additions and 3 deletions
+5 -1
View File
@@ -294,9 +294,13 @@ def concat_main_audio(
"-ac",
"2",
]
# 单 clip 简单模式:将所有音频滤镜合并为单个 -af 参数(避免多个 -af 冲突)
af_parts: list[str] = []
vol = _clip_volume(clip)
if abs(vol - 1.0) >= 1e-6:
command.extend(["-af", f"volume={vol:.4f}"])
af_parts.append(f"volume={vol:.4f}")
if af_parts:
command.extend(["-af", ",".join(af_parts)])
if trim_start > 0:
command.extend(["-ss", f"{trim_start:.3f}"])
if final_duration > 0:
@@ -1282,8 +1282,9 @@ class UnifiedRenderService:
if role != "background" and clip_volume > 0:
try:
has_audio = probe_has_audio(clip.local_path)
except Exception:
has_audio = True
except Exception as e:
logger.warning("[unified-render] 探测音频流失败,假设无音频: %s: %s", clip.local_path, e)
has_audio = False
else:
has_audio = False
if has_audio:
@@ -191,3 +191,24 @@ class TestPassThroughAudioProbe:
def test_clip_volume_static_helper(self):
assert UnifiedRenderService._clip_volume(_clip("c1")) == 1.0
assert UnifiedRenderService._clip_volume(_clip("c2", config={"volume": 0.7})) == pytest.approx(0.7)
def test_pass_through_probe_exception_defaults_to_no_audio(self):
"""probe_has_audio 抛异常时必须默认无音频,不能盲目映射不存在的音轨。"""
clips = [_clip("c1")]
svc = _service(clips)
with (
patch("pathlib.Path.exists", return_value=True),
patch("video_processing.unified_render_service.probe_duration", return_value=5.0),
patch(
"video_processing.unified_render_service.probe_has_audio",
side_effect=RuntimeError("probe failed"),
) as mock_probe,
patch("video_processing.unified_render_service.run_ffmpeg") as mock_run,
):
layers = svc._group_clips_into_layers(clips)
has_audio = svc._render_pass_through(layers, Path("/tmp/out.mp4"), video_duration=5.0)
assert has_audio is False
mock_probe.assert_called()
cmd_str = " ".join(mock_run.call_args[0][0])
assert "aac" not in cmd_str