前端录入音频并上传

目录

  • 纯 js 实现(有问题)
  • 使用插件 `recorder-core` (没问题)

纯 js 实现(有问题)

上传音频文件时 blob 数据中 size 一直是0,导致上传之后音频不可播放(本地录制后本地是可以播放的)在这里插入图片描述

<template><div><button v-if="!isRecording" @click="startRecording">开始录音</button><button v-else @click="stopRecording">停止录音</button><audio v-show="recordedAudio" ref="audioPlayer" controls></audio><!-- <audio src="./法老-百变酒精.mp3" controls></audio> --></div>
</template><script>
import { UploadOssFiles } from '@/api/service'export default {data() {return {isRecording: false,recordedAudio: null,mediaRecorder: null,chunks: []}},methods: {startRecording() {navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {this.isRecording = truethis.mediaRecorder = new MediaRecorder(stream)this.mediaRecorder.addEventListener('dataavailable', this.handleDataAvailable)this.mediaRecorder.start()}).catch((error) => {console.error('无法访问麦克风:', error)})},stopRecording() {this.isRecording = falsethis.mediaRecorder.stop()// this.mediaRecorder.state = 'inactive'const blob = new Blob(this.chunks, { type: 'audio/webm' })// const blob = new Blob(this.chunks, { type: 'audio/mp3' })console.log('blob----', blob)const formData = new FormData()// formData.append('audio', blob, 'recording.webm')formData.append('files', blob, 'recording.webm')// formData.append('files', blob, 'recording.mp3')// 发送音频数据到后端的API接口UploadOssFiles(formData).then((response) => {// 处理后端返回的响应}).catch((error) => {// 处理请求错误})},handleDataAvailable(event) {this.chunks.push(event.data)if (this.mediaRecorder.state === 'inactive') {this.processRecordedAudio()}},processRecordedAudio() {const blob = new Blob(this.chunks, { type: 'audio/webm' })// const blob = new Blob(this.chunks, { type: 'audio/mp3' })this.recordedAudio = URL.createObjectURL(blob)console.log('this.recordedAudio----', this.recordedAudio)this.$refs.audioPlayer.src = this.recordedAudio}}
}
</script>

代码来源

使用插件 recorder-core (没问题)

在这里插入图片描述

<template><div><!-- 按钮 --><button @click="recOpen">打开录音,请求权限</button>| <button @click="recStart">开始录音</button> | <button @click="recStop">结束录音</button> |<button @click="recPlay">本地试听</button><div style="padding-top: 5px"><!-- 波形绘制区域 --><div style="border: 1px solid #ccc; display: inline-block; vertical-align: bottom"><div ref="recwave" style="height: 100px; width: 300px" /></div></div></div>
</template><script>
import { UploadOssFiles } from '@/api/service'// 必须引入的核心
import Recorder from 'recorder-core'// 引入mp3格式支持文件;如果需要多个格式支持,把这些格式的编码引擎js文件放到后面统统引入进来即可
import 'recorder-core/src/engine/mp3'
import 'recorder-core/src/engine/mp3-engine'
// 录制wav格式的用这一句就行
// import 'recorder-core/src/engine/wav'// 可选的插件支持项,这个是波形可视化插件
import 'recorder-core/src/extensions/waveview'// ts import 提示:npm包内已自带了.d.ts声明文件(不过是any类型)export default {name: '',components: {},data() {return {rec: null,recBlob: null,wave: null}},methods: {// 申请录音权限recOpen() {// 创建录音对象this.rec = Recorder({type: 'mp3', // 录音格式,可以换成wav等其他格式sampleRate: 16000, // 录音的采样率,越大细节越丰富越细腻bitRate: 16, // 录音的比特率,越大音质越好onProcess: (buffers,powerLevel,bufferDuration,bufferSampleRate,newBufferIdx,asyncEnd) => {// 录音实时回调,大约1秒调用12次本回调// 可实时绘制波形,实时上传(发送)数据if (this.wave) this.wave.input(buffers[buffers.length - 1], powerLevel, bufferSampleRate)}})// 打开录音,获得权限this.rec.open(() => {console.log('录音已打开')if (this.$refs.recwave) {// 创建音频可视化图形绘制对象this.wave = Recorder.WaveView({ elem: this.$refs.recwave })}},(msg, isUserNotAllow) => {// 用户拒绝了录音权限,或者浏览器不支持录音console.log((isUserNotAllow ? 'UserNotAllow,' : '') + '无法录音:' + msg)})},// 开始录音recStart() {if (!this.rec) {console.error('未打开录音')return}this.rec.start()console.log('已开始录音')},// 结束录音recStop() {if (!this.rec) {console.error('未打开录音')return}this.rec.stop((blob, duration) => {// blob就是我们要的录音文件对象,可以上传,或者本地播放this.recBlob = blob// 简单利用URL生成本地文件地址,此地址只能本地使用,比如赋值给audio.src进行播放,赋值给a.href然后a.click()进行下载(a需提供download="xxx.mp3"属性)var localUrl = (window.URL || webkitURL).createObjectURL(blob)console.log('录音成功', blob, localUrl, '时长:' + duration + 'ms')this.upload(blob) // 把blob文件上传到服务器this.rec.close() // 关闭录音,释放录音资源,当然可以不释放,后面可以连续调用startthis.rec = null},(err) => {console.error('结束录音出错:' + err)this.rec.close() // 关闭录音,释放录音资源,当然可以不释放,后面可以连续调用startthis.rec = null})},// 上传录音upload(blob) {console.log('blob----', blob)// 使用FormData用multipart/form-data表单上传文件// 或者将blob文件用FileReader转成base64纯文本编码,使用普通application/x-www-form-urlencoded表单上传var form = new FormData()form.append('files', blob, 'recorder.mp3') // 和普通form表单并无二致,后端接收到upfile参数的文件,文件名为recorder.mp3UploadOssFiles(form).then((response) => {// 处理后端返回的响应}).catch((error) => {// 处理请求错误})},// 本地播放录音recPlay() {// 本地播放录音试听,可以直接用URL把blob转换成本地播放地址,用audio进行播放var localUrl = URL.createObjectURL(this.recBlob)var audio = document.createElement('audio')audio.controls = truedocument.body.appendChild(audio)audio.src = localUrlaudio.play() // 这样就能播放了// 注意不用了时需要revokeObjectURL,否则霸占内存setTimeout(function () {URL.revokeObjectURL(audio.src)}, 5000)}}
}
</script><style lang='scss' scoped>
</style>

代码来源

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【基于MBD开发模式的matlab持续集成(一)】

基于MBD开发模式的matlab持续集成 引言 或许是感受到行业内卷的愈加激烈&#xff0c;在传统制造和高新技术相结合的新能源领域对软件工程开发的要求也愈加提高&#xff0c;尤其在互联网已经大行 其道的敏捷开发&#xff0c;便顺其自然的被新能源的老板们所看重。 概述 本文…

浅述数据中心供配电系统解决方案及产品选型

安科瑞 华楠 【摘 要】现如今&#xff0c;社会主要领域已从对单个设备的关注转化为对于系统解决方案的关注&#xff0c;数据中心的供应商们也想尽办法去满足所面对的各方面需求。基于此&#xff0c;主要提出了云计算数据中心供配电解决方案&#xff0c;同时还对数据中心供配电…

系统架构设计师(第二版)学习笔记----信息安全系统及信息安全技术

【原文链接】系统架构设计师&#xff08;第二版&#xff09;学习笔记----信息加解密技术 文章目录 一、信息安全系统的组成框架1.1 信息安全系统组成框架1.2 信息安全系统技术内容1.3 常用的基础安全设备1.4 网络安全技术内容1.5 操作系统安全内容1.6 操作系统安全机制1.7 数据…

I Pa?sWorD

2023icpc网络赛第一场 I 题意&#xff1a;题目给出只包含大小写字母&#xff0c;数字以及?的字符串&#xff0c;对于每一个小写字母&#xff0c;这一位字符既有可能是该小写字母&#xff0c;也有可能是该小写字母的对应大写字母&#xff0c;也就是该位的字符有两种可能&#x…

基于Java+SpringBoot+Vue的旧物置换网站设计和实现

基于JavaSpringBootVue的旧物置换网站设计和实现 源码传送入口前言主要技术系统设计功能截图数据库设计代码论文目录订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码传送入口 前言 摘 要 随着时代在一步一步在进步&#xff0c;旧物也成人们的烦恼&#xff0c;…

多线程的学习上篇

座右铭: 天行健&#xff0c;君子以自强不息;地势坤&#xff0c;君子以厚德载物. 引入进程这个概念的目的 引入进程这个概念,最主要的目的,是为了解决“并发编程"这样的问题. 这是因为CPU进入了多核心的时代 要想进一步提高程序的执行速度,就需要充分的利用CPU 的多核资源…

《PostgreSQL中的JSON处理:技巧与应用》

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f405;&#x1f43e;猫头虎建议程序员必备技术栈一览表&#x1f4d6;&#xff1a; &#x1f6e0;️ 全栈技术 Full Stack: &#x1f4da…

为什么qt设置了utf-8 bom 格式后还是有乱码

有乱码 void SingleApplication::_showInstanceRunningDialog() {// 创建一个提示窗口QMessageBox msgBox;msgBox.setIcon(QMessageBox::Information);msgBox.setWindowTitle("应用已运行");msgBox.setText("应用程序已经在运行中。");msgBox.setStandardB…

【深度学习实验】线性模型(二):使用NumPy实现线性模型:梯度下降法

目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 三、实验内容 0. 导入库 1. 初始化参数 2. 线性模型 linear_model 3. 损失函数loss_function 4. 梯度计算函数compute_gradients 5. 梯度下降函数gradient_descent 6. 调用函数 一、实验介绍 使用Nu…

RocketMQ 发送顺序消息

文章目录 顺序消息应用场景消息组&#xff08;MessageGroup&#xff09;顺序性生产的顺序性MQ 存储的顺序性消费的顺序性 rocketmq-client-java 示例&#xff08;gRPC 协议&#xff09;1. 创建 FIFO 主题生产者代码消费者代码解决办法解决后执行结果 rocketmq-client 示例&…

【结构型】代理模式(Proxy)

目录 代理模式(Proxy)适用场景代理模式实例代码&#xff08;Java&#xff09; 代理模式(Proxy) 为其他对象提供一种代理以控制对这个对象的访问。Proxy 模式适用于在需要比较通用和复杂的对象指针代替简单的指针的时候。 适用场景 远程代理 (Remote Proxy) 为一个对象在不同…

《ADS2011射频电路设计与仿真实例》功率放大器设计的输入输出匹配

徐兴福这本书的6.6 Smith圆图匹配这一节中具体匹配时&#xff0c;直接给出了电容与串联微带的值&#xff0c;没有给出推导过程&#xff0c;我一开始以为是省略了详细推导过程&#xff0c;后来发现好像基本上是可以随便自己设的。以输入匹配&#xff08;书本6.6.4输入匹配电路的…

Modbus RTU(Remote Terminal Unit)与RS-485协议介绍(主站设备(Master)、从站设备(Slave))

文章目录 Modbus RTU与RS-485协议介绍一、引言二、Modbus RTU 协议介绍2.1 Modbus RTU 协议简介2.2 Modbus RTU 协议帧结构主站设备、从站设备与从站设备地址2.3 Modbus RTU 协议举例 三、RS-485 协议介绍3.1 RS-485 协议简介3.2 RS-485 物理连接方式3.3 RS-485 与 Modbus RTU …

LeetCode-热题100-笔记-day31

105. 从前序与中序遍历序列构造二叉树https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c…

全国职业技能大赛云计算--高职组赛题卷④(容器云)

全国职业技能大赛云计算--高职组赛题卷④&#xff08;容器云&#xff09; 第二场次题目&#xff1a;容器云平台部署与运维任务1 Docker CE及私有仓库安装任务&#xff08;5分&#xff09;任务2 基于容器的web应用系统部署任务&#xff08;15分&#xff09;任务3 基于容器的持续…

企业架构LNMP学习笔记61

Nginx作为tomcat的前段反向代理&#xff1a; 在实际业务环境中&#xff0c;用户是直接通过域名访问&#xff0c;基于协议一般是http、https等。默认tomcat运行在8080端口。一般会通过前端服务器反向代理到后端的tomcat的方式&#xff0c;来实现用户可以通过域名访问tomcat的we…

2023全新TwoNav开源网址导航系统源码 | 去授权版

2023全新TwoNav开源网址导航系统源码 已过授权 所有功能可用 测试环境&#xff1a;NginxPHP7.4MySQL5.6 一款开源的书签导航管理程序&#xff0c;界面简洁&#xff0c;安装简单&#xff0c;使用方便&#xff0c;基础功能免费。 TwoNav可帮助你将浏览器书签集中式管理&#…

Java面试八股文宝典:初识数据结构-数组的应用扩展之HashMap

前言 除了基本的数组&#xff0c;还有其他高级的数据结构&#xff0c;用于更复杂的数据存储和检索需求。其中&#xff0c;HashMap 是 Java 集合框架中的一部分&#xff0c;用于存储键值对&#xff08;key-value pairs&#xff09;。HashMap 允许我们通过键来快速查找和检索值&…

【数据结构】树的存储结构;树的遍历;哈夫曼树;并查集

欢~迎~光~临~^_^ 目录 1、树的存储结构 1.1双亲表示法 1.2孩子表示法 1.3孩子兄弟表示法 2、树与二叉树的转换 3、树和森林的遍历 3.1树的遍历 3.1.1先根遍历 3.1.2后根遍历 3.2森林的遍历 3.2.1先序遍历森林 3.2.2中序遍历森林 4、树与二叉树的应用 4.1哈夫曼树…