Uniapp 小程序:语音播放与暂停功能的实现及优化方案

ops/2025/2/27 19:45:01/

界面部分

//开启语音 
<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()
}

总结
这段代码实现了语音播放和暂停的功能,通过界面上的按钮触发相应的操作。在播放语音时,会对内容进行截断和分割处理,以适应文字转语音插件的要求。同时,为了提高稳定性,添加了重试机制。在页面隐藏和卸载时,会自动停止语音播放并释放资源。


http://www.ppmy.cn/ops/161761.html

相关文章

Java异常类型

一、异常体系架构 1.1 体系图解 1.2 Exception & Error Exception 表示程序可以处理的异常情况&#xff0c;通常是由于程序逻辑错误或运行时问题引起的&#xff0c;比如NullPointException、IOException等。这些异常是设计用来被程序捕获&#xff0c;并采取相应的恢复措施…

【SQLI】sqlmap测试过滤规则和tamper有效性的方法

sqlmap测试过滤和tamper有效性的方法 1. 检测被过滤的字符或关键字2. 测试有效的 Tamper 脚本3. 自动化过滤检测4. 自定义 Tamper 脚本示例命令总结注意事项 使用 sqlmap 测试过滤规则和确定有效 tamper 脚本的步骤如下&#xff1a; 1. 检测被过滤的字符或关键字 方法一&#…

计算机毕设-基于springboot的仁和机构的体检预约系统的设计与实现(附源码+lw+ppt+开题报告)

博主介绍&#xff1a;✌多个项目实战经验、多个大型网购商城开发经验、在某机构指导学员上千名、专注于本行业领域✌ 技术范围&#xff1a;Java实战项目、Python实战项目、微信小程序/安卓实战项目、爬虫大数据实战项目、Nodejs实战项目、PHP实战项目、.NET实战项目、Golang实战…

视频字幕识别和翻译

下载的视频很多不是汉语的&#xff0c;我们需要用剪映将语音识别出来作为字幕压制到视频中去。 剪映6.0以后语音识别需要收费&#xff0c;但是低版本还是没有问题。 如果想要非汉语字幕转成中文&#xff0c;剪映低版本不提供这样功能。但是&#xff0c;用剪映导出识别字幕&am…

取消票证会把指定的票证从数据库中删除,同时也会把票证和航班 等相关表中的关联关系一起删除。但在删除之前,它会先检查当前用户是否拥有这张票

在做航班智能客服问答系统时会遇到取消票证的场景&#xff0c;这里涉及数据库的操作时会把指定的票证从数据库中删除&#xff0c;同时也会把票证和航班等相关表中的关联关系一起删除。但在删除之前&#xff0c;需要先检查当前用户是否拥有这张票&#xff0c;只有票主才有权限取…

前端面试真题 2025最新版

文章目录 写在前文CSS怪异盒模型JS闭包闭包的形成闭包注意点 CSS选择器及优先级优先级 说说flex布局及相关属性Flex 容器相关属性&#xff1a;Flex 项目相关属性 响应式布局如何实现是否用过tailwindcss&#xff0c;有哪些好处好处缺点 说说对象的 prototype属性及原型说说 pro…

使用 Three.js 转换 GLSL 粒子效果着色器

大家好&#xff01;我是 [数擎AI]&#xff0c;一位热爱探索新技术的前端开发者&#xff0c;在这里分享前端和 Web3D、AI 技术的干货与实战经验。如果你对技术有热情&#xff0c;欢迎关注我的文章&#xff0c;我们一起成长、进步&#xff01; 开发领域&#xff1a;前端开发 | AI…

JavaScript AJAX 库

注意&#xff1a;如果正在寻找可与React一起使用的AJAX库&#xff0c;请参阅React 的 AJAX 库。 这就是没有库来简化它的 AJAX 的样子。 <!DOCTYPE html> <!-- basic_ajax.html --> <html lang"en"> <head> <meta charset"UTF…