You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 22:54:25