界面部分
//开启语音
<button class="open" v-if="showPlay==false" @click="playText">这是开启播放的图片</button >//关闭语音
<button class="close" v-if="showPlay==true" @click="stopText">这是关闭播放的图片</button >
播放语音方法 playText
该方法用于处理语音播放的逻辑,包括内容截断、分割、重试机制等。
playText: function() {// 检查是否正在等待响应,如果是则提示用户等待// 切换显示为正在播放状态this.showPlay = true; // 初始化重试次数let retryCount = 0; // 设置最大重试次数const maxRetryTimes = 3; // 重试间隔时间(单位:毫秒)const retryInterval = 2000; // 假设最大允许的内容长度,可根据实际调整const maxContentLength = 100; // 截断内容的函数,如果内容长度超过最大允许长度,则截取前 maxContentLength 个字符const truncateContent = (content) => {if (content.length > maxContentLength) {return content.slice(0, maxContentLength);}return content;};// 分割内容的函数,将长内容按合适的分割符号(。!,?)分割成多个部分const splitContent = (content) => {const parts = [];let start = 0;while (start < content.length) {let end = start + maxContentLength;if (end >= content.length) {parts.push(content.slice(start));break;}// 从后往前查找合适的分割符号(。!,?)let symbolIndices = [content.lastIndexOf('。', end), content.lastIndexOf('!', end), content.lastIndexOf('?', end), content.lastIndexOf(',', end)];symbolIndices = symbolIndices.filter(index => index > start);if (symbolIndices.length > 0) {end = Math.max(...symbolIndices);}parts.push(content.slice(start, end));start = end + 1;}return parts;};// 播放分割后的内容部分的函数const playParts = (parts) => {let index = 0;const playNextPart = () => {if (index < parts.length) {const part = parts[index];const plugin = requirePlugin('WechatSI');// 调用文字转语音插件plugin.textToSpeech({lang: 'zh_CN',tts: true,content: part,success: (res) => {// 创建内部音频上下文并播放音频this.innerAudioContext = uni.createInnerAudioContext();this.innerAudioContext.src = res.filename;this.innerAudioContext.play();// 监听音频播放结束事件,播放下一部分this.innerAudioContext.onEnded(() => {index++;playNextPart();});},fail: (res) => {console.log('文字转语音失败', res);if (retryCount < maxRetryTimes) {retryCount++;console.log(`正在进行第${retryCount}次重试...`);// 重试播放setTimeout(() => playNextPart(), retryInterval);} else {console.log('已达到最大重试次数,文字转语音仍失败');}}});} else {// 所有部分播放完毕,切换显示为可播放状态this.showPlay = false; }};playNextPart();};// 截断内容const truncatedContent = truncateContent(this.readContent);// 分割内容const splitContents = splitContent(this.readContent);if (splitContents.length > 1) {// 如果分割后的内容部分大于 1,则按部分播放playParts(splitContents);} else {// 内容较短,直接播放const retryFn = () => {if (retryCount < maxRetryTimes) {retryCount++;console.log(`正在进行第${retryCount}次重试...`);const plugin = requirePlugin('WechatSI');// 调用文字转语音插件plugin.textToSpeech({lang: 'zh_CN',tts: true,content: truncatedContent,success: (res) => {// 创建内部音频上下文并播放音频this.innerAudioContext = uni.createInnerAudioContext();this.innerAudioContext.src = res.filename;this.innerAudioContext.play();},fail: (res) => {console.log('文字转语音失败', res);// 重试播放setTimeout(retryFn, retryInterval);}});} else {console.log('已达到最大重试次数,文字转语音仍失败');}};const plugin = requirePlugin('WechatSI');// 调用文字转语音插件plugin.textToSpeech({lang: 'zh_CN',tts: true,content: truncatedContent,success: (res) => {// 创建内部音频上下文并播放音频this.innerAudioContext = uni.createInnerAudioContext();this.innerAudioContext.src = res.filename;this.innerAudioContext.play();},fail: (res) => {console.log('文字转语音失败', res);// 重试播放setTimeout(retryFn, retryInterval);}});}
}
暂停语音方法 stopText
该方法用于停止语音播放并释放资源。
stopText() {// 切换显示为可播放状态this.showPlay = false;if (this.innerAudioContext) {// 停止播放this.innerAudioContext.stop(); // 释放资源this.innerAudioContext = null; }
}
页面隐藏和卸载时的处理
在页面隐藏和卸载时,调用 stopText 方法停止语音播放。
onHide() {this.stopText()
},
onUnload() {this.stopText()
}
总结
这段代码实现了语音播放和暂停的功能,通过界面上的按钮触发相应的操作。在播放语音时,会对内容进行截断和分割处理,以适应文字转语音插件的要求。同时,为了提高稳定性,添加了重试机制。在页面隐藏和卸载时,会自动停止语音播放并释放资源。