
本文旨在解决使用JavaScript MediaRecorder进行实时录音,并通过Base64编码传输至PHP服务器保存为`.ogg`文件时,文件损坏无法播放的问题。核心问题在于`MediaRecorder`的媒体类型配置不当,以及服务器端对音频数据块的处理方式错误(覆盖而非追加)。教程将详细阐述正确的客户端配置和服务器端文件追加策略,并提供完整的代码示例。
1. 理解MediaRecorder与音频数据流
MediaRecorder API允许我们录制用户的音频和视频流。它通过ondataavailable事件周期性地提供媒体数据块(e.data),这些数据块通常是媒体流的一部分,而非完整的、可独立播放的文件。为了将这些数据块组合成一个可播放的媒体文件,我们需要在客户端或服务器端进行适当的处理。
在将数据发送到服务器进行保存时,常见的流程是:
- MediaRecorder捕获音频数据。
- ondataavailable事件触发,提供一个数据块。
- 数据块被编码(例如Base64),并通过HTTP请求发送到服务器。
- 服务器接收数据,解码,并保存到文件。
然而,在这个过程中,有两个关键环节容易导致最终文件损坏。
立即学习“PHP免费学习笔记(深入)”;
2. 客户端配置问题:错误的媒体类型指定
原始代码中,开发者尝试在创建Blob对象时指定媒体类型:
const blob = new Blob(chunks, { 'type' : 'audio/ogg; codecs=opus' });登录后复制
这种做法是错误的。MediaRecorder在开始录制时,就需要知道它应该以何种格式和编码器来处理媒体流。Blob构造函数中的type参数仅用于标识Blob的MIME类型,并不会改变其内部数据的实际编码格式。
正确做法是,在MediaRecorder的构造函数中指定媒体类型和编码器。这样,MediaRecorder才会按照指定的格式生成e.data数据块。
// ...
navigator.mediaDevices.getUserMedia ({ audio: true })
.then(function(stream) {
// 在这里定义 MediaRecorder 的选项
const mrOptions = { mimeType: 'audio/ogg; codecs=opus' };
mediaRecorder = new MediaRecorder(stream, mrOptions); // 将选项传递给构造函数
mediaRecorder.start(2000); // 每2秒触发一次 ondataavailable 事件
mediaRecorder.ondataavailable = function(e) {
chunks.push(e.data);
// 创建 Blob 时,可以引用 MediaRecorder 实际使用的 mimeType
const blob = new Blob(chunks, { type : mediaRecorder.mimeType });
chunks = []; // 清空 chunks,准备接收下一个数据块
// ... 后续处理
};
})
// ...登录后复制
通过在MediaRecorder构造函数中设置mimeType,我们确保了e.data数据块本身就是以audio/ogg; codecs=opus格式编码的。
标签: php javascript java js 编码 浏览器 app ai win stream red
还木有评论哦,快来抢沙发吧~