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的中间件,能自动帮你解析文件并写入磁盘:
- 先安装依赖:
npm install multer --save
- 服务器代码示例:
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手动解析请求流并写入文件:
- 安装依赖:
npm install busboy --save
- 服务器代码示例:
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
相关产品推荐
相关产品推荐

