uni-app录音功能
纯纯干货,cv即用
<template><!-- 录音页面 --><view class="page"><view class="tape_box"><view class="upload_box1"><view class="upload_top"><view class="upload_img_title">录音</view></view><view class="tape_calculagraph">{{ formatTime }}</view><view class="upload_pate_con"><!-- 点击录音按钮 --><image @click="toggleRecording":src="isRecording ? '../../static/isks.png' : '../../static/isks.png'" mode=""style="width: 60px;height: 50px;"></image></view><view class="clear_tape" @click="clearRecording" v-if="recordingAvailable">清除录音</view><!-- H5 平台的音频播放器 --><view v-if="recordingAvailable" class="audio-player"><audio ref="h5Audio" :src="audioURL" controls autoplay title="自定义的音频名称" @play="onAudioPlay"@pause="onAudioPause" @ended="onAudioEnded"></audio></view></view></view></view>
</template><script setup>
import { ref, computed, onMounted, onBeforeUnmount, onUnmounted } from 'vue';
// 录音相关变量
const isRecording = ref(false);
const time = ref(0);
const formatTime = computed(() => {const minutes = String(Math.floor(time.value / 60)).padStart(2, '0');const seconds = String(time.value % 60).padStart(2, '0');return `${minutes}:${seconds}`;
});
let timer = null;// 平台检测
const systemInfo = uni.getSystemInfoSync();
const platform = systemInfo.platform;// 录音管理器
let recorderManager = null;// H5录音相关变量
let mediaRecorder = null;
let audioChunks = [];
let audioBlob = null;
const recordingAvailable = ref(false);
let audioURL = '';// 播放相关变量
const isPlaying = ref(false);
const h5Audio = ref(null);// 初始化录音和播放功能
onMounted(() => {if (['ios', 'android', 'devtools'].includes(platform)) {initNativeRecorder();isPlaying.value = false;} else if (['windows', 'mac'].includes(platform)) {initH5Recorder();} else {uni.showToast({title: '当前平台不支持录音',icon: 'none',});}
});// 清理资源
onBeforeUnmount(() => {if (h5Audio.value) {h5Audio.value.removeEventListener('play', onAudioPlay);h5Audio.value.removeEventListener('pause', onAudioPause);h5Audio.value.removeEventListener('ended', onAudioEnded);}
});onUnmounted(() => {clearInterval(timer);if (recorderManager && recorderManager.stop) {recorderManager.stop();}if (mediaRecorder && mediaRecorder.state !== 'inactive') {mediaRecorder.stop();}
});// 初始化原生平台的录音管理器
function initNativeRecorder() {recorderManager = uni.getRecorderManager();recorderManager.onStart(() => {console.log('开始录音');});recorderManager.onStop((res) => {console.log('录音已停止', res);isRecording.value = false;clearInterval(timer);time.value = 0;recordingAvailable.value = true;audioURL = res.tempFilePath;});recorderManager.onError((err) => {console.error('录音错误', err);isRecording.value = false;clearInterval(timer);time.value = 0;uni.showToast({title: '录音失败',icon: 'none',});});
}// 初始化H5平台的录音器
function initH5Recorder() {if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {uni.showToast({title: '浏览器不支持录音功能',icon: 'none',});return;}
}// 切换录音状态
function toggleRecording() {if (isRecording.value) {stopRecording();} else {startRecording();}
}// 开始录音
function startRecording() {if (['ios', 'android', 'devtools'].includes(platform)) {uni.authorize({scope: 'scope.record',success() {recorderManager.start({format: 'mp3',});isRecording.value = true;timer = setInterval(() => {time.value += 1;}, 1000);},fail() {uni.showModal({content: '请打开录音功能权限',confirmText: '确认',cancelText: '取消',success: (res) => {if (res.confirm) {uni.openSetting();}},});},});} else {// H5平台录音navigator.mediaDevices.getUserMedia({audio: true,}).then((stream) => {mediaRecorder = new MediaRecorder(stream);mediaRecorder.start();isRecording.value = true;timer = setInterval(() => {time.value += 1;}, 1000);mediaRecorder.ondataavailable = (e) => {audioChunks.push(e.data);};mediaRecorder.onstop = () => {audioBlob = new Blob(audioChunks, { type: 'audio/mp3' });audioChunks = [];recordingAvailable.value = true;audioURL = URL.createObjectURL(audioBlob);if (h5Audio.value) {h5Audio.value.src = audioURL;}};}).catch((err) => {console.error('录音失败:', err);uni.showToast({title: '无法访问麦克风',icon: 'none',});});}
}// 停止录音
function stopRecording() {if (['ios', 'android', 'devtools'].includes(platform)) {recorderManager.stop();} else {if (mediaRecorder && mediaRecorder.state !== 'inactive') {mediaRecorder.stop();isRecording.value = false;clearInterval(timer);time.value = 0;}}
}// 清除录音
function clearRecording() {recordingAvailable.value = false;audioURL = '';time.value = 0;
}// H5音频播放事件处理
function onAudioPlay() {isPlaying.value = true;
}function onAudioPause() {isPlaying.value = false;
}function onAudioEnded() {isPlaying.value = false;
}
</script><style>
.page {position: fixed;top: 0;left: 0;right: 0;bottom: 0;background-color: rgba(0, 0, 0, 0.5);display: flex;justify-content: center;align-items: center;
}.tape_box {background-color: white;width: 90%;padding: 20px;border-radius: 10px;box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);text-align: center;
}.upload_top {display: flex;justify-content: space-between;align-items: center;
}.upload_img_title {flex: 1;text-align: center;font-size: 18px;font-weight: bold;
}.tape_calculagraph {margin: 10px 0;font-size: 24px;font-weight: bold;
}.upload_pate_con image {width: 50px;height: 50px;cursor: pointer;
}.clear_tape {margin-top: 10px;color: #00daca;cursor: pointer;
}.audio-player audio {width: 100%;margin-top: 10px;
}
</style>
相关文章:
uni-app录音功能
纯纯干货,cv即用 <template><!-- 录音页面 --><view class"page"><view class"tape_box"><view class"upload_box1"><view class"upload_top"><view class"upload_img_title…...

C语言【调试】(个人笔记版)
调试 前言一、Bug二、调试工具1.DeBug2.Release 三、调试快捷键1、断点 四、调试时查看程序的当前信息1、查看临时变量2、查看内存3、查看调用堆栈、汇编、寄存器 总结 前言 这篇文章大都是我的个人笔记: 调试在日常程序设计中是很重要的。调试说白了就是为了解决代…...

连锁收银系统
商淘云连锁管理系统助力连锁企业实现“人货账”全方位数字化管理,它依托连锁品牌进销存管理实现门店订货、线下收银、线上商城、会员营销等一体化管理。 门店订货补货支持连锁直营、加盟 不同门店不同进货价、不同门店不同商品、不同门店在线或者账期支付、门店PC或…...
5.2024.10.21
2024.10.21 学习和复习 学习QT的流程控制、函数、内联函数复习C语言printf练习 问题及解决方案 C学到函数之后有些吃力代码逻辑能力不大行,需要巩固一下C语言基础再挤多点时间去学习嵌入式写代码前先把大概思路写出来 碎碎念 最近作业比较多,有点静不下…...
前端Socket互动小游戏开发体验分享
随着实时网络通信技术的不断发展,基于WebSocket的前端互动小游戏成为了一种非常流行的选择。WebSocket允许客户端和服务器之间进行双向通信,为游戏互动带来了更快的响应时间和更流畅的体验。本文将通过一个简单的互动小游戏来探讨前端如何利用WebSocket技…...
react项目,通过自定义 separator 属性来修改日期选择器中间的分隔符:
1. 引入必要的依赖 确保你已经引入了 DatePicker 组件和 moment 库。 import React, { Component } from react; import { DatePicker } from antd; import moment from moment; const { RangePicker } DatePicker; const dateFormat "YYYY/MM/DD"; 2. 定义父组…...

双十一有啥好用的家居好物推荐?2024性价比高的超声波清洗机推荐
双十一今天晚上就可以越热开抢了,还不知道购买什么物品的小伙伴们赶紧来看看我这篇文章,在众多家居好物中,超声波清洗机以其高效、便捷的特点,成为了许多家庭的必备神器。2024年,市场上涌现出了不少性价比超高的产品&a…...

比亚迪车机安装第三方应用教程
比亚迪车机安装第三方应用教程 比亚迪车机U盘安装APP, 无论是dlink3.0还是4.0都是安卓系统,因此理论上安卓应用是都可以安装的,主要就是横屏和竖屏的区别。在比亚迪上安装软件我主要推荐两种方法。 第一种,直接从电脑端下载安装布…...

移动零---双指针法
目录 一:题目 二:算法原理讲解 三:代码编写 一:题目 题目链接:https://leetcode.cn/problems/move-zeroes/description/ 二:算法原理讲解 三:代码编写 void moveZeroes2(vector<int>& nums) {for (int d…...

MoeCTF 2024 ---Misc方向WP
安全杂项 signin 题目描述: xdsec的小伙伴们和参赛者来上课,碰巧这一天签到系统坏了,作为老师的你,要帮他们 教师代签。 特殊提醒:luo同学今天好像在宿舍打游戏,不想来上课,这是严重的缺勤行为…...

【我的 RT 学习手札】信息收集
相关笔记整理自B站up主泷羽sec全栈渗透测试教学(免费) 视频链接为泷羽sec的个人空间-泷羽sec个人主页-哔哩哔哩视频 笔记只是方便师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线࿰…...
CMake变量:CMAKE_FIND_LIBRARY_SUFFIXES
CMAKE_FIND_LIBRARY_SUFFIXES是CMake中的一个变量,用于指定在查找库文件时使用的后缀列表。当CMake需要找到库文件时,它会尝试在这些后缀后添加库名来构建库文件的完整路径。例如,如果库名为mylib,并且CMAKE_FIND_LIBRARY_SUFFIXE…...

在使用 RabbitMQ 作为消息代理时,多个 Celery 实例(或应用)可以共享同一个 RabbitMQ 实例
在使用 RabbitMQ 作为消息代理时,多个 Celery 实例(或应用)可以共享同一个 RabbitMQ 实例。这样做可以简化基础设施管理,同时允许不同的 Celery 应用之间进行消息传递和协作。下面是如何配置多个 Celery 实例以使用同一个 RabbitM…...
ARM在嵌入式开发中的作用有哪些?
ARM在嵌入式开发中的作用主要体现在以下几个方面: 架构优势: ARM架构基于RISC(精简指令集计算机),具有精简而高效的指令集,适合资源受限的环境。低功耗设计使得ARM处理器在移动设备和嵌入式系统中非常受欢…...

-webkit-box-orient属性丢失?
在实际项目场景当中,我们经常会遇到需要对超长文本溢出省略的场景: 我们经常会这样写—— 单行省略: overflow: hidden; //文本溢出隐藏text-overflow: ellipsis; //文本溢出显示省略号white-space: nowrap; //不换行 多行省略:…...

openKylin系统SSH服务配置结合cpolar轻松实现开放麒麟远程连接
前言 本文主要介绍如何在openKlyin系统中设置ssh连接,并结合cpolar内网穿透工具实现远程也可以ssh连接本地局域网内部署的openKlyin系统. openKylin是中国首个基于Linux 的桌面操作系统开发者平台,通过开放操作系统源代码的方式,打造具有自…...

我的世界之合成
合成(Crafting)是一种在Minecraft中获得多种方块、工具和其他资源的方法。合成时,玩家必须先把物品从物品栏移入合成方格中。22的简易合成方格可以直接在物品栏中找到,而33的合成方格需要使用工作台或合成器来打开。 目录 1合成系…...

java基于SpringBoot+Vue+uniapp微信小程序的自助点餐系统的详细设计和实现(源码+lw+部署文档+讲解等)
项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念,提供了一套默认的配置,让开发者可以更专注于业务逻辑而不是配置文件。Spring Boot 通过自动化配置和约…...
AI 编译器学习笔记之八 -- Python基础学习
2、正则表达式 re.sub 正则替换:cleaned_text re.sub(r"[^\w\s]", "", text) - CSDN文库 3、在Python中,shape 是一个用于描述数组维度的属性,通常用在NumPy数组对象上,而不是标准的列表。 【Python】解决Py…...

盘点近几年腾讯的精选面试题(c/c++研发岗)
map插入方式有几种? 1)用insert函数插入pair数据, mapStudent.insert(pair<int, string>(1, “student_one”)); 2)用insert函数插入value_type数据 mapStudent.insert(map<int, string>::value_type (1, “student_one”)); 3)在insert函…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...