vue前端獲取/切換麥克風(fēng)、播放采集音頻和采集音量大小完整代碼
一、前言
使用時確保你有如下依賴且版本為Vue2,終端里面運(yùn)行
npm install element-ui npm install recordrtc npm install sass sass-loader
二、案列圖示
三、代碼
1、獲取麥克風(fēng)列表
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { var Mic = [] // 彈框獲取麥克風(fēng) navigator.mediaDevices.getUserMedia({audio: true}).then((stream) => { navigator.mediaDevices.enumerateDevices().then(function (devices) { devices.forEach(function (device) { if(device.kind === 'audioinput'){ // 麥克風(fēng) if(device.deviceId != 'default' && device.deviceId != 'communications'){ that.Mic.push(device) } } }); }) // 只是為了獲取麥克風(fēng)權(quán)限,獲取以后立馬關(guān)閉 stream.getTracks().forEach(track => track.stop()); }) }
2、用戶在麥克風(fēng)列表里面選擇一個麥克風(fēng)
<el-form style="padding: 0 80px" ref="mainFormRef" :model="main_form" label-width="100px" :rules="rules" > <el-form-item label="聲紋采集:" prop="file"> <el-select :disabled="voiceStatus" style="width: 200px;" v-model="main_form.chooseMicDeviceId" placeholder="請選擇麥克風(fēng)"> <el-option v-for="item in Mic" :key="item.deviceId" :label="item.label" :value="item.deviceId"> </el-option> </el-select> <div class="voiceGather" v-if="main_form.chooseMicDeviceId != ''"> <el-button style="margin-top: 20px;" @click="voiceInput">{{ voiceStatus ? '取消錄音' : '開始錄音' }}</el-button> <!-- 正在錄制 --> <template v-if="voiceStatus"> <div class="bo"> <div v-for="(item, index) in RMSList" :key="index" :style="{height: item / 100 * 40 + 'px'}" class="RMS"></div> </div> </template> </div> </el-form-item> </el-form>
3、選取了麥克風(fēng)以后使用當(dāng)前麥克風(fēng)錄音
重要代碼:audio: { deviceId: this.form.chooseMicDeviceId },將上面選的麥克風(fēng)放到getUserMedia中,即可啟用用戶自己選擇的麥克風(fēng)
// 開始錄音 startRecord(){ var that = this this.voiceStatus = true // mediaDevices可提供對相機(jī)和麥克風(fēng)等媒體輸入設(shè)備的連接訪問 window.navigator.mediaDevices.getUserMedia( { audio: { deviceId: this.main_form.chooseMicDeviceId }} ).then((stream) => { this.stream = stream; this.getVoice() this.recorder = RecordRTC(stream, { type: 'audio', mimeType: 'audio/wav', recorderType: RecordRTC.StereoAudioRecorder, desiredSampRate: 16000, numberOfAudioChannels: 1, // 單聲道 timeSlice: 30000, // bufferSize: 4096, // 緩存大小 ondataavailable: this.sendData, }); this.recorder.startRecording(); }).catch(function(err) { console.log(err); console.log('當(dāng)前瀏覽器不支持開啟麥克風(fēng)!'); that.voiceStatus = false }); },
在sendData中可以把數(shù)據(jù)流傳給后端,可以播放/下載采集到的數(shù)據(jù)流,也可以將數(shù)據(jù)流轉(zhuǎn)換成file傳給后端
sendData(blob) { var BB =new Blob([blob], {'type': 'audio/wav; codecs=opus'}) // var audioURL = window.URL.createObjectURL(BB) // 播放 // const audio = document.createElement('audio') // audio.controls = true // 音頻是否顯示控件 // audio.src = audioURL // audio.play() // 下載 // let a = document.createElement("a"); // a.href = audioURL; // a.download = '測試'; // a.click(); // // 釋放這個臨時的對象url // window.URL.revokeObjectURL(audioURL); let file = new window.File([BB], '測試.wav') console.log(file); },
4、獲取采集的音頻音量大小
// 獲取音量值大小 getVoice() { const audioContext = new (window.AudioContext || window.webkitAudioContext)() // 將麥克風(fēng)的聲音輸入這個對象 const mediaStreamSource = audioContext.createMediaStreamSource(this.stream) // 創(chuàng)建分析節(jié)點(diǎn) const analyserNode = audioContext.createAnalyser() // 連接節(jié)點(diǎn) mediaStreamSource.connect(analyserNode) // 可以實(shí)時聽到麥克風(fēng)采集的聲音 // analyserNode.connect(audioContext.destination) // 獲取音量數(shù)據(jù) const dataArray = new Uint8Array(analyserNode.frequencyBinCount); function getVolume() { analyserNode.getByteFrequencyData(dataArray); let sum = 0; for (let i = 0; i < dataArray.length; i++) { sum += dataArray[i]; } // 計(jì)算平均音量 const averageVolume = sum / dataArray.length; return averageVolume; } // 每隔一段時間獲取一次音量 this.timer1 = setInterval(() => { const volume = getVolume(); console.log('音量:', Math.round( volume )); // 在這里可以根據(jù)需要進(jìn)行相應(yīng)的處理 }, 100); },
四、全部代碼
<template> <div class="Page"> <el-form style="padding: 0 80px" ref="mainFormRef" :model="main_form" label-width="100px" :rules="rules" > <el-form-item label="聲紋采集:" prop="file"> <el-select :disabled="voiceStatus" style="width: 200px;" v-model="main_form.chooseMicDeviceId" placeholder="請選擇麥克風(fēng)"> <el-option v-for="item in Mic" :key="item.deviceId" :label="item.label" :value="item.deviceId"> </el-option> </el-select> <div class="voiceGather" v-if="main_form.chooseMicDeviceId != ''"> <el-button style="margin-top: 20px;" @click="voiceInput">{{ voiceStatus ? '取消錄音' : '開始錄音' }}</el-button> <!-- 正在錄制 --> <template v-if="voiceStatus"> <div class="bo"> <div v-for="(item, index) in RMSList" :key="index" :style="{height: item / 100 * 40 + 'px'}" class="RMS"></div> </div> </template> </div> </el-form-item> </el-form> </div> </template> <script> import RecordRTC from 'recordrtc' export default { data() { return { recorder: '', voiceStatus: false, // 是否正在錄音 main_form: { chooseMicDeviceId: '', // 選擇的麥克風(fēng)id }, Mic: [], // 可選擇的麥克風(fēng) rules: { file: [ { required: true, message: "不能為空", trigger: "blur" }, ], }, }; }, created() {}, mounted() { this.getMic() }, methods: { // 獲取當(dāng)前頁面可以選擇的麥克風(fēng) getMic(){ let that = this; if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { // 彈框獲取麥克風(fēng) navigator.mediaDevices.getUserMedia({audio: true}).then((stream) => { navigator.mediaDevices.enumerateDevices().then(function (devices) { devices.forEach(function (device) { console.log(devices); if(device.kind === 'audioinput'){ // 麥克風(fēng) if(device.deviceId != 'default' && device.deviceId != 'communications'){ that.Mic.push(device) } } }); }) stream.getTracks().forEach(track => track.stop()); }) } }, // 語音輸入 voiceInput(){ // 正在語音輸入 if(this.voiceStatus) { this.stopRecord() // 停止輸入 } else { // 開啟語音輸入 this.startRecord() } }, // 開始錄音 startRecord(){ var that = this this.voiceStatus = true // mediaDevices可提供對相機(jī)和麥克風(fēng)等媒體輸入設(shè)備的連接訪問 window.navigator.mediaDevices.getUserMedia( { audio: { deviceId: this.main_form.chooseMicDeviceId }} ).then((stream) => { this.stream = stream; this.getVoice() this.recorder = RecordRTC(stream, { type: 'audio', mimeType: 'audio/wav', recorderType: RecordRTC.StereoAudioRecorder, desiredSampRate: 16000, numberOfAudioChannels: 1, // 單聲道 timeSlice: 1000, // bufferSize: 4096, // 緩存大小 ondataavailable: this.sendData, }); this.recorder.startRecording(); }).catch(function(err) { console.log(err); console.log('當(dāng)前瀏覽器不支持開啟麥克風(fēng)!'); that.voiceStatus = false }); }, // 結(jié)束錄音 stopRecord(){ this.voiceStatus = false if (this.recorder != null) { let recorder = this.recorder recorder.stopRecording(); let stream = this.stream; clearInterval(this.timer1); stream.getAudioTracks().forEach(track => track.stop()); } }, // 獲取音量值大小 getVoice() { const audioContext = new (window.AudioContext || window.webkitAudioContext)() // 將麥克風(fēng)的聲音輸入這個對象 const mediaStreamSource = audioContext.createMediaStreamSource(this.stream) // 創(chuàng)建分析節(jié)點(diǎn) const analyserNode = audioContext.createAnalyser() // 連接節(jié)點(diǎn) mediaStreamSource.connect(analyserNode) // 可以實(shí)時聽到麥克風(fēng)采集的聲音 // analyserNode.connect(audioContext.destination) // 獲取音量數(shù)據(jù) const dataArray = new Uint8Array(analyserNode.frequencyBinCount); function getVolume() { analyserNode.getByteFrequencyData(dataArray); let sum = 0; for (let i = 0; i < dataArray.length; i++) { sum += dataArray[i]; } // 計(jì)算平均音量 const averageVolume = sum / dataArray.length; return averageVolume; } // 每隔一段時間獲取一次音量 this.timer1 = setInterval(() => { const volume = getVolume(); console.log('音量:', Math.round( volume )); // 在這里可以根據(jù)需要進(jìn)行相應(yīng)的處理 }, 100); }, // 每timeSlice執(zhí)行一次 sendData(blob) { var BB = new Blob([blob], {'type': 'audio/wav; codecs=opus'}) // var audioURL = window.URL.createObjectURL(BB) // 播放 // const audio = document.createElement('audio') // audio.controls = true // 音頻是否顯示控件 // audio.src = audioURL // audio.play() // 下載 // let a = document.createElement("a"); // a.href = audioURL; // a.download = '測試'; // a.click(); // // 釋放這個臨時的對象url // window.URL.revokeObjectURL(audioURL); let file = new window.File([BB], '測試.wav') console.log(file); }, }, }; </script> <style lang="scss" scoped> .Page{ padding: 20px; } </style>
總結(jié)
到此這篇關(guān)于vue前端獲取/切換麥克風(fēng)、播放采集音頻和采集音量大小的文章就介紹到這了,更多相關(guān)vue獲取麥克風(fēng)播放采集音頻和音量大小內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue-cli中devServer.proxy相關(guān)配置項(xiàng)的使用
這篇文章主要介紹了vue-cli中devServer.proxy相關(guān)配置項(xiàng)的使用詳解,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-04-04Vue實(shí)現(xiàn)Hover功能(mouseover與mouseenter的區(qū)別及說明)
這篇文章主要介紹了Vue實(shí)現(xiàn)Hover功能(mouseover與mouseenter的區(qū)別及說明),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10Vue響應(yīng)式原理深入解析及注意事項(xiàng)
Vue 最顯著的一個功能是響應(yīng)系統(tǒng) —— 模型只是普通對象,修改它則更新視圖。下面這篇文章主要給大家深入講解了關(guān)于Vue的響應(yīng)式原理,以及Vue響應(yīng)式的一些注意事項(xiàng),需要的朋友下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-12-12vue實(shí)現(xiàn)某元素吸頂或固定位置顯示(監(jiān)聽滾動事件)
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)某元素吸頂或固定位置顯示,監(jiān)聽滾動事件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12