我正在尝试使用 gridfs-stream 构建一个非常基本的视频上传系统。它可以在桌面上运行,但只能在我的手机上部分运行(iOS9 iphone 5,使用 Chrome 浏览器)。
它使用 iOS 的直接录制功能完美运行(录制不在照片库中且不保存的视频),但是当我尝试在照片库中选择已保存的视频时,视频无法正确上传。
- 在写入数据库之前保存到临时目录时,文件为空(大小:0kb)
- fs.chunks 集合中没有保存任何块
- fs.files 集合中的“length”属性为 0
- 它不显示,就像文件不存在一样。
这是代码:
function saveVideo(file){
var name = file.filename.split('.').slice(0, -1),
extension = file.filename.split('.').pop(),
randomString = Math.random().toString(36).substring(7);
file.filename = name + '_' + randomString + '.' + extension;
var writeStream = gridFs.createWriteStream({
filename: file.filename,
metadata: {
validated: false
}
});
fs.createReadStream(file.file).pipe(writeStream);
writeStream.on('close', function(){
fs.unlink(file.file);
});
}
app.post('/addVideo', function(req, res){
var files = req.files['file-input'];
if (files.length){
files.forEach(function (file, index){
saveVideo(file);
if (index == files.length - 1){
res.redirect('/admin')
}
});
}
else {
if (files.filename){
saveVideo(files);
}
res.redirect('/admin');
}
});
app.get('/videos/:filename', function(req, res){
gridFs.exist({'filename': req.params.filename}, function(err, found){
if (err){
return next(err);
}
if (found){
var readStream = gridFs.createReadStream({
filename: req.params.filename
});
readStream.pipe(res);
}
else {
res.status(404).send('Not Found');
}
});
});
我想过的事情:
使用照片而不是视频确实有效,但我需要我的 web 应用程序才能接收视频。
也许直接录制和从图库中选择视频之间存在差异?我真的不明白,因为除了iOS自动分配的名称外,我看不到任何名称。我试图强制使用特定的 mimetype/编码,但我不确定如何去做,也没有设法让它工作。(老实说,我什至不确定它是如何工作的)
使用其他浏览器:奇怪的是,当使用 Safari 而不是 Chrome 移动设备时,文件在写入数据库之前会正确放入 temp 目录。之后无法正确显示(视频大小不正确,并且有黑色背景占位符,就像视频不存在一样,但我可以右键单击 chrome 检查器中的链接并在新窗口中打开它,导致文件下载。视频没有损坏,文件不是“空的”,数据库中的长度属性也不是从 Chrome 上传时的状态(视频确实有效)。
如果有帮助,当使用直接记录功能在 Chrome 上提交我的表单时,它会重新加载页面并且输入为空。从图库中选择文件时,它会花费更多时间,但它不会重新加载页面并且文件仍在输入中,就好像它没有做任何事情一样。加载栏确实出现并停在中间。这是我正在使用的代码。我尝试了多个版本(例如使用 capture 属性),但没有奏效。我正在使用 express-busboy 模块来解码表单的数据。
<form action="/addVideo" method="POST" enctype="multipart/form-data">
<input type="file" accept="video/*" multiple name="file-input"/>
<input type="submit"/>
</form>
- 我尝试使用 connect-busboy 模块而不是 express-busboy (在添加文件之前它不会写入文件,它直接将其流式传输到数据库),但问题仍然存在。
谢谢。