fix: 修复 _has_audio() 始终返回 True 的 P0 问题
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 183h54m54s
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Failing after 183h54m58s
Deploy / Deploy Staging (push) Failing after 183h55m26s
CI/CD Pipeline / Frontend Lint (push) Failing after 183h55m54s
CI/CD Pipeline / Validate Code Quality And Tests (push) Failing after 183h55m58s
Deploy / Production Browser E2E (push) Failing after 1842h30m35s
Deploy / Build Production Runtime Images (push) Failing after 1842h31m8s
Deploy / Deploy Production (push) Failing after 1843h2m0s

- 仅当 clip_type 不是 title/subtitle 时才设置 audio_label
- title/subtitle 是纯文字/图片卡片,没有音频流
- 添加 7 个单元测试验证修复逻辑
- 所有 36 个测试通过
This commit is contained in:
灵应
2026-07-01 20:26:33 +08:00
committed by xiaoxia
parent e3706bd652
commit 17fc46c662
2 changed files with 67 additions and 6 deletions
@@ -428,12 +428,11 @@ class VideoComposeService:
video_label = f"v{input_index}"
# 5. atrim: 音频时长(假设输入可能有音频)
audio_filters = [
f"atrim=0:{duration}",
"asetpts=PTS-STARTPTS",
]
audio_label = f"a{input_index}"
# 5. 音频标签:仅当片段类型可能有音频时才设置
# title/subtitle 是纯文字/图片卡片,没有音频流
clip_type = clip.clip_type.lower() if clip.clip_type else ""
has_audio_stream = clip_type not in ("title", "subtitle")
audio_label = f"a{input_index}" if has_audio_stream else None
return ClipFilterChain(
clip_id=clip.id,
+62
View File
@@ -560,6 +560,68 @@ class TestBuildXfadeFilter(TestCase):
self.assertAlmostEqual(duration, 14.0, places=2)
class TestHasAudioTitleSubtitleFix(TestCase):
"""P0 修复验证:title/subtitle 片段不应有音频流。"""
def _make_clip(self, clip_id, clip_type, **kwargs):
"""创建测试用 stub clip。"""
return _StubClip(clip_id=clip_id, clip_type=clip_type, **kwargs)
def test_title_clip_has_no_audio_label(self):
"""title 类型片段的 audio_label 应为 None。"""
clip = self._make_clip("c1", "title")
chain = VideoComposeService._build_clip_filter(clip, 0, 1280, 720, 25)
self.assertIsNone(chain.audio_label, "title 片段不应有音频标签")
def test_subtitle_clip_has_no_audio_label(self):
"""subtitle 类型片段的 audio_label 应为 None。"""
clip = self._make_clip("c1", "subtitle")
chain = VideoComposeService._build_clip_filter(clip, 0, 1280, 720, 25)
self.assertIsNone(chain.audio_label, "subtitle 片段不应有音频标签")
def test_main_clip_has_audio_label(self):
"""main 类型片段应有音频标签。"""
clip = self._make_clip("c1", "main")
chain = VideoComposeService._build_clip_filter(clip, 0, 1280, 720, 25)
self.assertEqual(chain.audio_label, "a0")
def test_intro_clip_has_audio_label(self):
"""intro 类型片段应有音频标签。"""
clip = self._make_clip("c1", "intro")
chain = VideoComposeService._build_clip_filter(clip, 0, 1280, 720, 25)
self.assertEqual(chain.audio_label, "a0")
def test_has_audio_false_when_only_title_subtitle(self):
"""当所有片段都是 title/subtitle 时,_has_audio 应返回 False。"""
chains = [
VideoComposeService._build_clip_filter(
self._make_clip("c1", "title"), 0, 1280, 720, 25
),
VideoComposeService._build_clip_filter(
self._make_clip("c2", "subtitle"), 1, 1280, 720, 25
),
]
self.assertFalse(VideoComposeService._has_audio(chains))
def test_has_audio_true_when_mixed_clips(self):
"""混合片段(含 main)时,_has_audio 应返回 True。"""
chains = [
VideoComposeService._build_clip_filter(
self._make_clip("c1", "title"), 0, 1280, 720, 25
),
VideoComposeService._build_clip_filter(
self._make_clip("c2", "main"), 1, 1280, 720, 25
),
]
self.assertTrue(VideoComposeService._has_audio(chains))
def test_empty_clip_type_has_audio(self):
"""clip_type 为空字符串时,应有音频标签(保守策略)。"""
clip = self._make_clip("c1", "")
chain = VideoComposeService._build_clip_filter(clip, 0, 1280, 720, 25)
self.assertEqual(chain.audio_label, "a0")
if __name__ == "__main__":
import unittest
unittest.main()