style: auto-format with black + isort + ruff + prettier [skip ci-format-check]
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2s
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 2s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 45s
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 1m3s
Preview Deploy / Deploy Preview Environment (pull_request) Failing after 1m5s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Successful in 1m24s
CI/CD Pipeline / PR Build Web Image (pull_request) Failing after 1m48s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 1m51s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 2m57s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m56s
CI/CD Pipeline / Validate - Style (pull_request) Successful in 3m48s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 3m53s
AI Code Review / AI Code Review (pull_request) Successful in 6m23s
CI/CD Pipeline / Unit Tests (pull_request) Failing after 7m1s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 9m34s
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Failing after 3s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 6m48s
CI/CD Pipeline / Build Production Web Image (pull_request) Failing after 83h33m57s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Failing after 83h42m44s
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Failing after 83h42m50s
CI/CD Pipeline / Build Staging Worker Image (pull_request) Failing after 83h43m12s
CI/CD Pipeline / Build Staging API Image (pull_request) Failing after 83h43m13s
CI/CD Pipeline / Build Production API Image (pull_request) Failing after 83h33m34s
CI/CD Pipeline / Build Staging Web Image (pull_request) Failing after 83h43m12s
CI/CD Pipeline / Deploy Production (pull_request) Failing after 83h33m30s
CI/CD Pipeline / Build Production Worker Image (pull_request) Failing after 83h33m33s
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Failing after 83h42m25s
CI/CD Pipeline / Canary Release to Production (pull_request) Failing after 83h33m30s
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Failing after 83h42m25s
CI/CD Pipeline / ACR Image Cleanup (pull_request) Failing after 83h42m18s
CI/CD Pipeline / Staging API Integration Tests (pull_request) Failing after 83h42m18s
CI/CD Pipeline / Staging E2E Tests (pull_request) Failing after 83h42m19s
CI/CD Pipeline / Check push changed paths (pull_request) Failing after 83h43m14s

This commit is contained in:
CI Bot
2026-09-12 19:40:10 +00:00
parent 29b0a7d90d
commit d12632e32a
4 changed files with 28 additions and 11 deletions
+4 -2
View File
@@ -189,7 +189,9 @@ class LipsyncService:
audio_duration = probe_audio_duration(audio_data)
if audio_duration <= 0 and supplied_duration and supplied_duration > 0:
audio_duration = supplied_duration
logger.info("[lipsync] ffprobe 失败,使用前端传入的预合成时长: job_id=%s duration=%.2f", job.id, audio_duration)
logger.info(
"[lipsync] ffprobe 失败,使用前端传入的预合成时长: job_id=%s duration=%.2f", job.id, audio_duration
)
# 3. 句子时间戳:优先用前端预合成传入的 timings(后端预合成接口已经算过,可信);
# 否则若音频下载成功则重算;否则不设置(不阻塞主流程)
@@ -274,7 +276,7 @@ class LipsyncService:
"""
# 0. 输入校验
is_pre_synth = bool(audio_url) and bool(sentence_timings)
is_direct_audio = bool(audio_url) and not is_pre_synth
bool(audio_url) and not is_pre_synth
is_tts_mode = not bool(audio_url)
if is_tts_mode:
+1 -3
View File
@@ -26,11 +26,9 @@ from urllib.parse import urlparse
from celery import shared_task
# 复用共享的句子时间戳工具(#1845 配音前置)
from packages.domain.sentence_timings import compute_sentence_timings as _compute_sentence_timings
from packages.domain.sentence_timings import (
compute_sentence_timings as _compute_sentence_timings,
estimate_sentence_timings_by_chars as _estimate_sentence_timings_by_chars,
probe_audio_duration,
split_script_into_sentences as _split_script_into_sentences,
)
logger = logging.getLogger(__name__)
+21 -5
View File
@@ -157,8 +157,8 @@ const AiAvatarPage: React.FC = () => {
} catch (err) {
_clearTtsProgressTimer()
const errMsg =
(err as { response?: { data?: { message?: string; detail?: unknown } } })?.response?.data?.message ||
(err instanceof Error ? err.message : "配音合成失败,请重试")
(err as { response?: { data?: { message?: string; detail?: unknown } } })?.response?.data
?.message || (err instanceof Error ? err.message : "配音合成失败,请重试")
setTtsErrorMessage(typeof errMsg === "string" ? errMsg : "配音合成失败,请重试")
state.setTtsPreview({
audioUrl: null,
@@ -298,7 +298,14 @@ const AiAvatarPage: React.FC = () => {
message.error(err instanceof Error ? err.message : "对口型任务提交失败,请重试")
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [state.selectedVideo, state.selectedVoice, state.scriptText, state.speed, state.emotion, state.ttsPreview])
}, [
state.selectedVideo,
state.selectedVoice,
state.scriptText,
state.speed,
state.emotion,
state.ttsPreview,
])
// 取消对口型生成
const handleCancelLipsync = useCallback(() => {
@@ -744,7 +751,8 @@ const AiAvatarPage: React.FC = () => {
配音合成完成,点击下一步继续
</div>
<div style={{ marginTop: 8, fontSize: 13, color: "#8c8ca1" }}>
音频时长 {state.ttsPreview.duration.toFixed(1)}s,共 {state.ttsPreview.sentenceTimings.length} 句
音频时长 {state.ttsPreview.duration.toFixed(1)}s,共{" "}
{state.ttsPreview.sentenceTimings.length} 句
</div>
</>
)}
@@ -753,7 +761,15 @@ const AiAvatarPage: React.FC = () => {
<div style={{ fontSize: 48 }}>❌</div>
<div style={{ marginTop: 16, fontSize: 15, color: "#1a1a2e" }}>配音合成失败</div>
{ttsErrorMessage && (
<div style={{ marginTop: 8, fontSize: 13, color: "#ff4d4f", textAlign: "center", padding: "0 20px" }}>
<div
style={{
marginTop: 8,
fontSize: 13,
color: "#ff4d4f",
textAlign: "center",
padding: "0 20px",
}}
>
{ttsErrorMessage}
</div>
)}
+2 -1
View File
@@ -104,9 +104,10 @@ def test_preview_tts_success():
def test_preview_tts_cosyvoice_error():
"""CosyVoice 抛错:应该包装成 MediaKitError 抛出。"""
from packages.application.cosyvoice_service import CosyVoiceError
from app.services.mediakit_client import MediaKitError
from packages.application.cosyvoice_service import CosyVoiceError
svc = _make_service(cosyvoice=CosyVoiceError("cosyvoice down"))
try:
with pytest.raises(MediaKitError):