refactor: narrow intake to audio-first workflow

This commit is contained in:
2026-05-17 12:55:45 +08:00
parent b02bc3f583
commit 3b9e74f0a2
9 changed files with 395 additions and 220 deletions

View File

@@ -226,7 +226,9 @@ export default function Home() {
toast.info(`上传中:${file.name} (${(file.size / 1024 / 1024).toFixed(1)} MB)`)
const created = await uploadJob(file)
addJob(created)
toast.success(`已上传 ${created.id.slice(0, 8)}`)
setProductionJobIds((prev) => new Set(prev).add(created.id))
setAudioStripJobId(created.id)
toast.success(`已上传 ${created.id.slice(0, 8)},下载完成后自动解析音频`)
} catch (e) {
toast.error("上传失败:" + (e instanceof Error ? e.message : String(e)))
} finally {
@@ -537,13 +539,11 @@ export default function Home() {
}
setProductionJobIds((prev) => new Set(prev).add(target.id))
setAudioStripJobId(target.id)
toast.success("已进入自动生产:下载完成后会抽帧、解析音频并生成分镜初稿")
toast.success("已进入第一步:下载完成后自动解析音频文案、讲话人和背景音")
if (target.video_url && ["downloaded", "frames_extracted", "transcribed", "failed"].includes(target.status)) {
if (!target.frames.length) void handleAnalyzeJob(target.id, { mode: "replace" })
void handleTranscribeAudio(target.id, { silent: true })
if (target.frames.length) void handlePlanStoryboardJob(target.id)
}
}, [handleAnalyzeJob, handlePlanStoryboardJob, handleSubmit, handleTranscribeAudio, job])
}, [handleSubmit, handleTranscribeAudio, job])
useEffect(() => {
if (productionJobIds.size === 0) return
@@ -552,22 +552,13 @@ export default function Home() {
const videoReady = !!item.video_url && ["downloaded", "frames_extracted", "transcribed", "failed"].includes(item.status)
if (!videoReady) continue
const audioKey = `${item.id}:audio`
if (!autoTriggeredRef.current.has(audioKey) && item.audio_script?.status !== "rewriting" && !item.audio_script?.rewritten_text) {
const hasAudioResult = !!item.audio_script?.source_text || item.transcript.length > 0
if (!autoTriggeredRef.current.has(audioKey) && item.audio_script?.status !== "rewriting" && !hasAudioResult) {
autoTriggeredRef.current.add(audioKey)
void handleTranscribeAudio(item.id, { silent: true })
}
const analyzeKey = `${item.id}:analyze`
if (!autoTriggeredRef.current.has(analyzeKey) && item.frames.length === 0 && item.status !== "splitting") {
autoTriggeredRef.current.add(analyzeKey)
void handleAnalyzeJob(item.id, { mode: "replace" })
}
const planKey = `${item.id}:plan:${item.frames.length}`
if (item.frames.length > 0 && !autoTriggeredRef.current.has(planKey)) {
autoTriggeredRef.current.add(planKey)
void handlePlanStoryboardJob(item.id)
}
}
}, [handleAnalyzeJob, handlePlanStoryboardJob, handleTranscribeAudio, jobs, productionJobIds])
}, [handleTranscribeAudio, jobs, productionJobIds])
const handleQuickGenerateVideo = useCallback(async (frameIdx: number, scene: StoryboardScene, model: string) => {
if (!job) return
@@ -812,7 +803,7 @@ export default function Home() {
if (jobs.length === 0) return
// 状态切到 downloaded 时提示用户点解析(仅一次)
if (job?.status === "downloaded" && prevStatusRef.current !== "downloaded") {
toast.info("视频已就绪,请在左侧看板开始抽帧", { duration: 6000 })
toast.info("视频已下载,音频解析会自动开始;也可以在右侧手动重试", { duration: 6000 })
}
prevStatusRef.current = job?.status ?? null