diff --git a/aiChat/mixins/chatMixins.js b/aiChat/mixins/chatMixins.js index a5f6d29..2cfed3b 100644 --- a/aiChat/mixins/chatMixins.js +++ b/aiChat/mixins/chatMixins.js @@ -10,6 +10,8 @@ import settings from '@/config/baseSetting.js' import { formatAiMsgContent } from '../utils/aiChat' import cookie from '@/utils/store/cookie' import { handleLoginFailure } from '@/utils' +const plugin = requirePlugin('WechatSI') +const removeMarkdown = require('remove-markdown') export const chatMixins = { data() { return { @@ -46,7 +48,9 @@ export const chatMixins = { } */ ], - errorMsg: Object.freeze('您提的问题未能理解,云灵思想跑偏啦,重新整理一下问题或者重新提问,让云灵再试试!') + errorMsg: Object.freeze('您提的问题未能理解,云灵思想跑偏啦,重新整理一下问题或者重新提问,让云灵再试试!'), + audioAyy: [], + isPlayAudio: false } }, computed: { @@ -402,6 +406,61 @@ export const chatMixins = { } catch (err) { console.log('send failed (' + err.code + ')') } + }, + ttsHandle(item) { + this.isPlayAudio = false + this.audioAyy = [] + this.splitAndSynthesize(removeMarkdown(item.content).replace(/[\n\t\s]/g, '')) + }, + splitAndSynthesize(text) { + const _this = this + if (text) { + const textLength = text.length + const chunkSize = 100 + const chunk = text.slice(0, textLength > chunkSize ? chunkSize : textLength) + plugin.textToSpeech({ + // 语言 + lang: 'zh_CN', + tts: true, + // 要转换的文字 + content: chunk, + success: function(res) { + console.log("语音文件路径:", res.filename) + _this.audioAyy.push(res.filename) + // 首次就立即播放,增强体验 + if (!_this.isPlayAudio) { + _this.playNextChunk() + } + if (textLength > chunkSize) { + // 递归调用,播放一定要按照文本分割顺序 + _this.splitAndSynthesize(text.substr(chunkSize, textLength)) + } else { + // 最后一条合成,没有正在播放则立即播放 + if (!_this.isPlayAudio) { + _this.playNextChunk() + } + } + }, + fail: function(err) { + console.log("转换失败:", err) + } + }) + } else { + if (!_this.isPlayAudio) { + _this.playNextChunk() + } + } + }, + playNextChunk() { + if (this.audioAyy.length > 0) { + this.isPlayAudio = true + const audioContext = uni.createInnerAudioContext() + audioContext.src = this.audioAyy.shift() + audioContext.onEnded(() => this.playNextChunk()) + audioContext.play() + } else { + this.isPlayAudio = false + } } } } diff --git a/aiChat/views/index.vue b/aiChat/views/index.vue index 4e69c04..791e92a 100644 --- a/aiChat/views/index.vue +++ b/aiChat/views/index.vue @@ -233,6 +233,17 @@ /> 重新生成 + + + 播放 + 拷贝 diff --git a/manifest.json b/manifest.json index aad82ac..da1cfd6 100644 --- a/manifest.json +++ b/manifest.json @@ -146,11 +146,16 @@ "plugins" : { "live-player-plugin" : { "version" : "1.3.5", - //最新直播组件版本号 + // 最新直播组件版本号 "provider" : "wx2b03c6e691cd7370" + }, + "WechatSI" : { + "version" : "0.3.6", + // TTS版本号 + "provider" : "wx069ba97219f66d99" } }, - //直播appid + // 直播appid "optimization" : { "subPackages" : true } diff --git a/package.json b/package.json index 2fa1ef9..858a590 100644 --- a/package.json +++ b/package.json @@ -79,6 +79,7 @@ "miniapp-color-thief": "^1.0.5", "number-precision": "^1.5.2", "regenerator-runtime": "^0.12.1", + "remove-markdown": "^0.6.2", "uview-ui": "2.0.36", "vconsole": "^3.14.6", "vue": "^2.6.11",