diff --git a/.memory/worklog.json b/.memory/worklog.json
index 829da85..fd7d25c 100644
--- a/.memory/worklog.json
+++ b/.memory/worklog.json
@@ -1,12 +1,5 @@
{
"entries": [
- {
- "files_changed": 1,
- "hash": "38ca0f2",
- "message": "auto-save 2026-05-14 18:21 (~1)",
- "ts": "2026-05-14T18:22:03+08:00",
- "type": "commit"
- },
{
"files_changed": 1,
"message": "Codex 会话活跃 · 最近命令:codex · 1 项未提交变更 · 最近提交:auto-save 2026-05-14 18:21 (~1)",
@@ -3270,6 +3263,13 @@
"message": "auto-save 2026-05-17 13:50 (~2)",
"hash": "5a87149",
"files_changed": 2
+ },
+ {
+ "ts": "2026-05-17T13:56:10+08:00",
+ "type": "commit",
+ "message": "auto-save 2026-05-17 13:56 (~4)",
+ "hash": "c4b6980",
+ "files_changed": 4
}
]
}
diff --git a/docs/source-analysis.html b/docs/source-analysis.html
index 35380ca..3a95e1a 100644
--- a/docs/source-analysis.html
+++ b/docs/source-analysis.html
@@ -818,7 +818,7 @@ SubjectAsset {
| 上传视频 | POST /jobs/upload | uploadJob | 保存 source.mp4,然后同样进入下载完成状态;当前上传后也加入第一步队列,下载完成后自动解析音频。 |
| 删除输入视频 | DELETE /jobs/{id} | deleteJob | 从任务队列、URL 和磁盘 jobs/<id> 目录移除整个 job,包括源视频、关键帧、元素提取图和生成视频。 |
| 解析视频 | POST /jobs/{id}/analyze?frames=&target=&mode=&quality= | analyzeJob | 后续阶段保留的抽帧能力。默认 frames=12;target 支持透明骨架人、综合、清晰主体、转场变化、表情瞬间、动作峰值。当前第一步主流程不自动调用该接口。 |
- | 音频文案轨 | POST /jobs/{id}/transcribe | triggerTranscribe | 若尚未拆轨,先从 source.mp4 提取 audio.wav 并回填 source_audio_url;随后用 ASR 提取原始文案,翻译成中文,写入 audio_script.source_text、source_zh 和逐句 transcript。ASR_TIMEOUT_SECONDS 默认 45 秒,whisper-1 超时或异常后自动 fallback 到 ASR_FALLBACK_MODEL。再用 ASR_FALLBACK_MODEL 多模态音频分析讲话人、语速节奏、停顿、背景音乐/环境声/音效,写入 speaker_profile、rhythm_profile、background_audio_profile。当前第一步不默认生成 SKG 新口播和 MiniMax 配音。 |
+ | 音频文案轨 | POST /jobs/{id}/transcribe | triggerTranscribe | 若尚未拆轨,先从 source.mp4 提取 audio.wav 并回填 source_audio_url;随后用 ASR 提取原始文案,翻译成中文,写入 audio_script.source_text、source_zh 和逐句 transcript。远端 ASR_MODEL 失败后先走本机 LOCAL_ASR_BIN/LOCAL_ASR_MODEL(默认 mlx_whisper),再尝试 ASR_FALLBACK_MODEL。后端会拒绝重复文本、逐秒假字幕或覆盖率过低的结果,不再把不可听的多模态输出写进时间轴。再用 ASR_FALLBACK_MODEL 多模态音频分析讲话人、语速节奏、停顿、背景音乐/环境声/音效,写入 speaker_profile、rhythm_profile、background_audio_profile。当前第一步不默认生成 SKG 新口播和 MiniMax 配音。 |
| 原始音频文件 | GET /jobs/{id}/audio.wav | sourceAudioUrl | 返回拆轨得到的 wav;当前主界面不再渲染底部音频条,右侧音频解析工作表直接使用 transcript 和 audio_script 展示文字与声音分析结果。 |
| 改写配音文件 | GET /jobs/{id}/audio-script.mp3 | apiAssetUrl(job.audio_script.voice_url) | 后续新配音阶段保留的 MiniMax T2A 产物。当前第一步不默认生成该文件。 |
| 手动加帧 | POST /jobs/{id}/frames?t= | addManualFrame | 按视频时间戳抽一帧,index 递增但 frames 按 timestamp 排序。 |
@@ -941,6 +941,18 @@ SubjectAsset {
变更记录
这个记录不是 git log 的替代品。它记录“产品理解发生了什么变化、影响了哪些源码、你以后描述需求时该怎么说”。后续每次改功能都要补一条。
+
+
+ 2026-05-17 · 修复逐句时间轴假字幕
+ Bugfix
+ ASR
+
+
+
问题:当前 SKG 网关模型列表没有真实 /audio/transcriptions ASR 模型,whisper-1 原始调用返回 404;后续 gemini-2.5-flash 多模态 fallback 实际不能听到音频,却返回了 1 秒一段的重复假字幕,导致“逐句时间轴”乱掉。
+
改动:api/main.py 新增本机 mlx_whisper ASR fallback,并让它复用可用静态 ffmpeg,避免 Homebrew ffmpeg 动态库损坏。新增 ASR 质量校验:重复文本、逐秒合成时间轴、音频覆盖率过低的结果会被拒绝;转写失败时不再复用旧 transcript 或写入假时间轴。当前任务 ec90faadad27 已重新解析为 25 段真实时间轴。
+
影响:api/main.py、api/.env.example、RULES.md、docs/source-analysis.html。后续部署机器需要安装或配置可用 LOCAL_ASR_BIN;否则远端 ASR 不可用时会明确失败,而不是展示假逐句。
+
+
2026-05-17 · 修复素材输入元数据解析并移除底部音频条
@@ -949,7 +961,7 @@ SubjectAsset {
问题:粘贴 TK 链接后视频已经下载到 source.mp4,但本机 Homebrew ffprobe/ffmpeg 因缺少 libx265.215.dylib 直接崩溃,后端误显示为“下载失败”。同时用户不再需要底部音频展示。
-
改动:api/main.py 新增媒体二进制选择逻辑,先验证 PATH 里的 ffmpeg/ffprobe 是否可执行,失败时回退到本机静态 ffmpeg;没有可用 ffprobe 时用 ffmpeg -i 解析时长和分辨率。下载阶段把“元数据解析失败”和“下载失败”区分开。ASR 请求增加 ASR_TIMEOUT_SECONDS,whisper-1 长时间无响应时自动走 fallback。web/app/page.tsx 不再导入和渲染 AudioStrip,AdRecreationBoard 移除“打开音轨”按钮。
+
改动:api/main.py 新增媒体二进制选择逻辑,先验证 PATH 里的 ffmpeg/ffprobe 是否可执行,失败时回退到本机静态 ffmpeg;没有可用 ffprobe 时用 ffmpeg -i 解析时长和分辨率。下载阶段把“元数据解析失败”和“下载失败”区分开。ASR 请求增加 ASR_TIMEOUT_SECONDS,后续补充本机 mlx_whisper fallback 后不再直接信任不可听的多模态假字幕。web/app/page.tsx 不再导入和渲染 AudioStrip,AdRecreationBoard 移除“打开音轨”按钮。
影响:api/main.py、web/app/page.tsx、web/components/ad-recreation-board.tsx、RULES.md、docs/source-analysis.html。后续音频预览如果需要恢复,应先明确是否仍放在右侧工作表,而不是默认恢复底部浮层。