录音机
此示例演示用于从设备的麦克风录制音频的web应用程序的实现。 应用程序的整个周期如下所述。
- 用户单击←→按钮开始录制
- 录音期间:
-按钮变成红色与动画
-计时器正在运行
-正在收集音频数据 - 停止时:
-音频
文件形成-播放器和下载按钮出现 - 下载创建文件"记录-{日期}。波"
下面提供了对音频记录器代码的详细分析。 代码从一个基本的HTML结构和css样式开始,以获得一个美丽的界面.:
<div class="container">
<div class="title">Audio Recorder</div>
<div class="timer" id="timer">00:00</div>
<button id="recordBtn">🎤</button>
<button class="download-btn hidden" id="downloadBtn" title="Download recording">↓</button>
<div id="status">Press 🎤 to start recording</div>
<div class="audio-container" id="audioContainer">
<audio id="audioPlayer" controls></audio>
</div>
</div>
关键要素:
recordBtn-圆形记录按钮,downloadBtn-下载按钮(最初隐藏),timer-显示录制时间,audioPlayer-播放录制音频的元素。
接下来是变量的初始化
let mediaRecorder;
let audioChunks = [];
let audioBlob;
let audioUrl;
let startTime;
let timerInterval;
let stream;
let isRecording = false;
变量存储应用程序状态:
mediaRecorder-用于记录媒体的对象,audioChunks-用于存储记录数据的阵列,audioBlob/audioUrl-最终音频,timerInterval-更新计时器,stream-来自麦克风的数据流。
之后,声明辅助函数。
function formatTime(seconds) {
const mins = Math.floor(seconds / 60).toString().padStart(2, '0');
const secs = Math.floor(seconds % 60).toString().padStart(2, '0');
return `${mins}:${secs}`;
}
function updateTimer() {
const elapsed = Math.floor((Date.now() - startTime) / 1000);
timerElement.textContent = formatTime(elapsed);
}
formatTime 将秒转换为"MM:SS"格式,以及 updateTimer 更新计时器显示。
接下来是录音启动功能。
function startRecording() {
navigator.mediaDevices.getUserMedia({ audio: true })
.then(function(s) {
stream = s;
mediaRecorder = new MediaRecorder(stream);
audioChunks = [];
mediaRecorder.ondataavailable = function(e) {
if (e.data.size > 0) {
audioChunks.push(e.data);
}
};
mediaRecorder.onstop = function() {
audioBlob = new Blob(audioChunks, { type: 'audio/wav' });
audioUrl = URL.createObjectURL(audioBlob);
audioPlayer.src = audioUrl;
downloadBtn.classList.remove('hidden');
statusElement.textContent = "Recording saved! Click 🎤 to record again";
};
mediaRecorder.start(100);
startTime = Date.now();
timerInterval = setInterval(updateTimer, 1000);
updateTimer();
isRecording = true;
recordBtn.classList.add('recording');
recordBtn.textContent = "⏹️";
statusElement.textContent = "Recording... Click ⏹️ to stop";
})
.catch(function(err) {
console.error('Error accessing microphone:', err);
statusElement.textContent = "Error accessing microphone";
});
}
操作的逻辑如下所述。
- 通过以下方式请求访问麦克风
getUserMedia - 创建
MediaRecorder记录流 - 设置处理程序:
ondataavailable-收集音频片段,onstop-创建最终文件并显示下载按钮。
- 启动计时器并更改界面
之后,实施记录停止。
function stopRecording() {
if (mediaRecorder && mediaRecorder.state !== 'inactive') {
mediaRecorder.stop();
clearInterval(timerInterval);
stream.getTracks().forEach(track => track.stop());
isRecording = false;
recordBtn.classList.remove('recording');
recordBtn.textContent = "🎤";
}
}
停止录制、计时器和释放麦克风资源。
并下载录音:
function downloadRecording() {
if (audioUrl) {
const a = document.createElement('a');
a.href = audioUrl;
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
a.download = `recording-${timestamp}.wav`;
a.click();
statusElement.textContent = "Download started...";
}
}
为具有唯一名称的文件创建临时下载链接。
还有一个事件处理程序,允许录制按钮作为启动/停止开关工作,并且还可以将整个界面及其更新链接到音频文件录制事件。
recordBtn.addEventListener('click', function() {
if (isRecording) {
stopRecording();
} else {
startRecording();
}
});
downloadBtn.addEventListener('click', downloadRecording);
现在让我们启动应用程序本身,看看它是如何工作的。
In [ ]:
display("text/html", read("audio_recorder.html", String))
结论
此示例和工具本身可用于为DSP生成测试数据样本。