feat: 黑白名单支持配置qq号;支持所有语音模式下的随机角色对话;新增查看当前用户的回复设置;完善全局设置的相关功能;支持为Azure语音服务随机选择角色;优化设置全局语音角色和查看角色列表的功能;重构了代码以支持现有语音服务的打招呼功能;修复了Guoba面板上Azure语音角色选择的显示问题。 (#436)

* feat: add support for ‘greeting’ and ‘global reply mode’ commands, improve variable naming and remove unnecessary backend output.

* feat: Add support for black and white lists, global reply mode and voice role settings, private chat switch, and active greeting configuration. Refactor some variable names and comment out redundant code for better readability and reduced backend output.

* feat: 为新功能完善了帮助面板

* docs: 完善了‘打招呼’的帮助说明

* Commit Type: feat, bugfix

Add functionality to view plugin command table, fix bug in blacklist/whitelist, and fix bug where chat mode can still be used in private messaging when disabled.

* Commit Type: feat, bugfix

Add functionality to view plugin command table, fix bug in blacklist/whitelist, and fix bug where chat mode can still be used in private messaging when disabled.

* refactor: Remove redundant log output.

* Refactor: optimize code logic

* Fix: 修复绘图指令表被抢指令的bug。

* Refactor:1. Add support for automatically translating replies to Japanese and generating voice messages in VITS voice mode (please monitor remaining quota after enabling). 2. Add translation function. 3. Add emotion configuration for Azure voice mode, allowing the robot to select appropriate emotional styles for replies.

* Refactor:Handle the issue of exceeding character setting limit caused by adding emotion configuration.

* Fix: fix bugs

* Refactor: Added error feedback to translation service

* Refactor: Added support for viewing the list of supported roles for each language mode, and fixed some bugs in the emotion switching feature of the auzre mode.

* Refactor: Optimized some command feedback and added owner restriction to chat record export function.

* Refactor: Optimized feedback when viewing role list to avoid excessive messages.

* Refactor: Optimized feedback when configuring multi-emotion mode.

* Feature: Added help instructions for translation feature.

* chore: Adjust help instructions for mood settings

* Fix: Fixed issue where only first line of multi-line replies were being read and Azure voice was pronouncing punctuation marks.

* Fix: Fixed bug where switching to Azure voice mode prompted for missing key and restricted ability to view voice role list to only when in voice mode.

* Refactor: Add image OCR function and support translation for both quoted text and image.

* fix: Fix issue with error caused by non-image input.

* Refactor: Optimize code to filter emojis that cannot be displayed properly in claude mode.

* Refactor: Optimize some code structures.

* fix: Fix the bug of returning only one result when entering multiple lines of text on Windows system.

* Refactor: Optimize code logic for better user experience

* Refactor: Fix the conflict issue with other plugin translation commands

* Refactor: Replace Baidu Translation with Youdao Translation to eliminate configuration steps; optimize translation experience; add missing dependency prompts instead of causing program errors.Optimize the experience of switching between voice mode and setting global reply mode.

* Refactor: Remove unused files and dependencies in the project.

* Feature: Add Youdao translation service to provide more comprehensive translation support.

* Refactor: Optimize translation experience

* Refactor: Optimize translation experience

* Feature: Add functionality of keyword search command

* Feature: Add functionality of keyword search command.

* Refactor: Remove redundant code

* Add: Add feature to support randomly selecting roles for Azure voice. Refactor the code to support existing voice services for the ‘greeting’ feature. Fix the display issue of Azure voice role selection on the Guoba panel.

* Refactor: Remove redundant code

* Refactor: Improve the function of setting global voice roles and viewing role lists. Now you can set default roles for each voice service separately or view the supported role list.

* Refactor: Remove redundant code

* Feature: Add new function to support random character dialogues in all voice modes, add the ability to view the current user’s reply settings, and improve related functions in the global settings.

* Refactor: Add compatibility directive for viewing reply settings feature

* Feature: support adding QQ number to blacklist/whitelist

* fix: 处理全局设置指令被上下班指令占用的问题

* fix: 处理全局设置指令被上下班指令占用的问题

---------

Co-authored-by: Sean <1519059137@qq.com>
Co-authored-by: ikechan8370 <geyinchibuaa@gmail.com>
This commit is contained in:
Sean Murphy 2023-06-05 11:40:10 +08:00 committed by GitHub
parent 7007cacf6f
commit bdad936c70
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 704 additions and 447 deletions

View file

@ -8,6 +8,9 @@ import buffer from 'buffer'
import yaml from 'yaml'
import puppeteer from '../../../lib/puppeteer/puppeteer.js'
import { Config } from './config.js'
import { speakers as vitsRoleList } from './tts.js'
import { supportConfigurations as voxRoleList } from './tts/voicevox.js'
import { supportConfigurations as azureRoleList } from './tts/microsoft-azure.js'
// export function markdownToText (markdown) {
// return remark()
// .use(stripMarkdown)
@ -19,7 +22,7 @@ let _puppeteer
try {
const Puppeteer = (await import('../../../renderers/puppeteer/lib/puppeteer.js')).default
let puppeteerCfg = {}
let configFile = `./renderers/puppeteer/config.yaml`
let configFile = './renderers/puppeteer/config.yaml'
if (fs.existsSync(configFile)) {
try {
puppeteerCfg = yaml.parse(fs.readFileSync(configFile, 'utf8'))
@ -335,7 +338,7 @@ export async function renderUrl (e, url, renderCfg = {}) {
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: url,
url,
option: {
width: renderCfg.Viewport.width || 1280,
height: renderCfg.Viewport.height || 720,
@ -350,7 +353,7 @@ export async function renderUrl (e, url, renderCfg = {}) {
})
if (resultres.ok) {
const buff = Buffer.from(await resultres.arrayBuffer())
if(buff) {
if (buff) {
const base64 = segment.image(buff)
if (renderCfg.retType === 'base64') {
return base64
@ -363,7 +366,7 @@ export async function renderUrl (e, url, renderCfg = {}) {
}
}
}
await _puppeteer.browserInit()
const page = await _puppeteer.browser.newPage()
let base64
@ -401,7 +404,8 @@ export function getDefaultReplySetting () {
usePicture: Config.defaultUsePicture,
useTTS: Config.defaultUseTTS,
ttsRole: Config.defaultTTSRole,
ttsRoleAzure: Config.azureTTSSpeaker
ttsRoleAzure: Config.azureTTSSpeaker,
ttsRoleVoiceVox: Config.voicevoxTTSSpeaker
}
}
@ -679,16 +683,106 @@ export async function getUserData (user) {
return JSON.parse(data)
} catch (error) {
return {
user: user,
user,
passwd: '',
chat: [],
mode: '',
cast: {
api: '', //API设定
bing: '', //必应设定
bing_resource: '', //必应扩展资料
slack: '', //Slack设定
api: '', // API设定
bing: '', // 必应设定
bing_resource: '', // 必应扩展资料
slack: '' // Slack设定
}
}
}
}
}
export function getVoicevoxRoleList () {
return voxRoleList.map(item => item.name).join('、')
}
export function getAzureRoleList () {
return azureRoleList.map(item => item.name).join('、')
}
export async function getVitsRoleList (e) {
const [firstHalf, secondHalf] = [vitsRoleList.slice(0, Math.floor(vitsRoleList.length / 2)).join('、'), vitsRoleList.slice(Math.floor(vitsRoleList.length / 2)).join('、')]
const [chunk1, chunk2] = [firstHalf.match(/[^、]+(?:、[^、]+){0,30}/g), secondHalf.match(/[^、]+(?:、[^、]+){0,30}/g)]
const list = [await makeForwardMsg(e, chunk1, 'vits角色列表1'), await makeForwardMsg(e, chunk2, 'vits角色列表2')]
return await makeForwardMsg(e, list, 'vits角色列表')
}
export async function getUserReplySetting (e) {
let userSetting = await redis.get(`CHATGPT:USER:${e.sender.user_id}`)
if (userSetting) {
userSetting = JSON.parse(userSetting)
if (Object.keys(userSetting).indexOf('useTTS') < 0) {
userSetting.useTTS = Config.defaultUseTTS
}
} else {
userSetting = getDefaultReplySetting()
}
return userSetting
}
export async function getImg (e) {
// 取消息中的图片、at的头像、回复的图片放入e.img
if (e.at && !e.source) {
e.img = [`https://q1.qlogo.cn/g?b=qq&s=0&nk=${e.at}`]
}
if (e.source) {
let reply
if (e.isGroup) {
reply = (await e.group.getChatHistory(e.source.seq, 1)).pop()?.message
} else {
reply = (await e.friend.getChatHistory(e.source.time, 1)).pop()?.message
}
if (reply) {
let i = []
for (let val of reply) {
if (val.type === 'image') {
i.push(val.url)
}
}
e.img = i
}
}
return e.img
}
export async function getImageOcrText (e) {
const img = await getImg(e)
if (img) {
try {
let resultArr = []
let eachImgRes = ''
for (let i in img) {
const imgOCR = await Bot.imageOcr(img[i])
for (let text of imgOCR.wordslist) {
eachImgRes += (`${text?.words} \n`)
}
if (eachImgRes) resultArr.push(eachImgRes)
eachImgRes = ''
}
// logger.warn('resultArr', resultArr)
return resultArr
} catch (err) {
return false
// logger.error(err)
}
} else {
return false
}
}
// 对原始黑白名单进行去重和去除无效群号处理,并处理通过锅巴面板添加错误配置时可能导致的问题
export function processList (whitelist, blacklist) {
whitelist = Array.isArray(whitelist)
? whitelist
: String(whitelist).split(/[,]/)
blacklist = !Array.isArray(blacklist)
? blacklist
: String(blacklist).split(/[,]/)
whitelist = Array.from(new Set(whitelist)).filter(value => /^\^?[1-9]\d{5,9}$/.test(value))
blacklist = Array.from(new Set(blacklist)).filter(value => /^\^?[1-9]\d{5,9}$/.test(value))
return [whitelist, blacklist]
}

View file

@ -99,8 +99,8 @@ const defaultConfig = {
live2dOption_rotation: 0,
groupAdminPage: false,
enablePrivateChat: false,
groupWhitelist: [],
groupBlacklist: [],
whitelist: [],
blacklist: [],
ttsRegex: '/匹配规则/匹配模式',
slackUserToken: '',
slackBotUserToken: '',

View file

@ -1,6 +1,7 @@
import crypto from 'crypto'
import { getDefaultReplySetting, mkdirs } from '../common.js'
import { Config } from '../config.js'
import { translate } from '../translate.js'
let sdk
try {
@ -20,20 +21,29 @@ async function generateAudio (text, option = {}, ssml = '') {
let filename = `${_path}/data/chatgpt/tts/azure/${crypto.randomUUID()}.wav`
let audioConfig = sdk.AudioConfig.fromAudioFileOutput(filename)
let synthesizer
let speaker = option?.speaker || '随机'
let context = text
// 打招呼用
if (speaker === '随机') {
speaker = supportConfigurations[Math.floor(Math.random() * supportConfigurations.length)].code
let languagePrefix = supportConfigurations.find(config => config.code === speaker).languageDetail.charAt(0)
languagePrefix = languagePrefix.startsWith('E') ? '英' : languagePrefix
context = (await translate(context, languagePrefix)).replace('\n', '')
}
if (ssml) {
synthesizer = new sdk.SpeechSynthesizer(speechConfig, audioConfig)
await speakSsmlAsync(synthesizer, ssml)
} else {
speechConfig.speechSynthesisLanguage = option?.language || 'zh-CN'
logger.info('using speaker: ' + option?.speaker || 'zh-CN-YunyeNeural')
speechConfig.speechSynthesisVoiceName = option?.speaker || 'zh-CN-YunyeNeural'
} else { // 打招呼用
speechConfig.speechSynthesisLanguage = option?.language || supportConfigurations.find(config => config.code === speaker).language
speechConfig.speechSynthesisVoiceName = speaker
logger.info('using speaker: ' + speaker)
logger.info('using language: ' + speechConfig.speechSynthesisLanguage)
synthesizer = new sdk.SpeechSynthesizer(speechConfig, audioConfig)
await speakTextAsync(synthesizer, text)
await speakTextAsync(synthesizer, context)
}
console.log('synthesis finished.')
synthesizer.close()
synthesizer = undefined
return filename
}
@ -73,11 +83,27 @@ async function speakSsmlAsync (synthesizer, ssml) {
})
}
async function generateSsml (text, option = {}) {
const voiceName = option.speaker || 'zh-CN-YunyeNeural'
const expressAs = option.emotion ? `<mstts:express-as style="${option.emotion}" styledegree="${option.emotionDegree || 1}">` : ''
let speaker = option?.speaker || '随机'
let emotionDegree, role, emotion
// 打招呼用
if (speaker === '随机') {
role = supportConfigurations[Math.floor(Math.random() * supportConfigurations.length)]
speaker = role.code
if (role?.emotion) {
const keys = Object.keys(role.emotion)
emotion = keys[Math.floor(Math.random() * keys.length)]
}
logger.info('using speaker: ' + speaker)
logger.info('using emotion: ' + emotion)
emotionDegree = 2
} else {
emotion = option.emotion
emotionDegree = option.emotionDegree
}
const expressAs = emotion !== undefined ? `<mstts:express-as style="${emotion}" styledegree="${emotionDegree || 1}">` : ''
return `<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis"
xmlns:mstts="https://www.w3.org/2001/mstts" xml:lang="zh-CN">
<voice name="${voiceName}">
<voice name="${speaker}">
${expressAs}${text}${expressAs ? '</mstts:express-as>' : ''}
</voice>
</speak>`
@ -91,7 +117,7 @@ async function getEmotionPrompt (e) {
let emotionPrompt = ''
let ttsRoleAzure = userReplySetting.ttsRoleAzure
const configuration = Config.ttsMode === 'azure' ? supportConfigurations.find(config => config.code === ttsRoleAzure) : ''
if (configuration !== '' && configuration.emotion) {
if (configuration !== '' && configuration?.emotion) {
// 0-1 感觉没啥区别说实话只有1和2听得出差别。。
emotionPrompt = `\n在回复的最开始使用[]在其中表示你这次回复的情绪风格和程度(1-2)最小单位0.1
\n例如['angry',2]表示你极度愤怒
@ -110,28 +136,32 @@ export const supportConfigurations = [
name: '晓北',
language: 'zh-CN',
languageDetail: '中文(东北官话,简体)',
gender: '女'
gender: '女',
roleInfo: '晓北-女-中文(东北官话,简体)'
},
{
code: 'zh-CN-henan-YundengNeural',
name: '云登',
language: 'zh-CN',
languageDetail: '中文(中原官话河南,简体)',
gender: '男'
gender: '男',
roleInfo: '云登-男-中文(中原官话河南,简体)'
},
{
code: 'zh-CN-shaanxi-XiaoniNeural',
name: '晓妮',
language: 'zh-CN',
languageDetail: '中文(中原官话陕西,简体)',
gender: '女'
gender: '女',
roleInfo: '晓妮-女-中文(中原官话陕西,简体)'
},
{
code: 'zh-CN-henan-YundengNeural',
name: '云翔',
language: 'zh-CN',
languageDetail: '中文(冀鲁官话,简体)',
gender: '男'
gender: '男',
roleInfo: '云翔-男-中文(冀鲁官话,简体)'
},
{
code: 'zh-CN-XiaoxiaoNeural',
@ -157,7 +187,8 @@ export const supportConfigurations = [
'poetry-reading': '读诗时带情感和节奏的语气',
sad: '表达悲伤语气',
serious: '严肃、命令的语气'
}
},
roleInfo: '晓晓-女-中文(普通话,简体)'
},
{
code: 'zh-CN-YunxiNeural',
@ -178,7 +209,8 @@ export const supportConfigurations = [
newscast: '用于新闻播报,表现出庄重、严谨的语气',
sad: '表达悲伤、失落的语气',
serious: '表现出认真、严肃的语气'
}
},
roleInfo: '云希-男-中文 (普通话,简体)'
},
{
code: 'zh-CN-YunyangNeural',
@ -190,7 +222,8 @@ export const supportConfigurations = [
customerservice: '以亲切友好的语气为客户提供支持',
'narration-professional': '以专业、稳重的语气讲述',
'newscast-casual': '以轻松自然的语气播报新闻'
}
},
roleInfo: '云扬-男-中文 (普通话,简体)'
},
{
code: 'zh-CN-YunyeNeural',
@ -207,7 +240,8 @@ export const supportConfigurations = [
fearful: '表达害怕和不安的语气',
sad: '表达悲伤和失落的语气',
serious: '以认真和严肃的态度说话'
}
},
roleInfo: '云野-男-中文(普通话,简体)'
},
{
code: 'zh-CN-XiaoshuangNeural',
@ -215,37 +249,40 @@ export const supportConfigurations = [
language: 'zh-CN',
languageDetail: '中文(普通话,简体)',
gender: '女',
emotion: {
chat: '表达轻松随意的语气'
}
emotion: { chat: '表达轻松随意的语气' },
roleInfo: '晓双-女-中文(普通话,简体)'
},
{
code: 'zh-CN-XiaoyouNeural',
name: '晓悠',
language: 'zh-CN',
languageDetail: '中文(普通话,简体)',
gender: '女'
gender: '女',
roleInfo: '晓悠-女-中文(普通话,简体)'
},
{
code: 'zh-CN-XiaoqiuNeural',
name: '晓秋',
language: 'zh-CN',
languageDetail: '中文(普通话,简体)',
gender: '女'
gender: '女',
roleInfo: '晓秋-女-中文(普通话,简体)'
},
{
code: 'zh-CN-XiaochenNeural',
name: '晓辰',
language: 'zh-CN',
languageDetail: '中文(普通话,简体)',
gender: '女'
gender: '女',
roleInfo: '晓辰-女-中文(普通话,简体)'
},
{
code: 'zh-CN-XiaoyanNeural',
name: '晓颜',
language: 'zh-CN',
languageDetail: '中文(普通话,简体)',
gender: '女'
gender: '女',
roleInfo: '晓颜-女-中文(普通话,简体)'
},
{
code: 'zh-CN-XiaomoNeural',
@ -266,7 +303,8 @@ export const supportConfigurations = [
gentle: '温和、礼貌、愉快的语气,音调和音量较低',
sad: '表达悲伤语气',
serious: '严肃、命令的语气'
}
},
roleInfo: '晓墨-女-中文(普通话,简体)'
},
{
code: 'zh-CN-XiaoxuanNeural',
@ -283,7 +321,8 @@ export const supportConfigurations = [
fearful: '恐惧、紧张的语气,说话人处于紧张和不安的状态',
gentle: '温和、礼貌、愉快的语气,音调和音量较低',
serious: '严肃、命令的语气'
}
},
roleInfo: '晓萱-女-中文(普通话,简体)'
},
{
code: 'zh-CN-XiaohanNeural',
@ -302,7 +341,8 @@ export const supportConfigurations = [
gentle: '温和、礼貌、愉快的语气,音调和音量较低',
sad: '表达悲伤语气',
serious: '严肃、命令的语气'
}
},
roleInfo: '晓涵-女-中文(普通话,简体)'
},
{
code: 'zh-CN-XiaoruiNeural',
@ -315,7 +355,8 @@ export const supportConfigurations = [
calm: '沉着冷静的态度说话。语气、音调和韵律统一',
fearful: '恐惧、紧张的语气,说话人处于紧张和不安的状态',
sad: '表达悲伤语气'
}
},
roleInfo: '晓睿-女-中文(普通话,简体)'
},
{
code: 'zh-CN-XiaomengNeural',
@ -323,9 +364,8 @@ export const supportConfigurations = [
language: 'zh-CN',
languageDetail: '中文(普通话,简体)',
gender: '女',
emotion: {
chat: '表达轻松随意的语气'
}
emotion: { chat: '表达轻松随意的语气' },
roleInfo: '晓梦-女-中文(普通话,简体)'
},
{
code: 'zh-CN-XiaoyiNeural',
@ -340,7 +380,8 @@ export const supportConfigurations = [
gentle: '温和、礼貌、愉快的语气,音调和音量较低',
sad: '表达悲伤语气',
serious: '严肃、命令的语气'
}
},
roleInfo: '晓伊-女-中文(普通话,简体)'
},
{
code: 'zh-CN-XiaozhenNeural',
@ -355,7 +396,8 @@ export const supportConfigurations = [
fearful: '恐惧、紧张的语气,说话人处于紧张和不安的状态',
sad: '表达悲伤语气',
serious: '严肃、命令的语气'
}
},
roleInfo: '晓甄-女-中文(普通话,简体)'
},
{
code: 'zh-CN-YunfengNeural',
@ -371,14 +413,16 @@ export const supportConfigurations = [
fearful: '恐惧、紧张的语气,说话人处于紧张和不安的状态',
sad: '表达悲伤语气',
serious: '严肃、命令的语气'
}
},
roleInfo: '云枫-男-中文(普通话,简体)'
},
{
code: 'zh-CN-YunhaoNeural',
name: '云皓',
language: 'zh-CN',
languageDetail: '中文(普通话,简体)',
gender: '男'
gender: '男',
roleInfo: '云皓-男-中文(普通话,简体)'
},
{
code: 'zh-CN-YunjianNeural',
@ -390,7 +434,8 @@ export const supportConfigurations = [
'narration-relaxed': '以轻松、自然的语气进行叙述',
'sports-commentary': '在解说体育比赛时,使用专业而自信的语气',
'sports-commentary-excited': '在解说激动人心的体育比赛时,使用兴奋和激动的语气'
}
},
roleInfo: '云健-男-中文(普通话,简体)'
},
{
code: 'zh-CN-YunxiaNeural',
@ -404,7 +449,8 @@ export const supportConfigurations = [
cheerful: '表达积极愉快的语气',
fearful: '表达害怕、紧张的语气',
sad: '表达悲伤和失落的语气'
}
},
roleInfo: '云夏-男-中文 (普通话,简体)'
},
{
code: 'zh-CN-YunzeNeural',
@ -422,105 +468,120 @@ export const supportConfigurations = [
fearful: '表达害怕、不安的情绪',
sad: '用悲伤的语气表达悲伤和失落',
serious: '以严肃的语气和态度表现出对事情的重视和认真对待'
}
},
roleInfo: '云泽-男-中文 (普通话,简体)'
},
{
code: 'zh-HK-HiuGaaiNeural',
name: '曉佳',
language: 'zh-CN',
languageDetail: '中文(粤语,繁体)',
gender: '女'
gender: '女',
roleInfo: '曉佳-女-中文(粤语,繁体)'
},
{
code: 'zh-HK-HiuMaanNeural',
name: '曉曼',
language: 'zh-CN',
languageDetail: '中文(粤语,繁体)',
gender: '女'
gender: '女',
roleInfo: '曉曼-女-中文(粤语,繁体)'
},
{
code: 'zh-HK-WanLungNeural',
name: '雲龍',
language: 'zh-CN',
languageDetail: '中文(粤语,繁体)',
gender: '男'
gender: '男',
roleInfo: '雲龍-男-中文(粤语,繁体)'
},
{
code: 'en-GB-AbbiNeural',
name: 'Abbi',
language: 'en-GB',
languageDetail: '英语(英国)',
gender: 'female'
gender: 'female',
roleInfo: 'Abbi-女-英语(英国)'
},
{
code: 'en-GB-AlfieNeural',
name: 'Alfie',
language: 'en-GB',
languageDetail: '英语(英国)',
gender: 'male'
gender: 'male',
roleInfo: 'Alfie-男-英语(英国)'
},
{
code: 'en-GB-BellaNeural',
name: 'Bella',
language: 'en-GB',
languageDetail: '英语(英国)',
gender: 'female'
gender: 'female',
roleInfo: 'Bella-女-英语(英国)'
},
{
code: 'en-GB-ElliotNeural',
name: 'Elliot',
language: 'en-GB',
languageDetail: '英语(英国)',
gender: 'male'
gender: 'male',
roleInfo: 'Elliot-男-英语(英国)'
},
{
code: 'en-GB-EthanNeural',
name: 'Ethan',
language: 'en-GB',
languageDetail: '英语(英国)',
gender: 'male'
gender: 'male',
roleInfo: 'Ethan-男-英语(英国)'
},
{
code: 'en-GB-HollieNeural',
name: 'Hollie',
language: 'en-GB',
languageDetail: '英语(英国)',
gender: 'female'
gender: 'female',
roleInfo: 'Hollie-女-英语(英国)'
},
{
code: 'en-GB-LibbyNeural',
name: 'Libby',
language: 'en-GB',
languageDetail: '英语(英国)',
gender: 'female'
gender: 'female',
roleInfo: 'Libby-女-英语(英国)'
},
{
code: 'en-GB-MaisieNeural',
name: 'Maisie',
language: 'en-GB',
languageDetail: '英语(英国)',
gender: 'female'
gender: 'female',
roleInfo: 'Maisie-女-英语(英国)'
},
{
code: 'en-GB-NoahNeural',
name: 'Noah',
language: 'en-GB',
languageDetail: '英语(英国)',
gender: 'male'
gender: 'male',
roleInfo: 'Noah-男-英语(英国)'
},
{
code: 'en-GB-OliverNeural',
name: 'Oliver',
language: 'en-GB',
languageDetail: '英语(英国)',
gender: 'male'
gender: 'male',
roleInfo: 'Oliver-男-英语(英国)'
},
{
code: 'en-GB-OliviaNeural',
name: 'Olivia',
language: 'en-GB',
languageDetail: '英语(英国)',
gender: 'female'
gender: 'female',
roleInfo: 'Olivia-女-英语(英国)'
},
{
code: 'en-GB-RyanNeural',
@ -528,11 +589,8 @@ export const supportConfigurations = [
language: 'en-GB',
languageDetail: '英语(英国)',
gender: 'male',
emotion: {
chat: '表达轻松随意的语气',
cheerful: '表达积极愉快的语气'
}
emotion: { chat: '表达轻松随意的语气', cheerful: '表达积极愉快的语气' },
roleInfo: 'Ryan-男-英语(英国)'
},
{
code: 'en-GB-SoniaNeural',
@ -540,46 +598,48 @@ export const supportConfigurations = [
language: 'en-GB',
languageDetail: '英语(英国)',
gender: 'female',
emotion: {
cheerful: '表达积极愉快的语气',
sad: '表达悲伤语气'
}
emotion: { cheerful: '表达积极愉快的语气', sad: '表达悲伤语气' },
roleInfo: 'Sonia-女-英语(英国)'
},
{
code: 'en-GB-ThomasNeural',
name: 'Thomas',
language: 'en-GB',
languageDetail: '英语(英国)',
gender: 'male'
gender: 'male',
roleInfo: 'Thomas-男-英语(英国)'
},
{
code: 'ja-JP-AoiNeural',
name: '葵',
language: 'ja-JP',
languageDetail: '日语(日本)',
gender: '女'
gender: '女',
roleInfo: '葵-女-日语(日本)'
},
{
code: 'ja-JP-DaichiNeural',
name: '大地',
language: 'ja-JP',
languageDetail: '日语(日本)',
gender: '男'
gender: '男',
roleInfo: '大地-男-日语(日本)'
},
{
code: 'ja-JP-KeitaNeural',
name: '慶太',
language: 'ja-JP',
languageDetail: '日语(日本)',
gender: '男'
gender: '男',
roleInfo: '慶太-男-日语(日本)'
},
{
code: 'ja-JP-MayuNeural',
name: '真由',
language: 'ja-JP',
languageDetail: '日语(日本)',
gender: '女'
gender: '女',
roleInfo: '真由-女-日语(日本)'
},
{
code: 'ja-JP-NanamiNeural',
@ -591,49 +651,56 @@ export const supportConfigurations = [
chat: '表达轻松随意的语气',
cheerful: '表达积极愉快的语气',
customerservice: '以友好热情的语气为客户提供支持'
}
},
roleInfo: '七海-女-日语(日本)'
},
{
code: 'ja-JP-NaokiNeural',
name: '直樹',
language: 'ja-JP',
languageDetail: '日语(日本)',
gender: '男'
gender: '男',
roleInfo: '直樹-男-日语(日本)'
},
{
code: 'ja-JP-ShioriNeural',
name: '栞',
language: 'ja-JP',
languageDetail: '日语(日本)',
gender: '女'
gender: '女',
roleInfo: '栞-女-日语(日本)'
},
{
code: 'en-US-AIGenerate1Neural1',
name: 'AI Generate 1',
language: 'en-US',
languageDetail: 'English (United States)',
gender: '男'
gender: '男',
roleInfo: 'AI Generate 1-男-英语(美国)'
},
{
code: 'en-US-AIGenerate2Neural1',
name: 'AI Generate 2',
language: 'en-US',
languageDetail: 'English (United States)',
gender: '女'
gender: '女',
roleInfo: 'AI Generate 2-女-英语(美国)'
},
{
code: 'en-US-AmberNeural',
name: 'Amber',
language: 'en-US',
languageDetail: 'English (United States)',
gender: '女'
gender: '女',
roleInfo: 'Amber-女-英语(美国)'
},
{
code: 'en-US-AnaNeural',
name: 'Ana',
language: 'en-US',
languageDetail: 'English (United States)',
gender: '女性、儿童'
gender: '女性、儿童',
roleInfo: 'Ana-女性、儿童-英语(美国)'
},
{
code: 'en-US-AriaNeural',
@ -658,35 +725,40 @@ export const supportConfigurations = [
'narration-professional': '以专业、客观的语气朗读内容',
'newscast-casual': '以通用、随意的语气发布一般新闻',
'newscast-formal': '以正式、自信和权威的语气发布新闻'
}
},
roleInfo: 'Aria-女-英语(美国)'
},
{
code: 'en-US-AshleyNeural',
name: 'Ashley',
language: 'en-US',
languageDetail: 'English (United States)',
gender: '女'
gender: '女',
roleInfo: 'Ashley-女-英语(美国)'
},
{
code: 'en-US-BrandonNeural',
name: 'Brandon',
language: 'en-US',
languageDetail: 'English (United States)',
gender: '男'
gender: '男',
roleInfo: 'Brandon-男-英语(美国)'
},
{
code: 'en-US-ChristopherNeural',
name: 'Christopher',
language: 'en-US',
languageDetail: 'English (United States)',
gender: '男'
gender: '男',
roleInfo: 'Christopher-男-英语(美国)'
},
{
code: 'en-US-CoraNeural',
name: 'Cora',
language: 'en-US',
languageDetail: 'English (United States)',
gender: '女'
gender: '女',
roleInfo: 'Cora-女-英语(美国)'
},
{
code: 'en-US-DavisNeural',
@ -705,21 +777,24 @@ export const supportConfigurations = [
terrified: '非常害怕的语气,语速快且声音颤抖。不稳定的疯狂状态',
unfriendly: '表达一种冷淡无情的语气',
whispering: '说话非常柔和,发出的声音小且温柔'
}
},
roleInfo: 'Davis-男-英语(美国)'
},
{
code: 'en-US-ElizabethNeural',
name: 'Elizabeth',
language: 'en-US',
languageDetail: 'English (United States)',
gender: '女'
gender: '女',
roleInfo: 'Elizabeth-女-英语(美国)'
},
{
code: 'en-US-EricNeural',
name: 'Eric',
language: 'en-US',
languageDetail: 'English (United States)',
gender: '男'
gender: '男',
roleInfo: 'Eric-男-英语(美国)'
},
{
code: 'en-US-GuyNeural',
@ -739,15 +814,16 @@ export const supportConfigurations = [
unfriendly: '表达一种冷淡无情的语气',
whispering: '说话非常柔和,发出的声音小且温柔',
newscast: '以正式专业的语气叙述新闻'
}
},
roleInfo: 'Guy-男-英语(美国)'
},
{
code: 'en-US-JacobNeural',
name: 'Jacob',
language: 'en-US',
languageDetail: 'English (United States)',
gender: '男'
gender: '男',
roleInfo: 'Jacob-男-英语(美国)'
},
{
code: 'en-US-JaneNeural',
@ -766,7 +842,8 @@ export const supportConfigurations = [
terrified: '非常害怕的语气,语速快且声音颤抖。不稳定的疯狂状态',
unfriendly: '表达一种冷淡无情的语气',
whispering: '说话非常柔和,发出的声音小且温柔'
}
},
roleInfo: 'Jane-女-英语(美国)'
},
{
code: 'en-US-JasonNeural',
@ -785,14 +862,8 @@ export const supportConfigurations = [
terrified: '非常害怕的语气,语速快且声音颤抖。不稳定的疯狂状态',
unfriendly: '表达一种冷淡无情的语气',
whispering: '说话非常柔和,发出的声音小且温柔'
}
},
{
code: 'en-US-JennyMultilingualNeural3',
name: 'Jenny',
language: 'en-US',
languageDetail: '英语(美国)',
gender: 'female'
},
roleInfo: 'Jason-男-英语(美国)'
},
{
code: 'en-US-JennyNeural',
@ -815,22 +886,24 @@ export const supportConfigurations = [
chat: '表达轻松随意的语气',
customerservice: '以友好热情的语气为客户提供支持',
newscast: '以正式专业的语气叙述新闻'
}
},
roleInfo: 'Jenny-女-英语(美国)'
},
{
code: 'en-US-MichelleNeural',
name: 'Michelle',
language: 'en-US',
languageDetail: '英语(美国)',
gender: 'female'
gender: 'female',
roleInfo: 'Michelle-女-英语(美国)'
},
{
code: 'en-US-MonicaNeural',
name: 'Monica',
language: 'en-US',
languageDetail: '英语(美国)',
gender: 'female'
gender: 'female',
roleInfo: 'Monica-女-英语(美国)'
},
{
code: 'en-US-NancyNeural',
@ -849,14 +922,16 @@ export const supportConfigurations = [
terrified: '非常害怕的语气,语速快且声音颤抖。不稳定的疯狂状态',
unfriendly: '表达一种冷淡无情的语气',
whispering: '说话非常柔和,发出的声音小且温柔'
}
},
roleInfo: 'Nancy-女-英语(美国)'
},
{
code: 'en-US-RogerNeural',
name: 'Roger',
language: 'en-US',
languageDetail: '英语(美国)',
gender: 'male'
gender: 'male',
roleInfo: 'Roger-男-英语(美国)'
},
{
code: 'en-US-SaraNeural',
@ -875,15 +950,16 @@ export const supportConfigurations = [
terrified: '非常害怕的语气,语速快且声音颤抖。不稳定的疯狂状态',
unfriendly: '表达一种冷淡无情的语气',
whispering: '说话非常柔和,发出的声音小且温柔'
}
},
roleInfo: 'Sara-女-英语(美国)'
},
{
code: 'en-US-SteffanNeural',
name: 'Steffan',
language: 'en-US',
languageDetail: '英语(美国)',
gender: 'male'
gender: 'male',
roleInfo: 'Steffan-男-英语(美国)'
},
{
code: 'en-US-TonyNeural',
@ -902,21 +978,24 @@ export const supportConfigurations = [
terrified: '非常害怕的语气,语速快且声音颤抖。不稳定的疯狂状态',
unfriendly: '表达一种冷淡无情的语气',
whispering: '说话非常柔和,发出的声音小且温柔'
}
},
roleInfo: 'Tony-男-英语(美国)'
},
{
code: 'en-IN-NeerjaNeural',
name: 'Neerja',
language: 'en',
languageDetail: '英语(印度)',
gender: 'female'
gender: 'female',
roleInfo: 'Neerja-女-英语(印度)'
},
{
code: 'en-IN-PrabhatNeural',
name: 'Prabhat',
language: 'en',
languageDetail: '英语(印度)',
gender: 'male'
gender: 'male',
roleInfo: 'Prabhat-男-英语(印度)'
}
]