亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

web網(wǎng)頁上實(shí)現(xiàn)錄音功能(vue3組件示例)

 更新時(shí)間:2025年06月24日 09:45:26   作者:重生之我在農(nóng)廠搬磚  
在Vue項(xiàng)目或網(wǎng)頁上實(shí)現(xiàn)文字轉(zhuǎn)換成語音播放功能,通常涉及到語音合成技術(shù),這篇文章主要介紹了web網(wǎng)頁上實(shí)現(xiàn)錄音功能(vue3組件示例)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

一. 前言

在Web開發(fā)中實(shí)現(xiàn)音頻錄制功能是許多應(yīng)用場(chǎng)景的常見需求。本文將通過一個(gè)完整的Vue 3組件示例,詳細(xì)解析如何利用現(xiàn)代瀏覽器API實(shí)現(xiàn)網(wǎng)頁端的錄音功能。

二. 技術(shù)實(shí)現(xiàn)

1.核心API介紹

MediaRecorder API 是實(shí)現(xiàn)錄音功能的核心,它允許我們直接捕獲來自用戶設(shè)備的媒體流。主要方法:

getUserMedia() 獲取媒體設(shè)備權(quán)限
MediaRecorder() 創(chuàng)建錄音實(shí)例
ondataavailable 接收音頻數(shù)據(jù)
onstop 處理錄音結(jié)束事件

2.模板部分

<template>
  <div class="voice-recorder">
    <!-- 錄音控制 -->
    <button @click="toggleRecording" :class="{ recording: isRecording }">
      {{ isRecording ? "停止錄音" : "開始錄音" }}
    </button>

    <!-- 生成的音頻文件列表 -->
    <div v-if="audioFiles.length > 0" class="audio-list">
      <div v-for="(audio, index) in audioFiles" :key="index">
        <audio controls :src="audio.url"></audio>
      </div>
    </div>
  </div>
</template>

3.核心邏輯實(shí)現(xiàn)

const isRecording = ref(false);
const mediaRecorder = ref(null);
const audioChunks = ref([]);
const audioFiles = ref([]);
// 開始錄音
const startRecording = async (e) => {
  if (isRecording.value) return;
  try {
    audioChunks.value = [];
    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
    mediaRecorder.value = new MediaRecorder(stream);

    mediaRecorder.value.ondataavailable = (e) => {
      audioChunks.value.push(e.data);
    };
    mediaRecorder.value.onstop = () => {
      const audioBlob = new Blob(audioChunks.value, { type: "audio/webm" });
      const audioURL = URL.createObjectURL(audioBlob);
      audioFiles.value.push({
        name: `recording_${Date.now()}.${getFileExtension(audioBlob.type)}`,
        url: audioURL,
      });
      audioChunks.value = [];
    };
    mediaRecorder.value.start();
    isRecording.value = true;
  } catch (error) {
    console.error("錄音錯(cuò)誤:", error);
  }
};

4. 關(guān)鍵功能點(diǎn)解析

(1) 音頻格式處理

通過MIME類型映射獲取文件擴(kuò)展名:

// 獲取文件擴(kuò)展名
const getFileExtension = (mimeType) => {
  const extensions = {
    "audio/webm": "webm",
    "audio/ogg": "ogg",
    "audio/mp4": "mp4",
    "audio/mpeg": "mp3",
    "audio/wav": "wav",
  };
  return extensions[mimeType] || "webm";
};

(2) 資源管理

組件卸載時(shí)自動(dòng)釋放資源:

//停止錄音
const stopRecording = () => {
  console.log("停止錄音");
  isRecording.value = false;
  if (mediaRecorder.value) {
    mediaRecorder.value.stop();
    mediaRecorder.value.stream.getTracks().forEach((track) => track.stop());
  }
};
// 清理資源
onUnmounted(() => {
  stopRecording();
});

三. 完整代碼

<template>
  <div class="voice-recorder">
    <!-- 錄音控制 -->
    <button @click="toggleRecording" :class="{ recording: isRecording }">
      {{ isRecording ? "停止錄音" : "開始錄音" }}
    </button>

    <!-- 生成的音頻文件列表 -->
    <div v-if="audioFiles.length > 0" class="audio-list">
      <div v-for="(audio, index) in audioFiles" :key="index">
        <audio controls :src="audio.url"></audio>
      </div>
    </div>
  </div>
</template>

<script setup>
const isRecording = ref(false);
const mediaRecorder = ref(null);
const audioChunks = ref([]);
const audioFiles = ref([]);

// 開始錄音
const startRecording = async (e) => {
  if (isRecording.value) return;
  try {
    audioChunks.value = [];
    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
    mediaRecorder.value = new MediaRecorder(stream);

    mediaRecorder.value.ondataavailable = (e) => {
      audioChunks.value.push(e.data);
    };
    mediaRecorder.value.onstop = () => {
      const audioBlob = new Blob(audioChunks.value, { type: "audio/webm" });
      const audioURL = URL.createObjectURL(audioBlob);
      audioFiles.value.push({
        name: `recording_${Date.now()}.${getFileExtension(audioBlob.type)}`,
        url: audioURL,
      });
      audioChunks.value = [];
    };
    mediaRecorder.value.start();
    isRecording.value = true;
  } catch (error) {
    console.error("錄音錯(cuò)誤:", error);
  }
};

//停止錄音
const stopRecording = () => {
  console.log("停止錄音");
  isRecording.value = false;
  if (mediaRecorder.value) {
    mediaRecorder.value.stop();
    mediaRecorder.value.stream.getTracks().forEach((track) => track.stop());
  }
};

// 獲取文件擴(kuò)展名
const getFileExtension = (mimeType) => {
  const extensions = {
    "audio/webm": "webm",
    "audio/ogg": "ogg",
    "audio/mp4": "mp4",
    "audio/mpeg": "mp3",
    "audio/wav": "wav",
  };
  return extensions[mimeType] || "webm";
};

// 切換錄音狀態(tài)
const toggleRecording = () => {
  if (!isRecording.value) {
    startRecording();
  } else {
    if (mediaRecorder.value) {
      mediaRecorder.value.stop();
      mediaRecorder.value.stream.getTracks().forEach((track) => track.stop());
    }
  }
  isRecording.value = !isRecording.value;
};

// 清理資源
onUnmounted(() => {
  stopRecording();
});
</script>

<style lang="scss" scoped>
.voice-recorder {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
  button {
    padding: 12px 24px;
    background: #42b983;
    color: white;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    transition: background 0.3s;
    &.recording {
      background: #ff4444;
    }
  }

  button:hover {
    background: #3aa876;
  }

  button:disabled {
    background: #ddd;
    cursor: not-allowed;
  }
}

.recording {
  background-color: #ff4444;
  color: white;
}

.audio-list {
  margin-top: 20px;
}
</style>

四. 功能擴(kuò)展建議

添加錄音時(shí)長(zhǎng)顯示

實(shí)現(xiàn)音頻波形可視化

總結(jié)

到此這篇關(guān)于web網(wǎng)頁上實(shí)現(xiàn)錄音功能的文章就介紹到這了,更多相關(guān)vue3 web網(wǎng)頁錄音功能內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論