
本文深入探讨了使用javascript mediarecorder进行实时音频录制并上传至php服务器时,导致生成文件损坏的常见问题。核心在于mediarecorder在初始化时未能正确指定音频mime类型和编码器。教程将详细指导如何在mediarecorder构造函数中正确配置`mimetype`选项,确保生成有效的音频数据块。同时,文章还将讨论服务器端文件处理(如连续录音的追加写入)以及数据块拼接的关键注意事项,旨在帮助开发者构建稳定可靠的实时音频录制解决方案。
在Web开发中,利用MediaRecorder API实现麦克风实时录音并将数据发送至后端服务器进行存储是一种常见的需求。然而,开发者在尝试将分块的音频数据(通常是Base64编码后)保存为可播放的音频文件时,经常会遇到文件损坏或无法播放的问题。本文将深入分析这一问题的根源,并提供一个可靠的解决方案。
当使用MediaRecorder进行录音时,其ondataavailable事件会周期性地提供音频数据块(e.data)。开发者通常会将这些数据块收集起来,然后转换为Blob对象,再进行Base64编码并通过AJAX发送到服务器。服务器端接收到数据后进行Base64解码并写入文件。
导致文件损坏的核心原因在于MediaRecorder未能正确地在录音开始前知晓并生成指定格式的音频数据。许多开发者可能会尝试在ondataavailable回调中,当创建Blob对象时指定其type(例如{ 'type' : 'audio/ogg; codecs=opus' })。然而,这种做法是错误的。Blob构造函数中的type参数仅仅是告知浏览器或接收方这个Blob对象的MIME类型,它并不能改变MediaRecorder已经生成的数据的实际编码格式。如果MediaRecorder在录制时没有被告知要生成audio/ogg; codecs=opus格式的数据,那么它可能生成默认的或不兼容的格式,即使你将Blob的类型声明为audio/ogg; codecs=opus,底层数据仍然是错误的,导致文件无法播放。
正确的做法是在初始化MediaRecorder实例时,通过其构造函数的第二个参数(一个选项对象)来明确指定所需的MIME类型和编码器。这样,MediaRecorder从一开始就会按照指定的格式生成音频数据块,确保数据的有效性。
首先,我们需要修改MediaRecorder的初始化部分,确保在录音开始前就指定好音频格式。
<script>
var mediaRecorder = null;
let chunks = [];
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
console.log('getUserMedia supported.');
navigator.mediaDevices.getUserMedia({ audio: true })
.then(function(stream) {
// --- 关键修正部分开始 ---
// 定义MediaRecorder的选项,明确指定MIME类型和编码器
// 推荐使用 'audio/ogg; codecs=opus' 或 'audio/webm; codecs=opus'
// 确保你的浏览器支持这些MIME类型
const mrOptions = { mimeType: 'audio/ogg; codecs=opus' };
// 将选项传递给MediaRecorder构造函数
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,准备接收下一个数据块
var reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function() {
// 从Data URL中提取Base64编码的数据
var data = reader.result.split(";base64,")[1];
requestp2("a.php", "data=" + encodeURIComponent(data));
}
}
})
.catch(function(err) {
console.log('The following getUserMedia error occurred: ' + err);
});
} else {
console.log('getUserMedia not supported on your browser!');
}
function requestp2(path, data) {
var http = new XMLHttpRequest();
http.open('POST', path, true);
http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
http.send(data);
}
</script>在上述代码中,我们引入了mrOptions对象,并在其中指定了mimeType: 'audio/ogg; codecs=opus'。这个选项被传递给MediaRecorder构造函数,确保MediaRecorder从一开始就生成符合Ogg Opus格式的音频数据。在创建Blob时,我们现在使用mediaRecorder.mimeType来保持类型声明与实际生成数据的一致性。
PHP服务器端的处理相对简单,主要负责接收Base64编码的数据,解码并写入文件。
<?php
if(isset($_POST["data"]))
{
// base64_decode 会将Base64编码的字符串解码为二进制数据
// file_put_contents 会将二进制数据写入文件
// 注意:原始代码每次都覆盖文件,如果需要连续录音,应使用FILE_APPEND模式
file_put_contents("r.ogg", base64_decode($_POST["data"]));
exit;
}
?>MIME类型选择与兼容性:
连续录音的文件处理:
file_put_contents("r.ogg", base64_decode($_POST["data"]), FILE_APPEND);数据块(Chunks)的处理:
错误处理:
解决MediaRecorder实时录音文件损坏的关键在于在初始化MediaRecorder实例时,通过mimeType选项明确指定所需的音频格式和编码器。这确保了MediaRecorder从一开始就生成符合规范的音频数据块。同时,开发者还需要根据实际需求,合理选择服务器端的文件写入模式(覆盖或追加),并理解ondataavailable事件中数据块的处理方式,以构建一个稳定、可靠的实时音频录制与存储解决方案。
以上就是修复MediaRecorder实时录音文件损坏问题:关键在于MIME类型配置的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号