<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
cnpm i js-audio-recorder --s
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,預設是16 sampleRate: 48000, // 取樣率,支援 11025、16000、22050、24000、44100、48000,根據瀏覽器預設值,我的chrome是48000 numChannels: 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();//獲取左聲道和右聲道音訊資料 }, /** * 下載錄音檔案 * */ //下載pcm downPCM(){ //這裡傳參進去的時檔名 recorder.downloadPCM('新檔案'); }, //下載wav downWAV(){ //這裡傳參進去的時檔名 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>
推薦使用npm
安裝的方式:
安裝:
npm i js-audio-recorder
呼叫:
import Recorder from 'js-audio-recorder'; let recorder = new Recorder();
<script type="text/javascript" src="./dist/recorder.js"></script> let recorder = new Recorder();
可以設定輸出資料引數,
let recorder = new Recorder({ sampleBits: 16, // 取樣位數,支援 8 或 16,預設是16 sampleRate: 16000, // 取樣率,支援 11025、16000、22050、24000、44100、48000,根據瀏覽器預設值,我的chrome是48000 numChannels: 1, // 聲道,支援 1 或 2, 預設是1 // compiling: false,(0.x版本中生效,1.x增加中) // 是否邊錄邊轉換,預設是false });
返回: recorder範例。
取樣位數。
取樣率。
聲道數。
(0.x版本中生效,最新目前不支援)
是否邊錄音邊轉換。
獲取資料方法:
回撥方式
recorder.onprogress = function(params) { console.log(params.data); // 當前獲取到到音訊資料 }
data,DataView型陣列,格式如 [DataView, DataView, DataView ...] 。
主動獲取
getWholeData(); // [DataView, DataView, DataView ...] getNextData(); // [DataView, DataView, DataView ...]
getWholeData() 的值和onprogress
回撥中的data資料一致。
getNextData() 獲取的是前一次 getNextData() 之後的值,他只是data資料的一小部分。
獲取錄音的總時長。
console.log(recorder.duration);
錄音檔案大小(單位:位元組)。
console.log(recorder.fileSize);
開始錄音。
返回: Promise。
recorder.start().then(() => { // 開始錄音 }, (error) => { // 出錯了 console.log(`${error.name} : ${error.message}`); });
錄音暫停。
返回: void
recorder.pause();
繼續錄音。
返回: void。
recorder.resume()
結束錄音。
返回: void。
recorder.stop();
錄音播放。
返回: void。
recorder.play();
獲取音訊已經播的時長。
返回: number。
recorder.getPlayTime();
暫停錄音播放。
返回: void。
recorder.pausePlay();
恢復錄音播發。
返回: void。
recorder.resumePlay();
停止播放。
返回: void。
recorder.stopPlay();
銷燬範例。
返回: Promise。
// 銷燬錄音範例,置為null釋放資源,fn為回撥函數, recorder.destroy().then(function() { recorder = null; });
getPCMBlob()
獲取 PCM 資料,在錄音結束後使用。
返回: Blob
注:使用該方法會預設呼叫 stop() 方法。
recorder.getPCMBlob();
getWAVBlob()
獲取 WAV 資料,在錄音結束後使用
返回: Blob
注:使用該方法會預設呼叫 stop() 方法。
recorder.getWAVBlob();
getChannelData()
獲取左聲道和右聲道音訊資料。
recorder.getChannelData();
downloadPCM([ filename ])
下載 PCM 格式
注:使用該方法會預設呼叫 stop() 方法。
recorder.downloadPCM(fileName ?);
downloadWAV([ filename ])
下載 WAV 格式
注:使用該方法會預設呼叫 stop() 方法。
(0.x版本中生效,最新目前不支援)
該方式為邊錄邊轉換,建議在 compiling 為 true 時使用。
getWholeData()
獲取已經錄音的所有資料。若沒有開啟邊錄邊轉(compiling為false),則返回是空陣列。
返回: Array, 陣列中是DataView資料
定時獲取所有資料:
setInterval(() => { recorder.getWholeData(); }, 1000)
getNextData()
獲取前一次 getNextData() 之後的資料。若沒有開啟邊錄邊轉(compiling為false),則返回是空陣列。
定時獲取新增資料:
setInterval(() => { recorder.getNextData(); }, 1000) // 實時錄音,則可將該資料返回給伺服器端。
getRecordAnalyseData()
返回的是一個1024長的,0-255大小的Uint8Array型別。使用者可以根據這些資料自定義錄音波形。此介面獲取的是錄音時的。
let dataArray = recorder.getRecordAnalyseData();
getPlayAnalyseData()
返回資料同 getRecordAnalyseData(),該方法獲取的是播放時的。
let dataArray = recorder.getPlayAnalyseData();
播放外部音訊,格式由瀏覽器的audio支援的型別決定。
Player.play(/* 放入arraybuffer資料 */);
未給予錄音許可權的頁面在開始錄音時需要再次點選允許錄音,才能真正地錄音,存在丟失開始這一段錄音的情況,增加方法以便使用者提前獲取麥克風許可權。
獲取麥克風許可權。
返回:promise。
Recorder.getPermission().then(() => { console.log('給許可權了'); }, (error) => { console.log(`${error.name} : ${error.message}`); });
此處then
回撥與start
的一致。
js-audio-recorder 支援的事件回撥。
用於獲取錄音時長。
不推薦使用,用onprogress代替。
recorder.onprocess = function(duration) { console.log(duration); }
目前支援獲取以下資料:
recorder.onprogress = function(params) { console.log('錄音時長(秒)', params.duration); console.log('錄音大小(位元組)', params.fileSize); console.log('錄音音量百分比(%)', params.vol); // console.log('當前錄音的總資料([DataView, DataView...])', params.data); }
錄音播放開始回撥。
recorder.onplay = () => { console.log('onplay') }
錄音播放暫停回撥。
recorder.onpauseplay = () => { console.log('onpauseplay') }
錄音播放恢復回撥。
recorder.onresumeplay = () => { console.log('onresumeplay') }
錄音播放停止回撥。
recorder.onstopplay = () => { console.log('onstopplay') }
錄音播放完成回撥。
recorder.onplayend = () => { console.log('onplayend') }
recorder上可以測試,注意選擇16000取樣率,16取樣位數,單聲道錄音。
import Player from './player/player';
用於協助播放錄音檔案,包括,開始、暫停、恢復、停止等功能。所支援的格式由瀏覽器的audio支援的型別決定。可單獨使用。
播放外部的音訊。所支援的格式由瀏覽器的audio支援的型別決定。
實際是呼叫了decodeAudioData
實現音訊播放。
Recorder.play(/* 放入arraybuffer資料 */);
暫停播放。
恢復播放。
停止播放。
增加播放完成回撥函數。
獲取播放時間。
獲取回放錄音的波形資料。
將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' }); }
npm install lamejs
到此這篇關於vue實現錄音功能js-audio-recorder帶波浪圖效果的範例的文章就介紹到這了,更多相關vue js-audio-recorder錄音內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45