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

界面部分

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/978173.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【嵌入式原理设计】实验六:倒车控制设计

目录 一、实验目的 二、实验环境 三、实验内容 四、实验记录及处理 五、实验小结 六、成果文件提取链接 一、实验目的 熟悉和掌握各模块联合控制的工作方式 二、实验环境 Win10ESP32实验开发板 三、实验内容 1、用串口和OLED显示当前小车与障碍物的距离值&#xff1b…

探索浮点数在内存中的存储(附带快速计算补码转十进制)

目录 一、浮点数在内存中的存储 1、常见的浮点数&#xff1a; 2、浮点数存储规则&#xff1a; 3、内存中无法精确存储&#xff1a; 4、移码与指数位E&#xff1a; 5、指数E的三种情况&#xff1a; 二、快速计算补码转十进制 1、第一种方法讨论&#xff1a; 2、第二种方…

实体机器人识别虚拟环境中障碍物

之前的内容已经实现了虚拟机器人识别实体机器人的功能&#xff0c;接下来就是实体机器人如何识别虚拟环境中的障碍物&#xff08;包括虚拟环境中的障碍物和其他虚拟机器人&#xff09;。 我做的是基于雷达的&#xff0c;所以主要要处理的是雷达的scan话题 我的虚拟机器人命名…

湖北中医药大学谱度众合(武汉)生命科技有限公司研究生工作站揭牌

2025年2月11日&#xff0c;湖北中医药大学&谱度众合&#xff08;武汉&#xff09;生命科技有限公司研究生工作站揭牌仪式在武汉生物技术研究院一楼101会议室举行&#xff0c;湖北中医药大学研究生院院长刘娅教授、基础医学院院长孔明望教授、基础医学院赵敏教授、基础医学院…

ARM Coretex-M核心单片机(STM32)找到hardfault的原因,与hardfault解决方法

1. 前提基础知识&#xff08;ARM异常 压栈流程&#xff09;M核栈增长是地址逐渐减小的 **M3h ARM CM4核心带浮点处理器FPU的&#xff0c;压栈的东西还不一样 进入hardfult后看MSP或者SP的值&#xff0c;看下边第二章图如果hardfult里边啥都没有&#xff0c;就只有个while(1){}…

组件传递props校验

注意&#xff1a;prop是只读的&#xff01;不可以修改父组件的数据。 可以检验传过来的内容是否类型没问题。 App.vue <template><div><!-- <parentDemo/> --><componentA/></div></template> <script> import ComponentA …

机试刷题_NC52 有效括号序列【python】

NC52 有效括号序列 from operator import truediv # # 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可 # # # param s string字符串 # return bool布尔型 # class Solution:def isValid(self , s: str) -> bool:if not s…

threejs:document.createElement创建标签后css设置失效

vue3threejs&#xff0c;做一个给模型批量CSS2D标签的案例&#xff0c;在导入模型的js文件里&#xff0c;跟着课程写的代码如下&#xff1a; import * as THREE from three; // 引入gltf模型加载库GLTFLoader.js import { GLTFLoader } from three/addons/loaders/GLTFLoader.…

一文读懂西门子 PLC 串口转以太网系列模块

在工业自动化领域&#xff0c;随着智能化和信息化的不断发展&#xff0c;设备之间的高效通信变得至关重要。西门子 PLC 作为工业控制的核心设备&#xff0c;其通信方式的拓展需求日益凸显。西门子 PLC 串口转网口产品应运而生&#xff0c;它为实现串口设备与以太网网络的无缝连…

Linux | GRUB / bootloader 详解

注&#xff1a;本文为 “Linux | GRUB / bootloader” 相关文章合辑。 英文引文&#xff0c;机翻未校。 图片清晰度限于引文原状。 未整理去重。 What is Grub in Linux? What is it Used for? Linux 中的 Grub 是什么&#xff1f;它的用途是什么&#xff1f; Abhishek …

java高级(IO流多线程)

file 递归 字符集 编码 乱码gbk&#xff0c;a我m&#xff0c;utf-8 缓冲流 冒泡排序 //冒泡排序 public static void bubbleSort(int[] arr) {int n arr.length;for (int i 0; i < n - 1; i) { // 外层循环控制排序轮数for (int j 0; j < n -i - 1; j) { // 内层循环…

Dubbo RPC 原理

一、Dubbo 简介 Apache Dubbo 是一款高性能、轻量级的开源 RPC 框架&#xff0c;支持服务治理、协议扩展、负载均衡、容错机制等核心功能&#xff0c;广泛应用于微服务架构。其核心目标是解决分布式服务之间的高效通信与服务治理问题。 二、Dubbo 架构设计 1. 核心组件 Prov…

普中单片机-51TFT-LCD显示屏(1.8寸 STM32)

普中官方论坛&#xff1a; http://www.prechin.cn/gongsixinwen/208.html 普中科技-各型号开发板资料链接&#xff1a;https://www.bilibili.com/read/cv23681775/?spm_id_from333.999.0.0 27-TFTLCD显示实验_哔哩哔哩_bilibili 2.程序烧录 2.1设置彩屏驱动 3.实验效果

Starlink卫星动力学系统仿真建模第九讲-滑模(SMC)控制算法原理简介及卫星控制应用

滑模控制&#xff08;Sliding Mode Control&#xff09;算法详解 一、基本原理 滑模控制&#xff08;Sliding Mode Control, SMC&#xff09;是一种变结构控制方法&#xff0c;通过设计一个滑模面&#xff08;Sliding Surface&#xff09;&#xff0c;迫使系统状态在有限时间内…

nss刷题5(misc)

[HUBUCTF 2022 新生赛]最简单的misc 打开后是一张图片&#xff0c;没有其他东西&#xff0c;分离不出来&#xff0c;看看lsb&#xff0c;红绿蓝都是0&#xff0c;看到头是png&#xff0c;重新保存为png&#xff0c;得到一张二维码 扫码得到flag [羊城杯 2021]签到题 是个动图…

【C/C++】删除链表的倒数第 N 个结点(leetcode T19)

考点预览&#xff1a; 双指针法&#xff1a;通过维护两个指针来一次遍历链表&#xff0c;避免了多次遍历链表的低效方法。 边界条件&#xff1a;要特别处理删除头结点的情况。 题目描述&#xff1a; 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回…

人工智能定义

一、人工智能核心概念体系 1.1 人工智能的本质 人工智能的定义:人工智能(Artificial Intelligence,简称 AI)是指计算机系统能够执行通常需要人类智能才能完成的任务,如学习、推理、解决问题、理解自然语言、识别图像和声音等。它通过模拟人类的智能行为,运用算法和数据…

量子计算的威胁,以及企业可以采取的措施

当谷歌、IBM、Honeywell和微软等科技巨头纷纷投身量子计算领域时&#xff0c;一场技术军备竞赛已然拉开帷幕。 量子计算虽能为全球数字经济带来巨大价值&#xff0c;但也有可能对相互关联的系统、设备和数据造成损害。这一潜在影响在全球网络安全领域引起了强烈关注。也正因如…

0—QT ui界面一览

2025.2.26&#xff0c;感谢gpt4 1.控件盒子 1. Layouts&#xff08;布局&#xff09; 布局控件用于组织界面上的控件&#xff0c;确保它们的位置和排列方式合理。 Vertical Layout&#xff08;垂直布局&#xff09; &#xff1a;将控件按垂直方向排列。 建议&#xff1a;适…

【Uniapp-Vue3】导入uni-id用户体系

在uniapp官网的uniCloud中下载uni-id用户体系 或者直接进入加载&#xff0c;下载地址&#xff1a;uni-id-pages - DCloud 插件市场 进入以后下载插件&#xff0c;打开HbuilderX 选中项目&#xff0c;点击确定 点击跳过 点击合并 右键uniCloud文件夹下的database文件夹&#x…