fix: use local asr for transcript timeline

This commit is contained in:
2026-05-17 13:58:05 +08:00
parent c4b6980dd0
commit 660348f39d
2 changed files with 21 additions and 9 deletions

View File

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