@minto-ai/huoshan-tts
Version:
借助“火山引擎在线语音合成API”实现浏览器端“文本转语音
100 lines (88 loc) • 2.76 kB
text/typescript
/**
* 发音规则
* 描述某一段文本的发音,供转换为 Ssml 的 <phoneme> 使用
* @property content 原始文本内容(可为多字符,用于最长匹配)
* @property alphabet 发音字母表,支持 'py'(拼音)或 'ipa'
* @property ph 发音标记,依据 alphabet 的格式填写
*/
interface PronunciationRule {
content: string
alphabet: 'py' | 'ipa'
ph: string
}
/**
* 发音规则列表
* 由多个发音规则构成的数组
*/
type PronunciationRuleList = Array<PronunciationRule>
/**
* Ssml 转换器
* 根据发音规则,将输入文本按最长匹配替换为 <phoneme> 并输出 Ssml
*/
class SsmlConverter {
private readonly pronunciationRules: PronunciationRuleList
/**
* 创建 Ssml 转换器
* @param pronunciationRules 多音字/词规则列表,按长度降序用于最长匹配
*/
constructor(pronunciationRules: PronunciationRuleList) {
this.pronunciationRules = [
...pronunciationRules.sort((a, b) => b.content.length - a.content.length),
]
}
/**
* 批量转换段落为 Ssml 字符串数组
* @param paragraphs 段落文本数组
* @returns Ssml 字符串数组
*/
convertParagraphs(paragraphs: string[]): string[] {
const ssmlList: string[] = []
for (const paragraph of paragraphs) {
ssmlList.push(this.convertParagraph(paragraph))
}
return ssmlList
}
/**
* 单段落转换为 Ssml
* @param paragraph 段落文本
* @returns Ssml 字符串
*/
private convertParagraph(paragraph: string): string {
let ssmlText = ''
let cursor = 0
while (cursor < paragraph.length) {
const matchedRule: PronunciationRule | null = this.pronunciationRules.find(rule =>
paragraph.startsWith(rule.content, cursor),
) ?? null
if (matchedRule !== null) {
ssmlText += `<phoneme alphabet="${matchedRule.alphabet}" ph="${matchedRule.ph}">${matchedRule.content}</phoneme>`
cursor += matchedRule.content.length
}
else {
ssmlText += paragraph[cursor]
cursor += 1
}
}
return `<speak>${ssmlText}</speak>`
}
}
let ssmlConverter: SsmlConverter | null = null
/**
* 创建或复用 Ssml 转换器(单例)
* @param pronunciationRules 发音规则列表
* @returns SsmlConverter 实例(全局复用)
*/
function createSsmlConverter(pronunciationRules: PronunciationRuleList): SsmlConverter {
if (ssmlConverter === null) {
ssmlConverter = new SsmlConverter(pronunciationRules)
}
return ssmlConverter
}
export {
createSsmlConverter,
}
export type {
PronunciationRule,
PronunciationRuleList,
SsmlConverter,
}