前言:

因为业务需要,现在将整理的录音功能资料记录下,使用插件js-audio-recorder

目录:

实现效果:可得到三种录音数据,pcm,wav,mp3 等

官方api入口:点我(网不好的童鞋可以看最下面的api截图)

官方案例入口:点我

官方源码git入口:点我

实现步骤:

一:安装插件 js-audio-recorder

二:安装将格式转换为mp3的插件 lamejs

三:附上实现源码:

到这里,代码就结束了,上面每个方法都有很详细的注释,就不累赘了

整理api:(有代理的可以看官网,这里是摘取官网的api)

1,使用

安装

npm 方式

script 标签方式

2,属性

实例初始化

sampleBits

sampleRate

numChannels

compiling

实例属性

duration

fileSize

3,操作

start()

pause()

resume()

stop()

play()

getPlayTime()

pausePlay()

resumePlay()

stopPlay()

destroy()

音频数据

录音结束,获取取录音数据

录音结束,下载录音文件

录音中,获取录音数据

录音波形显示

播放外部

Player.play(blob)

其他

录音权限

getPermission()

4,Event

onprocess(duration)

onprogress(duration)

onplay

onpauseplay

onresumeplay

onstopplay

onplayend

5,应用

语音识别

6,Player

Player 播放类

Player.play([arraybuffer])

Player.pausePlay()

Player.resumePlay()

Player.stopPlay()

Player.addPlayEnd(fn)

Player.getPlayTime()

Player.getAnalyseData()

7,其他音频格式

MP3

安装lamejs


实现效果:可得到三种录音数据,pcm,wav,mp3 等

官方api入口:点我(网不好的童鞋可以看最下面的api截图)

官方案例入口:点我

官方源码git入口:点我

实现步骤:

一:安装插件 js-audio-recorder

cnpm i js-audio-recorder --s

二:安装将格式转换为mp3的插件 lamejs

cnpm install lamejs --s

三:附上实现源码:

提示:慎用自身的这个监听事件,可以拿到数据,但是每秒拿到的数据非常多

<template><div class="home" style="margin:1vw;"><Button type="success" @click="getPermission()" style="margin:1vw;">获取麦克风权限</Button><br/><Button type="info" @click="startRecorder()"  style="margin:1vw;">开始录音</Button><Button type="info" @click="resumeRecorder()" style="margin:1vw;">继续录音</Button><Button type="info" @click="pauseRecorder()" style="margin:1vw;">暂停录音</Button><Button type="info" @click="stopRecorder()" style="margin:1vw;">结束录音</Button><br/><Button type="success" @click="playRecorder()" style="margin:1vw;">录音播放</Button><Button type="success" @click="pausePlayRecorder()" style="margin:1vw;">暂停录音播放</Button><Button type="success" @click="resumePlayRecorder()" style="margin:1vw;">恢复录音播放</Button><Button type="success" @click="stopPlayRecorder()" style="margin:1vw;">停止录音播放</Button><br/><Button type="info" @click="getRecorder()" style="margin:1vw;">获取录音信息</Button><Button type="info" @click="downPCM()" style="margin:1vw;">下载PCM</Button><Button type="info" @click="downWAV()" style="margin:1vw;">下载WAV</Button><Button type="info" @click="getMp3Data()" style="margin:1vw;">下载MP3</Button><br/><Button type="error" @click="destroyRecorder()" style="margin:1vw;">销毁录音</Button><br/><div style="width:100%;height:200px;border:1px solid red;"><canvas id="canvas"></canvas><span style="padding: 0 10%;"></span><canvas id="playChart"></canvas></div></div>
</template><script>import Recorder from 'js-audio-recorder'const lamejs = require('lamejs')const recorder = new Recorder({sampleBits: 16,                 // 采样位数,支持 8 或 16,默认是16sampleRate: 48000,              // 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,我的chrome是48000numChannels: 1,                 // 声道,支持 1 或 2, 默认是1// compiling: false,(0.x版本中生效,1.x增加中)  // 是否边录边转换,默认是false})// 绑定事件-打印的是当前录音数据recorder.onprogress = function(params) {// console.log('--------------START---------------')// console.log('录音时长(秒)', params.duration);// console.log('录音大小(字节)', params.fileSize);// console.log('录音音量百分比(%)', params.vol);// console.log('当前录音的总数据([DataView, DataView...])', params.data);// console.log('--------------END---------------')}export default {name: 'home',data () {return {//波浪图-录音drawRecordId:null,oCanvas : null,ctx : null,//波浪图-播放drawPlayId:null,pCanvas : null,pCtx : null,}},mounted(){this.startCanvas();},methods: {/*** 波浪图配置* */startCanvas(){//录音波浪this.oCanvas = document.getElementById('canvas');this.ctx = this.oCanvas.getContext("2d");//播放波浪this.pCanvas = document.getElementById('playChart');this.pCtx = this.pCanvas.getContext("2d");},/***  录音的具体操作功能* */// 开始录音startRecorder () {recorder.start().then(() => {this.drawRecord();//开始绘制图片}, (error) => {// 出错了console.log(`${error.name} : ${error.message}`);});},// 继续录音resumeRecorder () {recorder.resume()},// 暂停录音pauseRecorder () {recorder.pause();this.drawRecordId && cancelAnimationFrame(this.drawRecordId);this.drawRecordId = null;},// 结束录音stopRecorder () {recorder.stop()this.drawRecordId && cancelAnimationFrame(this.drawRecordId);this.drawRecordId = null;},// 录音播放playRecorder () {recorder.play();this.drawPlay();//绘制波浪图},// 暂停录音播放pausePlayRecorder () {recorder.pausePlay()},// 恢复录音播放resumePlayRecorder () {recorder.resumePlay();this.drawPlay();//绘制波浪图},// 停止录音播放stopPlayRecorder () {recorder.stopPlay();},// 销毁录音destroyRecorder () {recorder.destroy().then(function() {recorder = null;this.drawRecordId && cancelAnimationFrame(this.drawRecordId);this.drawRecordId = null;});},/***  获取录音文件* */getRecorder(){let toltime = recorder.duration;//录音总时长let fileSize = recorder.fileSize;//录音总大小//录音结束,获取取录音数据let PCMBlob = recorder.getPCMBlob();//获取 PCM 数据let wav = recorder.getWAVBlob();//获取 WAV 数据let channel = recorder.getChannelData();//获取左声道和右声道音频数据},/***  下载录音文件* *///下载pcmdownPCM(){//这里传参进去的时文件名recorder.downloadPCM('新文件');},//下载wavdownWAV(){//这里传参进去的时文件名recorder.downloadWAV('新文件');},/***  获取麦克风权限* */getPermission(){Recorder.getPermission().then(() => {this.$Message.success('获取权限成功')}, (error) => {console.log(`${error.name} : ${error.message}`);});},/*** 文件格式转换 wav-map3* */getMp3Data(){const mp3Blob = this.convertToMp3(recorder.getWAV());recorder.download(mp3Blob, 'recorder', 'mp3');},convertToMp3(wavDataView) {// 获取wav头信息const wav = lamejs.WavHeader.readHeader(wavDataView); // 此处其实可以不用去读wav头信息,毕竟有对应的config配置const { channels, sampleRate } = wav;const mp3enc = new lamejs.Mp3Encoder(channels, sampleRate, 128);// 获取左右通道数据const result = recorder.getChannelData()const buffer = [];const leftData = result.left && new Int16Array(result.left.buffer, 0, result.left.byteLength / 2);const rightData = result.right && new Int16Array(result.right.buffer, 0, result.right.byteLength / 2);const remaining = leftData.length + (rightData ? rightData.length : 0);const maxSamples = 1152;for (let i = 0; i < remaining; i += maxSamples) {const left = leftData.subarray(i, i + maxSamples);let right = null;let mp3buf = null;if (channels === 2) {right = rightData.subarray(i, i + maxSamples);mp3buf = mp3enc.encodeBuffer(left, right);} else {mp3buf = mp3enc.encodeBuffer(left);}if (mp3buf.length > 0) {buffer.push(mp3buf);}}const enc = mp3enc.flush();if (enc.length > 0) {buffer.push(enc);}return new Blob(buffer, { type: 'audio/mp3' });},/*** 绘制波浪图-录音* */drawRecord () {// 用requestAnimationFrame稳定60fps绘制this.drawRecordId = requestAnimationFrame(this.drawRecord);// 实时获取音频大小数据let dataArray = recorder.getRecordAnalyseData(),bufferLength = dataArray.length;// 填充背景色this.ctx.fillStyle = 'rgb(200, 200, 200)';this.ctx.fillRect(0, 0, this.oCanvas.width, this.oCanvas.height);// 设定波形绘制颜色this.ctx.lineWidth = 2;this.ctx.strokeStyle = 'rgb(0, 0, 0)';this.ctx.beginPath();var sliceWidth = this.oCanvas.width * 1.0 / bufferLength, // 一个点占多少位置,共有bufferLength个点要绘制x = 0;          // 绘制点的x轴位置for (var i = 0; i < bufferLength; i++) {var v = dataArray[i] / 128.0;var y = v * this.oCanvas.height / 2;if (i === 0) {// 第一个点this.ctx.moveTo(x, y);} else {// 剩余的点this.ctx.lineTo(x, y);}// 依次平移,绘制所有点x += sliceWidth;}this.ctx.lineTo(this.oCanvas.width, this.oCanvas.height / 2);this.ctx.stroke();},/*** 绘制波浪图-播放* */drawPlay () {// 用requestAnimationFrame稳定60fps绘制this.drawPlayId = requestAnimationFrame(this.drawPlay);// 实时获取音频大小数据let dataArray = recorder.getPlayAnalyseData(),bufferLength = dataArray.length;// 填充背景色this.pCtx.fillStyle = 'rgb(200, 200, 200)';this.pCtx.fillRect(0, 0, this.pCanvas.width, this.pCanvas.height);// 设定波形绘制颜色this.pCtx.lineWidth = 2;this.pCtx.strokeStyle = 'rgb(0, 0, 0)';this.pCtx.beginPath();var sliceWidth = this.pCanvas.width * 1.0 / bufferLength, // 一个点占多少位置,共有bufferLength个点要绘制x = 0;          // 绘制点的x轴位置for (var i = 0; i < bufferLength; i++) {var v = dataArray[i] / 128.0;var y = v * this.pCanvas.height / 2;if (i === 0) {// 第一个点this.pCtx.moveTo(x, y);} else {// 剩余的点this.pCtx.lineTo(x, y);}// 依次平移,绘制所有点x += sliceWidth;}this.pCtx.lineTo(this.pCanvas.width, this.pCanvas.height / 2);this.pCtx.stroke();}},}
</script><style lang='less' scoped></style>

到这里,代码就结束了,上面每个方法都有很详细的注释,就不累赘了

整理api:(有代理的可以看官网,这里是摘取官网的api)

1,使用

安装

npm 方式

推荐使用npm安装的方式:

安装:

npm i js-audio-recorder
Copy

调用:

import Recorder from 'js-audio-recorder';let recorder = new Recorder();
Copy

script 标签方式

<script type="text/javascript" src="./dist/recorder.js"></script>let recorder = new Recorder();

2,属性

实例初始化

可以配置输出数据参数,

let recorder = new Recorder({sampleBits: 16,                 // 采样位数,支持 8 或 16,默认是16sampleRate: 16000,              // 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,我的chrome是48000numChannels: 1,                 // 声道,支持 1 或 2, 默认是1// compiling: false,(0.x版本中生效,1.x增加中)  // 是否边录边转换,默认是false
});
Copy
  • 返回: recorder实例。

sampleBits

采样位数。

sampleRate

采样率。

numChannels

声道数。

compiling

(0.x版本中生效,最新目前不支持)

是否边录音边转换。

获取数据方法:

  • 回调方式
recorder.onprogress = function(params) {console.log(params.data);       // 当前获取到到音频数据
}
Copy

data,DataView型数组,格式如 [DataView, DataView, DataView ...] 。

  • 主动获取
getWholeData();     // [DataView, DataView, DataView ...]getNextData();      // [DataView, DataView, DataView ...]
Copy

getWholeData() 的值和onprogress回调中的data数据一致。

getNextData() 获取的是前一次 getNextData() 之后的值,他只是data数据的一小部分。

实例属性

duration

获取录音的总时长。

console.log(recorder.duration);
Copy

fileSize

录音文件大小(单位:字节)。

console.log(recorder.fileSize);

3,操作

start()

开始录音。

  • 返回: Promise。
recorder.start().then(() => {// 开始录音
}, (error) => {// 出错了console.log(`${error.name} : ${error.message}`);
});
Copy

pause()

录音暂停。

  • 返回: void
recorder.pause();
Copy

resume()

继续录音。

  • 返回: void。
recorder.resume()
Copy

stop()

结束录音。

  • 返回: void。
recorder.stop();
Copy

play()

录音播放。

  • 返回: void。
recorder.play();
Copy

getPlayTime()

获取音频已经播的时长。

  • 返回: number。
recorder.getPlayTime();
Copy

pausePlay()

暂停录音播放。

  • 返回: void。
recorder.pausePlay();
Copy

resumePlay()

恢复录音播发。

  • 返回: void。
recorder.resumePlay();
Copy

stopPlay()

停止播放。

  • 返回: void。
recorder.stopPlay();
Copy

destroy()

销毁实例。

  • 返回: Promise。
// 销毁录音实例,置为null释放资源,fn为回调函数,
recorder.destroy().then(function() {recorder = null;
});
Copy

音频数据

录音结束,获取取录音数据

getPCMBlob()

获取 PCM 数据,在录音结束后使用。

  • 返回: Blob

注:使用该方法会默认调用 stop() 方法。

recorder.getPCMBlob();
Copy

getWAVBlob()

获取 WAV 数据,在录音结束后使用

  • 返回: Blob

注:使用该方法会默认调用 stop() 方法。

recorder.getWAVBlob();
Copy

getChannelData()

获取左声道和右声道音频数据。

recorder.getChannelData();
Copy

录音结束,下载录音文件

downloadPCM([ filename ])

下载 PCM 格式

  • fileName String 重命名文件
  • 返回: Blob

注:使用该方法会默认调用 stop() 方法。

recorder.downloadPCM(fileName ?);
Copy

downloadWAV([ filename ])

下载 WAV 格式

  • fileName String 重命名文件
  • 返回: Blob

注:使用该方法会默认调用 stop() 方法。

录音中,获取录音数据

(0.x版本中生效,最新目前不支持)

该方式为边录边转换,建议在 compiling 为 true 时使用。

getWholeData()

获取已经录音的所有数据。若没有开启边录边转(compiling为false),则返回是空数组。

  • 返回: Array, 数组中是DataView数据

定时获取所有数据:

setInterval(() => {recorder.getWholeData();
}, 1000)
Copy

getNextData()

获取前一次 getNextData() 之后的数据。若没有开启边录边转(compiling为false),则返回是空数组。

  • 返回: Array, 数组中是DataView数据

定时获取新增数据:

setInterval(() => {recorder.getNextData();
}, 1000)
// 实时录音,则可将该数据返回给服务端。
Copy

录音波形显示

getRecordAnalyseData()

返回的是一个1024长的,0-255大小的Uint8Array类型。用户可以根据这些数据自定义录音波形。此接口获取的是录音时的。

let dataArray = recorder.getRecordAnalyseData();
Copy

getPlayAnalyseData()

返回数据同 getRecordAnalyseData(),该方法获取的是播放时的。

let dataArray = recorder.getPlayAnalyseData();
Copy

播放外部

Player.play(blob)

播放外部音频,格式由浏览器的audio支持的类型决定。

Player.play(/* 放入arraybuffer数据 */);
Copy

其他

录音权限

未给予录音权限的页面在开始录音时需要再次点击允许录音,才能真正地录音,存在丢失开始这一段录音的情况,增加方法以便用户提前获取麦克风权限。

getPermission()

获取麦克风权限。

  • 返回:promise。
Recorder.getPermission().then(() => {console.log('给权限了');
}, (error) => {console.log(`${error.name} : ${error.message}`);
});
Copy

此处then回调与start的一致。

4,Event

js-audio-recorder 支持的事件回调。

onprocess(duration)

用于获取录音时长。

不推荐使用,用onprogress代替。

recorder.onprocess = function(duration) {console.log(duration);
}
Copy

onprogress(duration)

目前支持获取以下数据:

  • 录音时长(duration)。
  • 录音大小(fileSize)。
  • 录音音量百分比(vol)。
  • 所有的录音数据(data)。
recorder.onprogress = function(params) {console.log('录音时长(秒)', params.duration);console.log('录音大小(字节)', params.fileSize);console.log('录音音量百分比(%)', params.vol);// console.log('当前录音的总数据([DataView, DataView...])', params.data);
}
Copy

onplay

录音播放开始回调。

recorder.onplay = () => {console.log('onplay')
}
Copy

onpauseplay

录音播放暂停回调。

recorder.onpauseplay = () => {console.log('onpauseplay')
}
Copy

onresumeplay

录音播放恢复回调。

recorder.onresumeplay = () => {console.log('onresumeplay')
}
Copy

onstopplay

录音播放停止回调。

recorder.onstopplay = () => {console.log('onstopplay')
}
Copy

onplayend

录音播放完成回调。

recorder.onplayend = () => {console.log('onplayend')
}

5,应用

语音识别

recorder上可以测试,注意选择16000采样率,16采样位数,单声道录音。

6,Player

Player 播放类

import Player from './player/player';
Copy

用于协助播放录音文件,包括,开始、暂停、恢复、停止等功能。所支持的格式由浏览器的audio支持的类型决定。可单独使用。

Player.play([arraybuffer])

播放外部的音频。所支持的格式由浏览器的audio支持的类型决定。

实际是调用了decodeAudioData实现音频播放。

Recorder.play(/* 放入arraybuffer数据 */);
Copy

Player.pausePlay()

暂停播放。

Player.resumePlay()

恢复播放。

Player.stopPlay()

停止播放。

Player.addPlayEnd(fn)

增加播放完成回调函数。

Player.getPlayTime()

获取播放时间。

Player.getAnalyseData()

获取回放录音的波形数据。

7,其他音频格式

MP3

将pcm(wav)音频文件转化为mp3格式。

注:使用16采样位数。

利用lamejs进行转换,使用情况见demo,例子:

function convertToMp3(wavDataView) {// 获取wav头信息const wav = lamejs.WavHeader.readHeader(wavDataView); // 此处其实可以不用去读wav头信息,毕竟有对应的config配置const { channels, sampleRate } = wav;const mp3enc = new lamejs.Mp3Encoder(channels, sampleRate, 128);// 获取左右通道数据const result = recorder.getChannelData()const buffer = [];const leftData = result.left && new Int16Array(result.left.buffer, 0, result.left.byteLength / 2);const rightData = result.right && new Int16Array(result.right.buffer, 0, result.right.byteLength / 2);const remaining = leftData.length + (rightData ? rightData.length : 0);const maxSamples = 1152;for (let i = 0; i < remaining; i += maxSamples) {const left = leftData.subarray(i, i + maxSamples);let right = null;let mp3buf = null;if (channels === 2) {right = rightData.subarray(i, i + maxSamples);mp3buf = mp3enc.encodeBuffer(left, right);} else {mp3buf = mp3enc.encodeBuffer(left);}if (mp3buf.length > 0) {buffer.push(mp3buf);}}const enc = mp3enc.flush();if (enc.length > 0) {buffer.push(enc);}return new Blob(buffer, { type: 'audio/mp3' });
}
Copy

安装lamejs

npm install lamejs

vue实现录音功能js-audio-recorder带波浪图相关推荐

  1. vue.runtime.esm.js:4560 [Vue warn]: Property or method “item“ is not defined on the instance but

    报错异常 vue.runtime.esm.js:4560 [Vue warn]: Property or method "item" is not defined on the i ...

  2. dropzonejs vue 使用_dropzone.js使用实践

    官网地址:http://www.dropzonejs.com/ 一,它是什么: DropzoneJS is an open source library that provides drag'n'dr ...

  3. 【项目技术点总结之一】vue集成d3.js利用svg加载图片实现缩放拖拽功能

    [项目技术点总结之一]vue集成d3.js利用svg加载图片实现缩放拖拽功能 前言 概述 技术介绍 实现过程 插件安装 引用组件 初始化组件 实现效果 简单理解 使用d3创建一个svg 在svg中提添 ...

  4. js循环动态绑定带参数函数遇到的问题及解决方案[转]

    今天写原生javascript时,想利用绑定事件实现类似jquery中on方法的功能:于是有了for循环里绑定事件,无意中发现定义类能解决好多问题! 例如:一个不确定长度的列表,在鼠标经过某一条的时候 ...

  5. JS调用后台带参数的方法

    JS调用后台带参数的方法 对于前台调用后台的方法,我们想到最多的就是用AJAX,这个是毋庸置疑的, 我就不再这里多说了.我今天主要想说的是用JS调用后台的方法. 对于后台往前台传值,用这种<%= ...

  6. js setTimeout 传递带参数的函数的2种方式

    js setTimeout 传递带参数的函数的2种方式 Created by Marydon on 2018年9月14日 1.准备工作 function sayYourName(param) {ale ...

  7. SQLAlchemy中模糊查询;JS中POST带参数跳转;JS获取url参数

    SQLAlchemy中模糊查询,如何like多个关键字 JS中POST带参数跳转 一个项目中要跳转到另外一个项目,还需要带参数 考虑到安全性的问题,最好是用POST跳转,不能再URL中拼参 所以找到了 ...

  8. vue项目中主要文件的加载顺序(index.html、App.vue、main.js)

    先后顺序: index.html > App.vue的export外的js代码 > main.js > App.vue的export里面的js代码 > Index.vue的ex ...

  9. Vue中的Js动画与Velocity.js 的结合

    <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8" ...

最新文章

  1. 计算机vb2级知识点,二级考试(VB)知识点细化(针对浙江省计算机等级考试)
  2. 工业电脑中PCI、CPCI、PXI插槽的区别
  3. mysql触发器和存储过程_MySql的存储过程和触发器
  4. 深度学习模型之各种caffe版本(Linux和windows)的网址和配置
  5. 6.Maven聚合和继承,相关案例配置
  6. html flash 动画效果代码大全,flash动作代码大全
  7. zoj 3640 概率dp
  8. css 浮动和清除浮动
  9. 关于Windowsn 7因验证未通过被视为“非正版”出现“黑屏”的应急处理预案
  10. SQL允许你用EXECUTE执行一个变量中定义的SQL语句,并且允许你在被执行的SQL语句中,再次嵌套入一个变量定义的语句,并且再次在其中用EXECUTE执行它...
  11. Android 网络HTML查看器
  12. 关于idea中运行maven项目报错显示找不到包或符号的问题——终极方案
  13. 将两个PCB文件合并成一个文件
  14. 20道你必须要背会的微服务面试题,面试一定会被问到
  15. uniapp 使用本地数据库
  16. svn图标不显示的问题
  17. 高尔顿钉板仿真模拟 MATLAB
  18. Cocos技术派 | TS版属性面板定义高级篇
  19. 抽奖活动的奖品怎么设置?
  20. 搞死SAP系统系列 让系统无法连接数据库

热门文章

  1. 浅谈大型web系统架构
  2. C语言:编写代码实现,模拟用户登入情景,并且只能登入三次。(只允许输入三次,如果密码正确则提示登陆成功,如果三次均输入错误,则退出程序)
  3. XP中服务与后门技术
  4. 基于联邦学习中毒攻击的防御策略
  5. Python实现一个全国各高校查询系统
  6. H264——H264码流分析实例(SPS、PPS)
  7. 网站如何报价 做一个普通企业网站多少钱?
  8. SRC小技巧:批量查询网站权重
  9. 扩散模型加持下,机器人模型DALL-E-Bot可以轻松完成自主重新排列任务
  10. 堆(heap):先进先出,栈(stack)先进后出