chore: rebase到develop + 格式化代码
CI/CD Pipeline / Integration Tests (pull_request) Failing after 1m26s
CI/CD Pipeline / Production Browser E2E (pull_request) Failing after 1541h17m16s
CI/CD Pipeline / Staging API Integration Tests (pull_request) Failing after 1541h17m18s
CI/CD Pipeline / Staging E2E Tests (pull_request) Failing after 1541h17m18s
CI/CD Pipeline / Build Production Runtime Images (pull_request) Failing after 1541h17m20s
CI/CD Pipeline / Build & Push Staging (Watchtower auto-deploy) (pull_request) Failing after 1541h17m20s
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Has been skipped
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Failing after 1541h48m55s
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped

This commit is contained in:
CI Bot
2026-07-14 09:35:53 +08:00
committed by xiaoxia-bot
parent a1285be576
commit c6bc8170d1
6 changed files with 25 additions and 42 deletions
+1 -1
View File
@@ -46,8 +46,8 @@ from packages.application.voice_library.use_cases import (
CreateVoiceLibraryUseCase,
QuotaExceededError,
)
from packages.ports.user_repository import UserRepository
from packages.domain.voice_presets import list_voices
from packages.ports.user_repository import UserRepository
logger = logging.getLogger(__name__)
+2 -6
View File
@@ -244,9 +244,7 @@ class TtsEngine:
# 音量调整
# 用 adelay 延迟到字幕开始时间
delay_ms = int(max(0, int(seg.start_time * 1000)))
filter_parts.append(
f"[{i}:a]adelay={delay_ms}:all=1,volume=0.8[{seg_label}]"
)
filter_parts.append(f"[{i}:a]adelay={delay_ms}:all=1,volume=0.8[{seg_label}]")
delay_labels.append(f"[{seg_label}]")
if not delay_labels:
@@ -262,9 +260,7 @@ class TtsEngine:
filter_parts.append(f"{delay_labels[0]}[{tts_label}]")
else:
# 多个片段 amix 叠加
filter_parts.append(
f"{mix_inputs}amix=inputs={n_inputs}:duration=longest[{tts_label}]"
)
filter_parts.append(f"{mix_inputs}amix=inputs={n_inputs}:duration=longest[{tts_label}]")
return ";".join(filter_parts), audio_files
@@ -44,6 +44,7 @@ from video_processing.render_audio import RenderContext, merge_audio_video, mix_
from video_processing.render_subtitles import generate_ass_subtitles
from video_processing.subtitle_generator import generate_ass_from_timeline
from video_processing.tts_engine import TtsEngine
from packages.domain.tts_config import TtsConfig
logger = logging.getLogger(__name__)
@@ -534,9 +535,7 @@ class UnifiedRenderService:
tts_engine = TtsEngine(tts_service, self.work_dir / "tts")
# 整段配音模式
result = tts_engine.generate_full_voiceover(
tts_config, total_duration=video_duration
)
result = tts_engine.generate_full_voiceover(tts_config, total_duration=video_duration)
if not result.success or not result.segments:
logger.warning("TTS 配音生成失败,跳过: %s", result.error_message)
+1 -3
View File
@@ -168,9 +168,7 @@ class MockTtsService(TtsService):
filter_parts = []
# 主音 + 轻微频率调制
filter_parts.append(
f"sine=frequency={base_freq}:duration={duration}:sample_rate={sample_rate}"
)
filter_parts.append(f"sine=frequency={base_freq}:duration={duration}:sample_rate={sample_rate}")
# 颤音效果
filter_parts.append(f"tremolo=f={tremolo_freq}:d={tremolo_depth}")
+1 -6
View File
@@ -212,12 +212,7 @@ def list_voices(
if keyword:
kw = keyword.lower()
result = [
v for v in result
if kw in v.name.lower()
or kw in v.description.lower()
or kw in v.voice_id.lower()
]
result = [v for v in result if kw in v.name.lower() or kw in v.description.lower() or kw in v.voice_id.lower()]
return result
+18 -23
View File
@@ -4,6 +4,9 @@ from pathlib import Path
import pytest
from apps.worker.video_processing.tts_engine import TtsEngine, VoiceoverResult, VoiceoverSegment
from packages.adapters.tts.mock_tts_service import MockTtsService
from packages.domain.tts_config import TtsConfig
from packages.domain.voice_presets import (
VoiceGender,
VoicePreset,
@@ -12,11 +15,7 @@ from packages.domain.voice_presets import (
get_voice,
list_voices,
)
from packages.domain.tts_config import TtsConfig
from packages.ports.tts_service import TtsError, TtsService
from packages.adapters.tts.mock_tts_service import MockTtsService
from apps.worker.video_processing.tts_engine import TtsEngine, VoiceoverResult, VoiceoverSegment
# ─── TtsConfig 配置解析 ────────────────────────────────────
@@ -75,16 +74,18 @@ class TestTtsConfig:
assert config.volume == 1.0
def test_parse_invalid_types(self):
config = TtsConfig.parse({
"enabled": True,
"speed": "fast",
"pitch": "high",
"volume": "loud",
"voice_id": 123,
"text": 456,
"align_mode": "invalid",
"overlap_mode": "invalid",
})
config = TtsConfig.parse(
{
"enabled": True,
"speed": "fast",
"pitch": "high",
"volume": "loud",
"voice_id": 123,
"text": 456,
"align_mode": "invalid",
"overlap_mode": "invalid",
}
)
assert config.speed == 1.0
assert config.pitch == 0.0
assert config.volume == 0.8
@@ -178,9 +179,7 @@ class TestMockTtsService:
voices = ["female_warm", "male_stable", "child_cute"]
for vid in voices:
output = tmp_path / f"{vid}.wav"
result = self.service.synthesize(
"测试", voice_id=vid, output_path=output
)
result = self.service.synthesize("测试", voice_id=vid, output_path=output)
assert result.exists()
def test_synthesize_speed_faster(self, tmp_path):
@@ -199,9 +198,7 @@ class TestMockTtsService:
def test_synthesize_pitch_changes(self, tmp_path):
output = tmp_path / "high_pitch.wav"
result = self.service.synthesize(
"测试", voice_id="female_warm", pitch=6, output_path=output
)
result = self.service.synthesize("测试", voice_id="female_warm", pitch=6, output_path=output)
assert result.exists()
def test_synthesize_empty_text_raises(self):
@@ -229,9 +226,7 @@ class TestMockTtsService:
def test_synthesize_unknown_voice_fallback(self, tmp_path):
output = tmp_path / "fallback.wav"
# 未知音色应该 fallback 到默认音色,不报错
result = self.service.synthesize(
"测试", voice_id="unknown_voice", output_path=output
)
result = self.service.synthesize("测试", voice_id="unknown_voice", output_path=output)
assert result.exists()