mirror of
https://github.com/ikechan8370/chatgpt-plugin.git
synced 2025-12-17 13:57:10 +00:00
feat: 语音支持中日结合
This commit is contained in:
parent
4a94241f15
commit
b212fcf87e
4 changed files with 91 additions and 6 deletions
|
|
@ -619,7 +619,7 @@ export class chatgpt extends plugin {
|
||||||
}
|
}
|
||||||
if (useTTS) {
|
if (useTTS) {
|
||||||
if (Config.ttsSpace && response.length <= 299) {
|
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))
|
await e.reply(segment.record(wav))
|
||||||
if (Config.alsoSendText) {
|
if (Config.alsoSendText) {
|
||||||
await this.reply(`${response}`, e.isGroup)
|
await this.reply(`${response}`, e.isGroup)
|
||||||
|
|
|
||||||
|
|
@ -377,8 +377,91 @@ export async function isCN () {
|
||||||
|
|
||||||
export function limitString (str, maxLength) {
|
export function limitString (str, maxLength) {
|
||||||
if (str.length <= maxLength) {
|
if (str.length <= maxLength) {
|
||||||
return str;
|
return str
|
||||||
} else {
|
} 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!'))
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ const defaultConfig = {
|
||||||
initiativeChatGroups: [],
|
initiativeChatGroups: [],
|
||||||
enableDraw: true,
|
enableDraw: true,
|
||||||
helloPrompt: '写一段话让大家来找我聊天。类似于“有人找我聊天吗?"这种风格,轻松随意一点控制在20个字以内',
|
helloPrompt: '写一段话让大家来找我聊天。类似于“有人找我聊天吗?"这种风格,轻松随意一点控制在20个字以内',
|
||||||
version: 'v2.1.7'
|
version: 'v2.1.8'
|
||||||
}
|
}
|
||||||
const _path = process.cwd()
|
const _path = process.cwd()
|
||||||
let config = {}
|
let config = {}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { Config } from './config.js'
|
import { Config } from './config.js'
|
||||||
import fetch from 'node-fetch'
|
import fetch from 'node-fetch'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
import {wrapTextByLanguage} from "./common.js";
|
||||||
let proxy
|
let proxy
|
||||||
if (Config.proxy) {
|
if (Config.proxy) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -35,11 +36,12 @@ function randomNum (minNum, maxNum) {
|
||||||
return 0
|
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 === '随机') {
|
if (!speaker || speaker === '随机') {
|
||||||
logger.info('随机角色!这次哪个角色这么幸运会被选到呢……')
|
logger.info('随机角色!这次哪个角色这么幸运会被选到呢……')
|
||||||
speaker = speakers[randomNum(0, speakers.length)]
|
speaker = speakers[randomNum(0, speakers.length)]
|
||||||
}
|
}
|
||||||
|
text = wrapTextByLanguage(text)
|
||||||
logger.info(`正在使用${speaker},基于文本:'${text}'生成语音`)
|
logger.info(`正在使用${speaker},基于文本:'${text}'生成语音`)
|
||||||
let body = {
|
let body = {
|
||||||
data: [
|
data: [
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue