一. 前言
在Web开发中实现音频录制功能是许多应用场景的常见需求。本文将通过一个完整的Vue 3组件示例,详细解析如何利用现代浏览器API实现网页端的录音功能。
二. 技术实现
1.核心API介绍
MediaRecorder API 是实现录音功能的核心,它允许我们直接捕获来自用户设备的媒体流。主要方法: - <strong>getUserMedia()</strong> 获取媒体设备权限<strong>MediaRecorder()</strong> 创建录音实例<strong>ondataavailable</strong> 接收音频数据<strong>onstop</strong> 处理录音结束事件
复制代码 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>
复制代码 四. 功能扩展建议
添加录音时长显示
实现音频波形可视化
总结
到此这篇关于web网页上实现录音功能的文章就介绍到这了,更多相关vue3 web网页录音功能内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |