Vue 使用 js-audio-recorder 实现录制、播放、下载音频

Vue 使用 js-audio-recorder 实现录制、播放、下载 PCM 数据

  • Vue 使用 js-audio-recorder 实现录制、播放、下载 PCM 数据
    • js-audio-recorder 简介
    • Vue 项目创建
    • 下载相关依赖
    • 主界面设计
    • 设置路由
    • 组件及页面设计
    • 项目启动
    • 源码下载

Vue 使用 js-audio-recorder 实现录制、播放、下载 PCM 数据

js-audio-recorder 简介

纯 js 实现浏览器端录音。

支持功能:

  • 支持录音,暂停,恢复,和录音播放。
  • 支持音频数据的压缩,支持单双通道录音。
  • 支持录音时长、录音大小的显示。
  • 支持边录边转(播放) 后续支持。
  • 支持导出录音文件,格式为 pcm 或 wav。
  • 支持录音波形显示,可自己定制。

项目地址:https://github.com/2fps/recorder

演示地址:https://recorder.zhuyuntao.cn/

Vue 项目创建

按下面的步骤创建 Vue 项目:

在这里插入图片描述

然后 cd 到 vue_recorder 下,终端输入 npm run serve,出现下面输出说明成功了:

在这里插入图片描述

浏览器打开 http://localhost:8080/:

在这里插入图片描述

下载相关依赖

在项目中我们会用到 js-audio-plugin 以及 Element ,所以需要下载相关依赖并在 main.js 中引入。

安装 js-audio-plugin 指令:npm i js-audio-recorder

安装 Element 指令:npm install element-ui

安装好以后,在 main.js 添加:

// 引入 element-ui
import ElementUI from 'element-ui';
// element-ui 的 css 样式要单独引入
import 'element-ui/lib/theme-chalk/index.css';Vue.use(ElementUI);

主界面设计

主页面的设计在根组件 App.vue 中进行,主要负责一些全局内容的显示。

<template><div id="app"><!-- <nav><router-link to="/">Recorder</router-link> |</nav> --><router-view /></div>
</template><style lang="scss">
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;
}nav {padding: 30px;a {font-weight: bold;color: #2c3e50;&.router-link-exact-active {color: #42b983;}}
}
</style>

设置路由

在 router 目录下的 index.js 中设置路由:

import Vue from 'vue'
import VueRouter from 'vue-router'
import RecorderView from '../views/RecorderView.vue'Vue.use(VueRouter)const routes = [{path: '/',name: 'recorder',component: RecorderView},
]const router = new VueRouter({routes
})export default router

组件及页面设计

在 compoments 文件夹下新建 MyRecorder.vue:

<template><div style="padding: 20px;"><h1>{{ msg }}</h1><h3>录音上传</h3><div style="font-size:14px"><h3>录音时长:{{ recorder && recorder.duration.toFixed(4) }}</h3><br /><el-button type="primary" @click="handleStart">开始录音</el-button><el-button type="info" @click="handlePause">暂停录音</el-button><el-button type="success" @click="handleResume">继续录音</el-button><el-button type="warning" @click="handleStop">停止录音</el-button><br /><br /><h3>播放时长:{{ recorder && (playTime > recorder.duration ? recorder.duration.toFixed(4) : playTime.toFixed(4)) }}</h3><br /><el-button type="primary" @click="handlePlay">播放录音</el-button><el-button type="info" @click="handlePausePlay">暂停播放</el-button><el-button type="success" @click="handleResumePlay">继续播放</el-button><el-button type="warning" @click="handleStopPlay">停止播放</el-button><el-button type="error" @click="handleDestroy">销毁录音</el-button><el-button type="primary" @click="downloadPCM">下载PCM数据</el-button><el-button type="primary" @click="downloadWAV">下载WAV数据</el-button><el-button type="primary" @click="uploadRecord">上传</el-button></div></div>
</template><script>
import Recorder from 'js-audio-recorder'
// import axios from 'axios'export default {name: 'MyRecorder',props: {msg: String},data() {return {recorder: null,playTime: 0,timer: null,src: null}},created() {this.recorder = new Recorder({sampleBits: 16, // 采样位数,支持 8 或 16,默认是 16sampleRate: 16000, // 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,Chrome 是 48000numChannels: 1, // 声道数,支持 1 或 2, 默认是 1})},methods: {// 开始录音handleStart() {this.recorder = new Recorder()Recorder.getPermission().then(() => {console.log('开始录音')this.recorder.start() // 开始录音}, (error) => {this.$message({message: '请先允许该网页使用麦克风',type: 'info'})console.log(`${error.name} : ${error.message}`)})},handlePause() {console.log('暂停录音')this.recorder.pause() // 暂停录音},handleResume() {console.log('恢复录音')this.recorder.resume() // 恢复录音},handleStop() {console.log('停止录音')this.recorder.stop() // 停止录音},handlePlay() {console.log('播放录音')console.log(this.recorder)this.recorder.play() // 播放录音// 播放时长this.timer = setInterval(() => {try {this.playTime = this.recorder.getPlayTime()} catch (error) {this.timer = null}}, 100)},handlePausePlay() {console.log('暂停播放')this.recorder.pausePlay() // 暂停播放// 播放时长this.playTime = this.recorder.getPlayTime()this.time = null},handleResumePlay() {console.log('恢复播放')this.recorder.resumePlay() // 恢复播放// 播放时长this.timer = setInterval(() => {try {this.playTime = this.recorder.getPlayTime()} catch (error) {this.timer = null}}, 100)},handleStopPlay() {console.log('停止播放')this.recorder.stopPlay() // 停止播放// 播放时长this.playTime = this.recorder.getPlayTime()this.timer = null},handleDestroy() {console.log('销毁实例')this.recorder.destroy() // 销毁实例this.timer = null},downloadPCM() {console.log('下载PCM格式数据')// 注:使用该方法会默认调用 stop() 方法this.recorder.downloadPCM('record-pcm')},downloadWAV() {console.log('下载WAV格式数据')// 注:使用该方法会默认调用 stop() 方法this.recorder.downloadWAV('record-wav')},uploadRecord() {if (this.recorder == null || this.recorder.duration === 0) {this.$message({message: '请先录音',type: 'error'})return false}this.recorder.pause() // 暂停录音this.timer = nullconsole.log('上传录音') // 上传录音const formData = new FormData()const blob = this.recorder.getPCMBlob() // 获取 pcm 格式音频数据// 此处获取到 blob 对象后需要设置 fileName 满足项目上传需求,这里选择直接把 blob 作为 file 塞入 formDataconst fileOfBlob = new File([blob], new Date().getTime() + '.pcm')formData.append('file', fileOfBlob)const url = window.URL.createObjectURL(fileOfBlob)this.src = url// const axios = require('axios')// axios.post(url, formData).then(res => {//   console.log(res.data.data[0].url)// })}}
}
</script>

在 views 文件夹下新建 RecorderView.vue:

<template><div class="home"><!-- <imgalt="Vue logo"src="../assets/logo.png"> --><MyRecorder msg="Welcome to Vue Recorder" /></div>
</template><script>
// @ is an alias to /src
import MyRecorder from '@/components/MyRecorder.vue'export default {name: 'RecorderView',components: {MyRecorder}
}
</script>

项目启动

在终端中输入指令:npm run serve

可以看到如下界面,说明项目成功运行:

在这里插入图片描述

根据提示访问本地地址 http://localhost:8080/。

在这里插入图片描述

经过测试,页面正常排布,所有功能都正常使用(除了上传功能)。

源码下载

GitHub:

CSDN:vue-recorder.zip

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

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

相关文章

FPGA时序分析与时序约束(二)——时钟约束

目录 一、时序约束的步骤 二、时序网表和路径 2.1 时序网表 2.2 时序路径 三、时序约束的方式 三、时钟约束 3.1 主时钟约束 3.2 虚拟时钟约束 3.3 衍生时钟约束 3.4 时钟组约束 3.5 时钟特性约束 3.6 时钟延时约束 一、时序约束的步骤 上一章了解了时序分析和约束…

IDEA shorten command line介绍和JAR manifest 导致mybatis找不到接口类处理

如果类路径太长&#xff0c;或者有许多VM参数&#xff0c;程序就无法启动。原因是大多数操作系统都有命令行长度限制。在这种情况下&#xff0c;IntelliJIDEA将试图缩短类路径。最好选中 classpath file模式。 shorten command line 选项提供三种选项缩短类路径。 none&#x…

破局:国内母婴市场“红利减退”,母婴店如何拓客引流裂变?

破局&#xff1a;国内母婴市场“红利减退”&#xff0c;母婴店如何拓客引流裂变&#xff1f; 背景&#xff1a;中国母婴市场近年来人口出生率一直在恒定范围值&#xff0c;国家也在鼓励优生、多生政策&#xff0c;并且随着互联网的高速发展&#xff0c;人均可支配收入也在增加&…

你是无醇葡萄酒的爱好者吗?

不含酒精的蒸馏酒和起泡酒正在流行&#xff0c;尽管它们是葡萄酒市场中最小的细分市场之一&#xff0c;但需求和供应都在稳步增长。这是因为&#xff0c;和啤酒一样&#xff0c;消费者越来越多地询问无醇葡萄酒。 来自云仓酒庄品牌雷盛红酒分享不含酒精的酒好喝吗&#xff1f;尼…

单通道 6 阶高清视频滤波驱动 MS1631

MS1631 是一个单通道视频缓冲器&#xff0c;它内部集成 6dB 增益的轨到轨输出驱动器和 6 阶输出重建 滤波器。MS1631 的-3dB 带宽典型值为 72MHz&#xff0c;压摆率为 400V/us。MS1631 比无源 LC 滤波器与外加 驱动的解决方案能提供更好的图像质量。它单电源供电范围为2.5V 到…

从零开始学习Web自动化:用Python和Selenium实现网站登录功能!

Web自动化测试实战项目&#xff1a;使用Selenium和Python完成网站登录功能的自动化测试 本文将介绍如何使用Selenium和Python编写自动化测试脚本&#xff0c;对网站登录功能进行测试。我们将通过模拟用户在网站上输入用户名和密码&#xff0c;并点击登录按钮&#xff0c;来检验…

flink yarn-session 启动失败retrying connect to server 0.0.0.0/0.0.0.0:8032

原因分析&#xff0c;启动yarn-session.sh&#xff0c;会向resourcemanager的端口8032发起请求&#xff1a; 但是一直无法请求到8032端口&#xff0c;触发重试机制会不断尝试 备注&#xff1a;此问题出现时&#xff0c;我的环境ambari部署的HA 高可用hadoop&#xff0c;三个节点…

电力智能化管理系统

电力智能化管理系统是一种综合性的电力管理解决方案&#xff0c;它利用先进的信息技术、自动化技术和智能控制技术&#xff0c;实现对电力系统的全面管理和优化。 该系统依托电易云-智慧电力物联网&#xff0c;它的主要功能包括实时监测、故障预警、自动巡检、设备管理、数据分…

【Unity 实用工具篇】✨| I2 Localization 实现本地化及多种语言切换,快速上手

前言【Unity 实用工具篇】| I2 Localization 实现本地化及多种语言切换,快速上手一、多语言本地化插件 I2 Localization1.1 介绍1.2 效果展示1.3 使用说明及下载二、插件资源简单介绍三、通过示例快速上手3.1 添加 Languages语种3.2 添加 Term资源3.3 静

Java版直播商城规划:电商源码、小程序、三级分销与免 费搭建全攻略

【saas云平台】打造全行业全渠道全场景的saas产品&#xff0c;为经营场景提供一体化解决方案&#xff1b;门店经营区域化、网店经营一体化&#xff0c;本地化、全方位、一站式服务&#xff0c;为多门店提供统一运营解决方案&#xff1b;提供丰富多样的营销玩法覆盖所有经营场景…

在Next.js渲染Markdown竟然如此简单

Next.js 作为一款开箱即用的 React 框架&#xff0c;因其优秀的服务器渲染能力和灵活的配置方式&#xff0c;已经吸引了大量的开发者。同时&#xff0c;Markdown 作为一种轻量级的标记语言&#xff0c;以其简洁的语法和强大的功能&#xff0c;已经成为了写作的首选工具。那么&a…

SE-Net:Squeeze-and-Excitation Networks(CVPR2018)

文章目录 AbstractIntroduction表征的重要性以前的方向本文提出 Related WorkDeeper ArchitectureAlgorithmic Architecture SearchAttention and gating mechanisms Squeeze-and-Excitation BlocksSqueeze: Global Information EmbeddingExcitation: Adaptive RecalibrationIn…

2023长三角(芜湖)人工智能数字生态峰会成功召开!

聚焦当下&#xff0c;共议数字时代发展&#xff1b;瞩目未来&#xff0c;共谋数字生态蓝图。12月11日&#xff0c;2023长三角&#xff08;芜湖&#xff09;人工智能数字生态峰会暨2023长三角&#xff08;芜湖&#xff09;人工智能视觉算法大赛颁奖典礼在芜湖宜居国际博览中心盛…

如何使用AnyTXT Searcher实现远程办公速查异地电脑文件提升工作效率

如何使用AnyTXT Searcher实现远程办公速查异地电脑文件提升工作效率 前言1. AnyTXT Searcher1.1 下载安装AnyTXT Searcher 2. 下载安装注册cpolar3. AnyTXT Searcher设置和操作3.1 AnyTXT结合cpolar—公网访问搜索神器3.2 公网访问测试 4. 固定连接公网地址 前言 你是否遇到过…

飞速(FS)100G ZR4 光模块80km长距离传输

如今&#xff0c;100G QSFP28光模块已经被广泛部署在100m到40km的范围内。然而&#xff0c;传统的100G QSFP28模块面临一个挑战&#xff0c;因为它们的设计仅限于不超过40km的距离。超出此范围&#xff0c;色散、光衰减等问题就会增加&#xff0c;导致信噪比&#xff08;SNR&am…

八股文打卡day3——计算机网络(3)

面试题&#xff1a;请讲一下四次挥手的过程&#xff1f; 1.客户端发送FIN数据包给服务器&#xff0c;表示客户端不再发送数据给服务器&#xff0c;想要断开这个方向的连接。 2.服务器收到客户端的FIN包之后&#xff0c;发送ACK包给客户端&#xff0c;对收到的FIN包进行收到确认…

13. 从零用Rust编写正反向代理, HTTP中的压缩gzip,deflate,brotli算法

wmproxy wmproxy是由Rust编写&#xff0c;已实现http/https代理&#xff0c;socks5代理&#xff0c; 反向代理&#xff0c;静态文件服务器&#xff0c;内网穿透&#xff0c;配置热更新等&#xff0c; 后续将实现websocket代理等&#xff0c;同时会将实现过程分享出来&#xff…

构建智慧储能物联网,4G工业路由器远程监测在线管理

物联网技术的发展为智慧储能管理带来了革命性的变化。其中&#xff0c;4G工业路由器IR5000通过丰富的连接能力如串口RS485/232或网口的方式&#xff0c;实现了与储能现场各设备的连接&#xff0c;包括电表、电能检测器、防孤岛装置、BMS电池管理系统、监控服务器、储能控制器、…

WEB渗透—PHP反序列化(五)

Web渗透—PHP反序列化 课程学习分享&#xff08;课程非本人制作&#xff0c;仅提供学习分享&#xff09; 靶场下载地址&#xff1a;GitHub - mcc0624/php_ser_Class: php反序列化靶场课程&#xff0c;基于课程制作的靶场 课程地址&#xff1a;PHP反序列化漏洞学习_哔哩…

xcrun: error: invalid active developer path

macOS升级完成后出现 xcrun: error: invalid active developer path问题。 xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun这是由于 Xcode command line tools 丢…