如何用JavaScript录制网页系统音频?为在线架子鼓添加录制下载功能
为在线架子鼓添加系统音频录制与下载功能
我制作了一个简单的在线架子鼓播放器,现在想为网站添加录制演奏内容并下载的功能。希望代码简单且使用JavaScript,因为刚接触Web开发,仅掌握HTML、CSS和JavaScript等少量技术。曾在网上寻求帮助,但找到的都是使用麦克风录制用户音频的方法,而非录制系统音频,因此前来咨询。
要实现网页音频(架子鼓演奏声音)的录制,我们可以使用Web API中的MediaRecorder结合AudioContext捕获网页音频输出,以下是基于你现有代码的最简实现:
1. 更新HTML,添加录制控制按钮
在架子鼓按钮区域下方添加录制操作按钮:
<div class="set"> <!-- 原有架子鼓按钮 --> <button class="w drum">w</button> <button class="a drum">a</button> <button class="s drum">s</button> <button class="d drum">d</button> <button class="j drum">j</button> <button class="k drum">k</button> <button class="l drum">l</button> </div> <!-- 新增录制控制按钮 --> <div class="controls"> <button id="startRecord">开始录制</button> <button id="stopRecord" disabled>停止并下载</button> </div>
给控制按钮添加基础样式(写入你的styles.css):
.controls { margin: 20px 0; } .controls button { padding: 10px 20px; font-size: 1.2rem; margin: 0 10px; border: none; border-radius: 8px; background-color: #DA0463; color: white; cursor: pointer; font-family: 'Arvo', cursive; } .controls button:disabled { background-color: #888; cursor: not-allowed; }
2. 修改JavaScript,实现录制逻辑
替换原有index.js代码为以下内容,核心是通过AudioContext管理音频播放,并将输出接入MediaRecorder:
// 初始化音频上下文与录制变量 let audioContext; let mediaRecorder; let recordingChunks = []; let isRecording = false; // 页面加载时初始化音频上下文 window.addEventListener('load', () => { audioContext = new (window.AudioContext || window.webkitAudioContext)(); }); // 绑定架子鼓按钮点击与键盘事件 const drumButtons = document.querySelectorAll(".drum"); drumButtons.forEach(button => { button.addEventListener("click", function() { const key = this.innerHTML; makeSound(key); buttonAnimation(key); }); }); document.addEventListener("keypress", (event) => { makeSound(event.key); buttonAnimation(event.key); }); // 绑定录制控制按钮事件 document.getElementById('startRecord').addEventListener('click', startRecording); document.getElementById('stopRecord').addEventListener('click', stopAndDownloadRecording); // 开始录制 function startRecording() { if (isRecording) return; // 创建音频流目标,用于捕获输出 const recordDestination = audioContext.createMediaStreamDestination(); mediaRecorder = new MediaRecorder(recordDestination.stream); // 收集录制数据 mediaRecorder.ondataavailable = (e) => { recordingChunks.push(e.data); }; // 更新按钮状态 isRecording = true; document.getElementById('startRecord').disabled = true; document.getElementById('stopRecord').disabled = false; mediaRecorder.start(); } // 停止录制并下载文件 function stopAndDownloadRecording() { if (!isRecording) return; mediaRecorder.stop(); isRecording = false; // 更新按钮状态 document.getElementById('startRecord').disabled = false; document.getElementById('stopRecord').disabled = true; // 录制结束后生成下载链接 mediaRecorder.onstop = () => { const audioBlob = new Blob(recordingChunks, { type: 'audio/webm' }); const downloadUrl = URL.createObjectURL(audioBlob); const downloadLink = document.createElement('a'); downloadLink.href = downloadUrl; downloadLink.download = 'my-drum-recording.webm'; downloadLink.click(); // 清理资源 URL.revokeObjectURL(downloadUrl); recordingChunks = []; }; } // 播放架子鼓声音(适配录制逻辑) function makeSound(key) { // 激活音频上下文(浏览器要求用户交互后才能播放音频) if (audioContext.state === 'suspended') { audioContext.resume(); } let audioPath; switch (key) { case "w": audioPath = "sounds/tom-1.mp3"; break; case "a": audioPath = "sounds/tom-2.mp3"; break; case "s": audioPath = "sounds/tom-3.mp3"; break; case "d": audioPath = "sounds/tom-4.mp3"; break; case "j": audioPath = "sounds/snare.mp3"; break; case "k": audioPath = "sounds/crash.mp3"; break; case "l": audioPath = "sounds/kick-bass.mp3"; break; default: console.log(key); return; } // 加载并播放音频,同时接入录制流 fetch(audioPath) .then(res => res.arrayBuffer()) .then(buffer => audioContext.decodeAudioData(buffer)) .then(decodedAudio => { const audioSource = audioContext.createBufferSource(); audioSource.buffer = decodedAudio; // 如果正在录制,将音频连接到录制目标 if (isRecording) { audioSource.connect(audioContext.createMediaStreamDestination()); } // 始终连接到扬声器 audioSource.connect(audioContext.destination); audioSource.start(); }) .catch(err => console.error('音频加载失败:', err)); } // 按钮动画逻辑(保留原有功能) function buttonAnimation(currentKey) { const activeButton = document.querySelector("." + currentKey); activeButton.classList.add("pressed"); setTimeout(() => { activeButton.classList.remove("pressed"); }, 100); }
关键注意事项
- 运行环境: 该功能需要在HTTPS环境或本地
localhost下运行(浏览器安全限制) - 浏览器兼容性: 支持Chrome、Firefox、Edge等现代浏览器
- 音频格式: 录制文件为
webm格式,是浏览器原生支持的高效音频格式,可直接播放或转换为MP3等格式
内容的提问来源于stack exchange,提问作者Manas MJ
相关产品推荐
相关产品推荐

