最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue前端獲取/切換麥克風(fēng)、播放采集音頻和采集音量大小完整代碼

 更新時(shí)間:2023年12月01日 09:11:53   作者:Oamnij  
這篇文章主要給大家介紹了關(guān)于vue前端獲取/切換麥克風(fēng)、播放采集音頻和采集音量大小的相關(guān)資料,文中通過(guò)圖文以及代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用vue具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

一、前言

使用時(shí)確保你有如下依賴且版本為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)列表里面選擇一個(gè)麥克風(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="請(qǐng)選擇麥克風(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可提供對(duì)相機(jī)和麥克風(fēng)等媒體輸入設(shè)備的連接訪問(wèn)
  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 = '測(cè)試';
  // a.click();
  // // 釋放這個(gè)臨時(shí)的對(duì)象url
  // window.URL.revokeObjectURL(audioURL);

  let file = new window.File([BB], '測(cè)試.wav')
  console.log(file);
},

4、獲取采集的音頻音量大小

// 獲取音量值大小
getVoice() {
  const audioContext = new (window.AudioContext || window.webkitAudioContext)()
  // 將麥克風(fēng)的聲音輸入這個(gè)對(duì)象
  const mediaStreamSource = audioContext.createMediaStreamSource(this.stream)
  // 創(chuàng)建分析節(jié)點(diǎn)
  const analyserNode = audioContext.createAnalyser()
  // 連接節(jié)點(diǎn)
  mediaStreamSource.connect(analyserNode)
  // 可以實(shí)時(shí)聽(tīng)到麥克風(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;
  }

  // 每隔一段時(shí)間獲取一次音量
  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="請(qǐng)選擇麥克風(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)前頁(yè)面可以選擇的麥克風(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());
        })
      }
      
    },

    // 語(yǔ)音輸入
    voiceInput(){
      // 正在語(yǔ)音輸入
      if(this.voiceStatus) {
        this.stopRecord() // 停止輸入
      } else { // 開啟語(yǔ)音輸入
        this.startRecord()
      }
    },

    // 開始錄音
    startRecord(){
      var that = this
      this.voiceStatus = true
      // mediaDevices可提供對(duì)相機(jī)和麥克風(fēng)等媒體輸入設(shè)備的連接訪問(wèn)
      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)的聲音輸入這個(gè)對(duì)象
      const mediaStreamSource = audioContext.createMediaStreamSource(this.stream)
      // 創(chuàng)建分析節(jié)點(diǎn)
      const analyserNode = audioContext.createAnalyser()
      // 連接節(jié)點(diǎn)
      mediaStreamSource.connect(analyserNode)
      // 可以實(shí)時(shí)聽(tīng)到麥克風(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;
      }

      // 每隔一段時(shí)間獲取一次音量
      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 = '測(cè)試';
      // a.click();
      // // 釋放這個(gè)臨時(shí)的對(duì)象url
      // window.URL.revokeObjectURL(audioURL);

      let file = new window.File([BB], '測(cè)試.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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue實(shí)現(xiàn)瀑布流組件滑動(dòng)加載更多

    vue實(shí)現(xiàn)瀑布流組件滑動(dòng)加載更多

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)瀑布流組件滑動(dòng)加載更多,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • springboot之springboot與netty整合方案

    springboot之springboot與netty整合方案

    這篇文章主要介紹了VUE之關(guān)于store狀態(tài)管理核心解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • 詳解vue項(xiàng)目中如何加載markdown

    詳解vue項(xiàng)目中如何加載markdown

    這篇文章主要為大家詳細(xì)介紹了在vue項(xiàng)目中如何加載markdown,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-11-11
  • vue菜單欄自適應(yīng)折疊功能示例

    vue菜單欄自適應(yīng)折疊功能示例

    這篇文章主要介紹了vue菜單欄自適應(yīng)折疊,我這里使用的是el-menu導(dǎo)航菜單,監(jiān)聽(tīng)頁(yè)面寬度的改變,來(lái)改變導(dǎo)航菜單的折疊和展開,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-01-01
  • Vue中的偵聽(tīng)器及使用場(chǎng)景

    Vue中的偵聽(tīng)器及使用場(chǎng)景

    Vue中的偵聽(tīng)器是一種響應(yīng)式機(jī)制,可以對(duì)指定的數(shù)據(jù)進(jìn)行監(jiān)聽(tīng),并在數(shù)據(jù)變化時(shí)執(zhí)行相應(yīng)的回調(diào)函數(shù)。常用于監(jiān)聽(tīng)復(fù)雜數(shù)據(jù)類型的變化,如對(duì)象和數(shù)組。通過(guò)偵聽(tīng)器,可以實(shí)現(xiàn)數(shù)據(jù)的自動(dòng)更新和邏輯處理等功能,提高代碼的可讀性和可維護(hù)性
    2023-05-05
  • 基于Vue3+WebSocket實(shí)現(xiàn)實(shí)時(shí)文件傳輸監(jiān)控系統(tǒng)

    基于Vue3+WebSocket實(shí)現(xiàn)實(shí)時(shí)文件傳輸監(jiān)控系統(tǒng)

    WebSocket是一種在客戶端和服務(wù)器之間進(jìn)行雙向通信的網(wǎng)絡(luò)協(xié)議,它通過(guò)建立持久性的、全雙工的連接,允許服務(wù)器主動(dòng)向客戶端發(fā)送數(shù)據(jù),本文小編給大家介紹了基于Vue3+WebSocket實(shí)現(xiàn)實(shí)時(shí)文件傳輸監(jiān)控系統(tǒng),需要的朋友可以參考下
    2025-03-03
  • vue導(dǎo)出excel無(wú)法打開問(wèn)題及解決

    vue導(dǎo)出excel無(wú)法打開問(wèn)題及解決

    在Vue項(xiàng)目中導(dǎo)出Excel文件時(shí),需在請(qǐng)求中設(shè)置responseType為'blob'或'arraybuffer',否則文件可能損壞無(wú)法打開,正確配置確保瀏覽器正確解析二進(jìn)制數(shù)據(jù)流,生成有效Excel文件
    2025-08-08
  • vue報(bào)錯(cuò)Not?allowed?to?load?local?resource的解決辦法

    vue報(bào)錯(cuò)Not?allowed?to?load?local?resource的解決辦法

    這篇文章主要給大家介紹了關(guān)于vue報(bào)錯(cuò)Not?allowed?to?load?local?resource的解決辦法,這個(gè)錯(cuò)誤是因?yàn)閂ue不能加載本地資源的原因,需要的朋友可以參考下
    2023-07-07
  • vue 雙向數(shù)據(jù)綁定的實(shí)現(xiàn)學(xué)習(xí)之監(jiān)聽(tīng)器的實(shí)現(xiàn)方法

    vue 雙向數(shù)據(jù)綁定的實(shí)現(xiàn)學(xué)習(xí)之監(jiān)聽(tīng)器的實(shí)現(xiàn)方法

    這篇文章主要介紹了vue 雙向數(shù)據(jù)綁定的實(shí)現(xiàn)學(xué)習(xí)之監(jiān)聽(tīng)器的實(shí)現(xiàn)方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-11-11
  • Element使用el-table組件二次封裝

    Element使用el-table組件二次封裝

    這篇文章主要為大家介紹了Element使用el-table組件二次封裝示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06

最新評(píng)論

黄骅市| 宁都县| 耒阳市| 汾西县| 玛曲县| 呼和浩特市| 大余县| 延安市| 墨脱县| 南城县| 武夷山市| 宜宾县| 灵川县| 余庆县| 贺兰县| 五河县| 辉县市| 青田县| 洪泽县| 平安县| 德阳市| 常德市| 玉林市| 包头市| 专栏| 阿城市| 永吉县| 沙雅县| 杭锦旗| 射阳县| 全椒县| 高清| 颍上县| 竹山县| 定州市| 鹤山市| 博白县| 灵石县| 郓城县| 长阳| 肇东市|