NodeJs 读取视频文件
近期接到项目需求:用户上传自己录制的视频,然后可以在前端查看处理后的视频文件:
- 前端上传视频
- node接收并保存
- node读取视频文件
- node流传输
前端上传
用户录制自己的视频文件,并上传到服务器端:
代码块
前端使用jquery的ajax,核心代码:
var oMyForm = new FormData(); // 创建一个空的FormData对象
var videoBlob = new Blob(recordedBlobs, {
type: 'video/mp4'
}); //blob对象存储视频数据
oMyForm.append("videoData", videoBlob);
oMyForm.append("timeFileName", newFileName);
oMyForm.append("userFileName", fileName);
oMyForm.append("interview", JSON.stringify(interview));
$.ajax({
type: "POST",
url: "/study-video/video/upload",
data: oMyForm,
processData: false, // 告诉jquery不要处理发送的数据
contentType: false, // 告诉jquery不要设置content-Type请求头
success: function (msg) {
//上传中 隐藏
console.log(msg);
}
});
node保存视频文件/读取后-流传输给前端
用户录制自己的视频文件,并上传到服务器端:
代码块
前端使用jquery的ajax,核心代码:
var router = require('express').Router();
var fs = require('fs');
var path = require('path');
const os = require('os');
var config = require('../config/index');
var interviewInner = config.interview.inner;
var proxy = require('../serviceProxy/proxy');
var http = require('http');
var request = require('request');
//busboy 文件处理请求
function handleFiles(req, res, next) {
req.files = {};
req.busboy.on('file', function (fieldName, file, fileName, encoding, mimeType) {
if (!fileName) {
return;
}
file.fileRead = [];
console.log('uploading: ', fileName);
console.log(file);
file.on('data', function (data) {
console.log('File [' + fieldName + '] got ' + data.length + ' bytes');
file.fileRead.push(data);
});
file.on('end', function () {
var finalBuffer = Buffer.concat(this.fileRead);
req.files[fieldName] = {
buffer: finalBuffer,
size: finalBuffer.length,
filename: fileName,
mimetype: mimeType
};
console.log('File [' + fieldName + '] Finished');
});
});
req.busboy.on('field', function (key, value, keyTruncated, valueTruncated) {
console.log(key, '=', value);
req.body[key] = value;
});
req.busboy.on('finish', function () {
console.log('busboy finish');
next();
});
return req.pipe(req.busboy);
}
function composeUrl(host, port, path) {
return 'http://' + host + ':' + port + path;
}
router
.get('/interview/:path', function(req, res, next){
var video_path = decodeURIComponent(req.params.path);
if (video_path.endsWith('.mp4') && fs.existsSync(video_path) && fs.statSync(video_path).isFile()) {
//exists 流传输给前端,前端直接访问route即可
res.set({
"Content-type":"application/octet-stream",
"Content-Disposition":"attachment;filename="+ 'bplus.mp4'
});
var fReadStream = fs.createReadStream(video_path);
fReadStream.on("data",(chunk) => res.write(chunk,"binary"));
fReadStream.on("end",function () {
res.end();
});
}else{
res.send({
msg: 'not found :' + video_path
})
}
})
.post('/video/upload', handleFiles, function(req, res, next){
var interview = JSON.parse(req.body.interview);
var base = config.ugcVideoFolder;
if (!base) {
base = os.tmpdir();
}
//save video
var tmp_path1 = path.join(base, path.basename(req.body.timeFileName + '.mp4'));
fs.writeFileSync(tmp_path1, req.files['videoData'].buffer);
//save audio
var tmp_path2 = path.join(base, path.basename(req.body.timeFileName + '.wav'));
fs.writeFileSync(tmp_path2, req.files['audioData'].buffer);
//POST 传给后台,body的数据格式
var interviewData = {
interview_name: interview.interview_name,
member_id: res.locals.hcd_user.member_id || 'c7b6d3fb-32ea-4606-8358-3b7c70fb1dea',
interview_time: new Date(),
file_name: req.body.userFileName,
questions: [
{
question_num: 1,
question_description: "自我介绍",
video_path: tmp_path1,
video_name: req.body.timeFileName + '.mp4',
audio_path: tmp_path2,
audio_name: req.body.timeFileName + '.wav',
video_length: interview.questions[0].upload_time
}
]
};
//调用interview-service 保存数据 请求第三方server
request({
url: composeUrl(interviewInner.host, interviewInner.port, '/interview-info/upload'),
method: "POST",
json: false,
headers: {
"content-type": "application/json"
},
body: JSON.stringify(interviewData)
}, function (err, data) {
if(err){
res.send({
msg: 'server error'
});
}else{
res.send(data);
}
});
})
;
module.exports = router;
记录工作中学习的一些新东西,截取项目中部分核心代码。