前端录入音频并上传

目录

  • 纯 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.hqwc.cn/news/115853.html

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

相关文章

代码随想录算法训练营 动态规划part06

一、完全背包 卡哥的总结&#xff0c;还挺全代码随想录 (programmercarl.com) 二、零钱兑换 II 518. 零钱兑换 II - 力扣&#xff08;LeetCode&#xff09; 被选物品之间不需要满足特定关系&#xff0c;只需要选择物品&#xff0c;以达到「全局最优」或者「特定状态」即可。 …

人工智能机器学习-飞桨神经网络与深度学习

飞桨神经网络与深度学习-机器学习 目录 飞桨神经网络与深度学习-机器学习 1.机器学习概述 2.机器学习实践五要素 2.1.数据 2.2.模型 2.3.学习准则 2.4.优化算法 2.5.评估标准 3.实现简单的线性回归模型 3.1.数据集构建 3.2.模型构建 3.3.损失函数 3.4.模型优化 3…

【FAQ】安防监控系统/视频云存储/监控平台EasyCVR服务器解释器出现变更该如何修改?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

Golang代码漏洞扫描工具介绍——trivy

Golang代码漏洞扫描工具介绍——trivy Golang作为一款近年来最火热的服务端语言之一&#xff0c;深受广大程序员的喜爱&#xff0c;笔者最近也在用&#xff0c;特别是高并发的场景下&#xff0c;golang易用性的优势十分明显&#xff0c;但笔者这次想要介绍的并不是golang本身&a…

Learn Prompt-提供示例

目前我们与 ChatGPT 交流的主要形式是文字。提示除了指令问题的形式外&#xff0c;还可以包含例子。特别是当我们需要具体的输出时&#xff0c;提供例子可以省去我们对具体任务的解释&#xff0c;帮助ChatGPT更好地理解我们的确切需求&#xff0c;从而提供更准确&#xff0c;更…

SQL死锁进程内容查询语句

1.方式1 SELECT object_name(A.resource_associated_entity_id) as TABLENAME, A.request_session_id AS SPID,DB_NAME(B.dbid) AS DBName,B.blocked,B.dbid,B.program_name,B.waitresource,B.lastwaittype,B.loginame,B.hostname,B.login_time,B.last_batch--,B.* FROM sy…

重新认识架构—不只是软件设计

前言 什么是架构&#xff1f; 通常情况下&#xff0c;人们对架构的认知仅限于在软件工程中的定义&#xff1a;架构主要指软件系统的结构设计&#xff0c;比如常见的SOLID准则、DDD架构。一个良好的软件架构可以帮助团队更有效地进行软件开发&#xff0c;降低维护成本&#xff0…

FPGA——UART串口通信

文章目录 前言一、UART通信协议1.1 通信格式2.2 MSB或LSB2.3 奇偶校验位2.4 UART传输速率 二、UART通信回环2.1 系统架构设计2.2 fsm_key2.3 baud2.4 sel_seg2.5 fifo2.6 uart_rx2.7 uart_tx2.8 top_uart2.9 发送模块时序分析2.10 接收模块的时序分析2.11 FIFO控制模块时序分析…

C语言字符和字符串函数(2)

大家好&#xff0c;我今天继续来给大家分享C语言中的字符和字符串函数。 目录 ** 1.字符分类函数 2.memcpy 3.memmove 4.memcmp** 1.字符分类函数 islower判断字母小写函数 int main() {char ch w;if (islower(ch)){printf("小写\n");}else{printf("非小写\…

VR禁毒教育 | 毒品认知VR虚拟仿真科普:提高青少年抵制毒品的意识和能力

虚拟现实&#xff08;VR&#xff09;是一种让人们在仿真环境中体验、交互和操纵虚拟物体的技术&#xff0c;这种技术在许多领域都有广泛的应用&#xff0c;包括教育。特别是在毒品预防教育中&#xff0c;VR教育课件可以让学生以更直观、生动的方式了解各种毒品及其危害&#xf…

JCEF中js与java交互、js与java相互调用

jcef中js与java相互调用&#xff0c;java与js相互调用&#xff0c;chrome与java相互调用&#xff0c;java与chrome相互调用、jcef与java相互调用 前提&#xff1a;https://blog.csdn.net/weixin_44480167/article/details/133170970&#xff08;java内嵌浏览器CEF-JAVA、jcef、…

Mybatis常见面试题总结

梳理面试过程中Mybatis相关的常见问题。为保证知识点覆盖&#xff0c;参考了《Mybatis从入门到精通》、《深入浅出Mybatis技术原理与实战》、《Mybatis技术内幕》等书籍。 Mybatis 简介 Mybatis 是一款优秀的持久层框架(ORM框架)&#xff0c;它支持自定义SQL、存储过程以及高…