Files
video-create/.claude/skills/video-from-script/scripts/lib/phase-tts.js
sion123 f5d47ec5db feat(video-pipeline): 添加可配置的转场策略引擎和TTS语速支持
- 引入转场策略系统(`getTransition`),支持 `fixed`、`director`、`rhythm` 三种模式
- 根据账号配置文件动态读取转场配置(`loadTransitions`)
- 图片和视频轨道分别调用转场策略,替代原有的固定“闪白”转场
- 支持 `byPosition`(hook/body/keypoint/closing)和 `byDirector` 两种高级选择策略
- 图片动画支持 `loop_animation` 与 `in_animation` 解析(“缩放”、“弹入”等组合)
- TTS 合成新增 `rate` 字段(源自账号配置 `ttsRate`),默认语速调整为 1.1
- 默认动画类型从 `kenburns-zoom` 改为 `缩放`,适配中文 CapCut
2026-05-01 14:16:08 +08:00

48 lines
1.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Phase: tts — 语音合成
*
* 使用通义千问 TTS 生成旁白音频
*/
const path = require('path')
const { saveManifest, ensureDir, log, getManifestDir } = require('./pipeline-utils')
async function phaseTts(manifest, manifestPath, options = {}) {
const dir = getManifestDir(manifestPath)
const audioDir = path.join(dir, 'audio')
ensureDir(audioDir)
const { synthesize } = require('../qwen-tts')
const items = manifest.items.filter(it =>
it.status === 'done' && (it.script || it.text) && !it.audio
)
if (items.length === 0) { log('tts', '无待处理 item跳过'); return }
log('tts', `${items.length}`)
for (let i = 0; i < items.length; i++) {
const item = items[i]
const idx = i + 1
try {
const { filePath, duration } = await synthesize(item.script || item.text, {
outputDir: audioDir,
id: item.id || idx,
voice: manifest.ttsVoice || undefined,
instruction: manifest.ttsInstruction || undefined,
rate: manifest.ttsRate || undefined,
})
item.audio = path.relative(dir, filePath).replace(/\\/g, '/')
item.audioDuration = Math.round(duration * 1000) / 1000
log('tts', `[${idx}/${items.length}] ${duration.toFixed(1)}s: ${(item.script || item.text).substring(0, 30)}...`)
} catch (err) {
item.status = 'failed'
item.error = `TTS失败: ${err.message}`
log('tts', `[${idx}/${items.length}] 失败: ${err.message}`)
}
saveManifest(manifestPath, manifest)
}
}
module.exports = { phaseTts }