feat: 语音支持中日结合

This commit is contained in:
ikechan8370 2023-03-15 23:33:08 +08:00
parent 4a94241f15
commit b212fcf87e
4 changed files with 91 additions and 6 deletions

View file

@ -619,7 +619,7 @@ export class chatgpt extends plugin {
}
if (useTTS) {
if (Config.ttsSpace && response.length <= 299) {
let wav = await generateAudio(response, speaker, '中')
let wav = await generateAudio(response, speaker, '中日混合(中文用[ZH][ZH]包裹起来,日文用[JA][JA]包裹起来)')
await e.reply(segment.record(wav))
if (Config.alsoSendText) {
await this.reply(`${response}`, e.isGroup)

View file

@ -375,10 +375,93 @@ export async function isCN () {
}
}
export function limitString(str, maxLength) {
export function limitString (str, maxLength) {
if (str.length <= maxLength) {
return str;
return str
} else {
return str.slice(0, maxLength) + '...';
return str.slice(0, maxLength) + '...'
}
}
/**
* ```
* var text = '你好こんにちはHello';
* var wrappedText = wrapTextByLanguage(text);
* console.log(wrappedText);
* ```
* @param text
* @returns {string}
*/
export function wrapTextByLanguage (text) {
// 根据标点符号分割句子
const symbols = /([。!?,])/
let sentences = text.split(symbols)
sentences = sentences.reduce((acc, cur, index) => {
if (symbols.test(cur)) {
// 如果当前字符串是标点符号,则将其添加到前一个字符串的末尾
acc[acc.length - 1] += cur
} else {
// 否则,将当前字符串添加到结果数组中
acc.push(cur)
}
return acc
}, [])
let wrappedSentences = []
for (let i = 0; i < sentences.length; i++) {
let sentence = sentences[i]
// 如果是标点符号,则跳过
if (sentence === '。' || sentence === '' || sentence === '' || sentence === '') {
continue
}
const pattern = /[a-zA-Z]/g
sentence = sentence.replace(pattern, '')
// 判断这一句话是中文还是日语
let isChinese = true
let isJapanese = false
for (let j = 0; j < sentence.length; j++) {
let char = sentence.charAt(j)
if (char.match(/[\u3040-\u309F\u30A0-\u30FF]/)) {
isJapanese = true
isChinese = false
break
}
}
// 包裹句子
if (isChinese) {
sentence = `[ZH]${sentence}[ZH]`
} else if (isJapanese) {
sentence = `[JA]${sentence}[JA]`
}
wrappedSentences.push(sentence)
}
const mergedSentences = wrappedSentences.reduce((acc, cur) => {
if (cur === '') {
// 如果当前字符串为空或者是标点符号,则直接将其添加到结果数组中
acc.push(cur)
} else {
// 否则,判断前一个字符串和当前字符串是否为同种语言
const prev = acc[acc.length - 1]
let curPrefix = `${cur.slice(0, 4)}`
if (prev && prev.startsWith(curPrefix)) {
// 如果前一个字符串和当前字符串为同种语言,则将它们合并
let a = (acc[acc.length - 1] + cur)
a = lodash.replace(a, curPrefix + curPrefix, '')
acc[acc.length - 1] = a
} else {
// 否则,将当前字符串添加到结果数组中
acc.push(cur)
}
}
return acc
}, [])
return mergedSentences.join('')
}
// console.log(wrapTextByLanguage('你好这里是哈哈こんにちはHello'))

View file

@ -61,7 +61,7 @@ const defaultConfig = {
initiativeChatGroups: [],
enableDraw: true,
helloPrompt: '写一段话让大家来找我聊天。类似于“有人找我聊天吗?"这种风格轻松随意一点控制在20个字以内',
version: 'v2.1.7'
version: 'v2.1.8'
}
const _path = process.cwd()
let config = {}

View file

@ -1,6 +1,7 @@
import { Config } from './config.js'
import fetch from 'node-fetch'
import _ from 'lodash'
import {wrapTextByLanguage} from "./common.js";
let proxy
if (Config.proxy) {
try {
@ -35,11 +36,12 @@ function randomNum (minNum, maxNum) {
return 0
}
}
export async function generateAudio (text, speaker = '随机', language = '中', noiseScale = Config.noiseScale, noiseScaleW = Config.noiseScaleW, lengthScale = Config.lengthScale) {
export async function generateAudio (text, speaker = '随机', language = '中日混合(中文用[ZH][ZH]包裹起来,日文用[JA][JA]包裹起来)', noiseScale = Config.noiseScale, noiseScaleW = Config.noiseScaleW, lengthScale = Config.lengthScale) {
if (!speaker || speaker === '随机') {
logger.info('随机角色!这次哪个角色这么幸运会被选到呢……')
speaker = speakers[randomNum(0, speakers.length)]
}
text = wrapTextByLanguage(text)
logger.info(`正在使用${speaker},基于文本:'${text}'生成语音`)
let body = {
data: [