From e9b53505ac01967975616ea9b77af16b02a55cb1 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Mon, 2 Mar 2026 23:46:50 +0300 Subject: [PATCH] fix(web-test): move TTS to tools/tts/, use atempo instead of trimming - node-edge-tts installed in tools/tts/ (alongside tools/ffmpeg/) - Speed up TTS with ffmpeg atempo when it exceeds gap to next caption, instead of hard-cutting the audio Co-Authored-By: Claude Opus 4.6 --- .claude/skills/web-test/scripts/browser.mjs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.claude/skills/web-test/scripts/browser.mjs b/.claude/skills/web-test/scripts/browser.mjs index 079da284..4de0b189 100644 --- a/.claude/skills/web-test/scripts/browser.mjs +++ b/.claude/skills/web-test/scripts/browser.mjs @@ -2727,17 +2727,18 @@ export async function addNarration(videoPath, opts = {}) { segments.push({ file: silenceFile, type: 'silence' }); } - // Check if TTS audio is longer than gap to next caption — trim if needed + // Speed up TTS if it's longer than gap to next caption (instead of trimming) if (i < captions.length - 1) { const nextTimeMs = captions[i + 1].time; const maxDuration = (nextTimeMs - captionTimeMs) / 1000; if (ttsDuration > maxDuration && maxDuration > 0.1) { - const trimmedFile = pathJoin(tempDir, `tts_${i}_trimmed.mp3`); + const tempo = ttsDuration / maxDuration; + const spedFile = pathJoin(tempDir, `tts_${i}_sped.mp3`); execFileSync(ffmpegPath, [ - '-y', '-i', ttsFile, '-t', String(maxDuration), - '-c:a', 'copy', trimmedFile, + '-y', '-i', ttsFile, '-af', `atempo=${tempo.toFixed(4)}`, + '-c:a', 'libmp3lame', '-b:a', '128k', spedFile, ], { stdio: 'pipe', timeout: 10000 }); - segments.push({ file: trimmedFile, type: 'tts' }); + segments.push({ file: spedFile, type: 'tts' }); continue; } } @@ -3067,7 +3068,7 @@ function resolveFfmpeg(explicit) { async function edgeTtsProvider(text, outputPath, opts = {}) { // Resolve from tools/node_modules/ (next to ffmpeg) const __fn = fileURLToPath(import.meta.url); - const ttsModulePath = pathResolve(dirname(__fn), '..', '..', '..', '..', 'tools', 'node_modules', 'node-edge-tts', 'dist', 'edge-tts.js'); + const ttsModulePath = pathResolve(dirname(__fn), '..', '..', '..', '..', 'tools', 'tts', 'node_modules', 'node-edge-tts', 'dist', 'edge-tts.js'); const { EdgeTTS } = await import(pathToFileURL(ttsModulePath).href); const voice = opts.voice || 'ru-RU-DmitryNeural'; const tts = new EdgeTTS({ voice });