PHP接收WebRTC Blob视频上传MySQL的代码排错与实现
WebRTC Blob视频上传问题排查与实现方案
现有代码错误点
- 前端传参错误:
URL.createObjectURL()生成的是本地虚拟访问字符串,不是Blob二进制对象,直接传入FormData只会上传一段字符串,无法得到有效文件。 - 前后端字段不匹配:前端上传的文件字段名为
data、文件名字段名为fname,后端却在读取video-blob/audio-blob文件字段、video-filename/audio-filename文件名字段,双方字段完全对不上,自然无法接收数据。 - 后端缺少必要校验:没有判断上传目录是否存在、是否有写入权限,也没有捕获PHP文件上传的错误码,出现问题无法定位原因。
- 存储方案误区:不建议将视频二进制内容直接存入MySQL,大文件存入数据库会大幅拖慢查询性能,常规方案是将视频文件存在服务器磁盘,数据库仅存储文件路径、文件名、上传时间等元数据。
修正后的前端代码
// 直接获取录制生成的Blob对象,不要转成ObjectURL const videoBlob = recorder.getBlob(); const formData = new FormData(); // 字段名和后端保持一致 formData.append('video-filename', 'test.mp4'); // 传入Blob对象本身,第三个参数指定上传文件名 formData.append('video-blob', videoBlob, 'test.mp4'); $.ajax({ type: 'POST', url: '../../application/controllers/upload.php', data: formData, processData: false, contentType: false, success: function(res) { console.log('上传返回:', res); alert(res.msg); }, error: function(err) { console.error('上传请求失败:', err); } });
修正后的PHP服务端代码
<?php header('Content-Type: application/json'); $res = ['code' => 0, 'msg' => '', 'data' => []]; // 定义上传目录,提前创建该目录并设置755权限 $uploadDir = __DIR__ . '/uploads/'; if (!is_dir($uploadDir)) { mkdir($uploadDir, 0755, true); } foreach (['video', 'audio'] as $type) { $fileField = "${type}-blob"; $nameField = "${type}-filename"; // 校验文件是否上传成功 if (isset($_FILES[$fileField]) && $_FILES[$fileField]['error'] === UPLOAD_ERR_OK) { $fileName = $_POST[$nameField] ?? uniqid() . '.mp4'; // 过滤特殊字符,防止路径穿越漏洞 $fileName = str_replace(['/', '\\', '..'], '', $fileName); $targetPath = $uploadDir . $fileName; if (move_uploaded_file($_FILES[$fileField]['tmp_name'], $targetPath)) { $res['code'] = 1; $res['msg'] = '上传成功'; $res['data'] = [ 'file_name' => $fileName, 'file_path' => 'uploads/' . $fileName ]; // MySQL写入逻辑(仅存元数据,不存文件本体) // 替换成你自己的数据库配置 // $conn = new mysqli('127.0.0.1', '数据库用户名', '数据库密码', '数据库名'); // if ($conn->connect_error) { // $res['msg'] = '文件上传成功,数据库连接失败:' . $conn->connect_error; // echo json_encode($res); // exit; // } // $conn->set_charset('utf8mb4'); // $stmt = $conn->prepare("INSERT INTO video_records (file_name, file_path, upload_time) VALUES (?, ?, NOW())"); // $stmt->bind_param("ss", $fileName, $res['data']['file_path']); // $stmt->execute(); // $stmt->close(); // $conn->close(); } else { $res['msg'] = '文件写入失败,请检查uploads目录权限'; } echo json_encode($res); exit; } } $res['msg'] = '未接收到有效上传文件'; echo json_encode($res); ?>
配置注意事项
- 在
upload.php同级目录手动创建uploads文件夹,将文件夹权限设置为755,保证PHP运行身份有写入权限。 - 文件名后缀需要和实际录制格式匹配:如果
MediaRecorder输出的是webm格式,后缀要改为.webm,强行修改后缀为mp4会导致文件无法正常播放。 - 如果需要上传大体积视频,需要修改php.ini配置:调大
upload_max_filesize、post_max_size参数值,延长max_execution_time超时时间,必要时可以加分片上传逻辑。
内容的提问来源于stack exchange,提问作者osas divine
相关产品推荐
相关产品推荐

