web网页上实现录音功能(vue3)_vue 录音
文章目录
一. 前言
在Web开发中实现音频录制功能是许多应用场景的常见需求。本文将通过一个完整的Vue 3组件示例,详细解析如何利用现代浏览器API实现网页端的录音功能。
二. 技术实现
1.核心API介绍
MediaRecorder API 是实现录音功能的核心,它允许我们直接捕获来自用户设备的媒体流。主要方法:
getUserMedia() 获取媒体设备权限
MediaRecorder() 创建录音实例
ondataavailable 接收音频数据
onstop 处理录音结束事件
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.核心逻辑实现
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(\"录音错误:\", error); }};
4. 关键功能点解析
(1) 音频格式处理
通过MIME类型映射获取文件扩展名:
// 获取文件扩展名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) 资源管理
组件卸载时自动释放资源:
//停止录音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(\"录音错误:\", error); }};//停止录音const stopRecording = () => { console.log(\"停止录音\"); isRecording.value = false; if (mediaRecorder.value) { mediaRecorder.value.stop(); mediaRecorder.value.stream.getTracks().forEach((track) => track.stop()); }};// 获取文件扩展名const getFileExtension = (mimeType) => { const extensions = { \"audio/webm\": \"webm\", \"audio/ogg\": \"ogg\", \"audio/mp4\": \"mp4\", \"audio/mpeg\": \"mp3\", \"audio/wav\": \"wav\", }; return extensions[mimeType] || \"webm\";};// 切换录音状态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>
四. 功能扩展建议
添加录音时长显示
实现音频波形可视化