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

Node服务器如何将RecordRTC生成的音视频Blob写入为有效文件?

解决Node服务器写入RecordRTC Blob为有效视频文件的问题

我来帮你搞定这个问题!RecordRTC生成的Blob要转成服务器上可正常播放的视频文件,核心在于前端正确封装传输数据和后端正确处理二进制流,下面分步骤给你详细说明:

一、前端修正发送方式(关键!)

Angular的$http.post直接发送Blob容易出现Content-Type不匹配的问题,必须用FormData来包装Blob和其他标识数据,让浏览器自动处理multipart/form-data的传输格式:

// Angular前端代码示例
var formData = new FormData();
// 把RecordRTC生成的Blob加入FormData,第三个参数是文件名(可选但建议设置)
formData.append('videoBlob', yourRecordedBlob, 'user-recording.webm');
// 添加其他标识数据,比如用户ID、录制时间等
formData.append('userId', 'user_12345');
formData.append('recordTime', Date.now());

$http.post('/api/upload-video', formData, {
  transformRequest: angular.identity,
  // 必须设置为undefined,让浏览器自动生成正确的multipart/form-data请求头
  headers: {'Content-Type': undefined}
}).then(function(res) {
  console.log('上传成功!', res.data);
}, function(err) {
  console.error('上传失败:', err);
});

二、后端处理方案(两种常用方式)

方式1:用Multer快速处理(推荐,简洁高效)

Multer是Node.js专门处理multipart/form-data的中间件,能自动帮你解析文件并写入磁盘:

  1. 先安装依赖:
npm install multer --save
  1. 服务器代码示例:
const express = require('express');
const multer = require('multer');
const fs = require('fs');
const app = express();

// 确保uploads文件夹存在,不存在则创建
const uploadDir = './uploads';
if (!fs.existsSync(uploadDir)) {
  fs.mkdirSync(uploadDir, { recursive: true });
}

// 配置Multer的存储规则:路径+文件名
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, uploadDir);
  },
  filename: function (req, file, cb) {
    // 用用户ID+时间戳命名,避免文件重名
    const userId = req.body.userId;
    // RecordRTC默认生成webm格式,若你录制的是其他格式(如mp4),记得改后缀
    cb(null, `${userId}_${Date.now()}.webm`);
  }
});

const upload = multer({ storage: storage });

// 处理上传请求,upload.single('videoBlob')对应FormData里的key
app.post('/api/upload-video', upload.single('videoBlob'), (req, res) => {
  // req.file是上传的文件信息,req.body是你传的其他标识数据
  console.log('文件已保存到:', req.file.path);
  console.log('关联用户ID:', req.body.userId);
  
  res.status(200).json({
    success: true,
    message: '视频文件已保存',
    filePath: req.file.path
  });
});

app.listen(3000, () => {
  console.log('服务器运行在 http://localhost:3000');
});

方式2:手动用Busboy处理流(适合理解底层原理)

如果你不想用Multer,也可以用Busboy手动解析请求流并写入文件:

  1. 安装依赖:
npm install busboy --save
  1. 服务器代码示例:
const express = require('express');
const Busboy = require('busboy');
const fs = require('fs');
const path = require('path');
const app = express();

const uploadDir = './uploads';
if (!fs.existsSync(uploadDir)) {
  fs.mkdirSync(uploadDir, { recursive: true });
}

app.post('/api/upload-video', (req, res) => {
  const busboy = new Busboy({ headers: req.headers });
  let userId = '';
  let writeStream = null;

  // 处理表单里的非文件字段(比如userId)
  busboy.on('field', (fieldname, val) => {
    if (fieldname === 'userId') {
      userId = val;
    }
  });

  // 处理文件流
  busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
    const saveFileName = `${userId}_${Date.now()}.webm`;
    const savePath = path.join(uploadDir, saveFileName);
    
    // 创建写入流,把上传的文件流pipe到磁盘
    writeStream = fs.createWriteStream(savePath);
    file.pipe(writeStream);

    file.on('end', () => {
      writeStream.end();
      console.log('文件写入完成:', savePath);
    });
  });

  // 所有数据处理完成
  busboy.on('finish', () => {
    res.status(200).json({
      success: true,
      message: '视频上传成功',
      filePath: saveFileName
    });
  });

  // 处理上传错误
  busboy.on('error', (err) => {
    console.error('上传出错:', err);
    res.status(500).json({ success: false, error: '上传失败' });
  });

  req.pipe(busboy);
});

app.listen(3000, () => {
  console.log('服务器运行在 http://localhost:3000');
});

三、常见问题排查

如果按上面操作后视频还是无法播放,检查这几点:

  • 前端Blob有效性:在前端用URL.createObjectURL(yourRecordedBlob)生成预览链接,确认录制的视频本身是正常的。
  • 文件格式匹配:RecordRTC默认生成webm格式,保存时后缀要对应;如果是mp4格式,要确保录制时配置了正确的编码器。
  • 文件完整性:对比前端Blob的大小和服务器保存文件的大小,确认传输过程中没有数据丢失。

内容的提问来源于stack exchange,提问作者tejkweku

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:15:49