我正在尝试从nodejs服务器提供~52MB mp4视频文件。下面附有用于提供文件的代码的屏幕截图。 我有一个mime类型的对象用于静态文件调用,其中包含mp4的mime类型。
var mimeTypes = {
html: 'text/html; charset=utf-8',
jpeg: 'image/jpeg',
jpg: 'image/jpeg',
png: 'image/png',
js: 'text/javascript',
css: 'text/css',
mp4: 'video/mp4'
};
但是,当我尝试导航到chrome中的页面时,我收到错误:
GET http://localhost:8888/videos/movie.mp4 net::ERR_INCOMPLETE_CHUNKED_ENCODING
现在这个相同的逻辑(截图上面)用于提供图像和css就好了,但是在尝试为mp4提供服务时它失败了。查看Chrome中的网络请求面板,我可以看到服务器以200 OK状态响应,并提供零字节文件作为视频。网络请求中的字节范围也看起来很可疑,但我对HTTP请求的了解还不够清楚。
查看stats对象(如下所示,从fs.lstat获得),看起来文件'知道'如何分成4096字节的块,但是我不断得到不完整的chunked编码错误。我没有防病毒软件,并尝试使用其他浏览器关闭Chrome浏览器中的各种设置,但我看不到该视频。
{"dev":16777220,"mode":33188,"nlink":1,"uid":501,"gid":20,"rdev":0,"blksize":4096,"ino":1070608,"size":51246445,"blocks":100096,"atime":"2016-06-15T23:06:27.000Z","mtime":"2016-06-15T21:41:00.000Z","ctime":"2016-06-15T21:45:56.000Z"}
我缺少一个标题吗?我是否过早地以某种方式结束了回应?我现在很无能为力。
答案 0 :(得分:4)
答案 1 :(得分:2)
使用this solution修复。
```
if (stats.isFile()) {
var extension = path.extname(file).split('.').reverse()[0];
if (extension === 'mp4') {
// gotta chunk the response if serving an mp4
var range = req.headers.range;
var parts = range.replace(/bytes=/, "").split("-");
var partialstart = parts[0];
var partialend = parts[1];
var total = stats.size;
var start = parseInt(partialstart, 10);
var end = partialend ? parseInt(partialend, 10) : total - 1;
var chunksize = (end - start) + 1;
var mimeType = mimeTypes[extension] || 'text/plain; charset=utf-8';
res.writeHead(206, {
'Content-Range': 'bytes ' + start + '-' + end + '/' + total,
'Accept-Ranges': 'bytes',
'Content-Length': chunksize,
'Content-Type': mimeType
});
var fileStream = fs.createReadStream(file, {
start: start,
end: end
});
fileStream.pipe(res);
res.on('close', function() {
console.log('response closed');
if (res.fileStream) {
res.fileStream.unpipe(this);
if (this.fileStream.fd) {
fs.close(this.fileStream.fd);
}
}
});
} else {
var mimeType = mimeTypes[extension] || 'text/plain; charset=utf-8';
res.writeHead(200, {'Content-Type': mimeType});
var fileStream = fs.createReadStream(file);
fileStream.pipe(res);
}
return;
}
```
答案 2 :(得分:0)
这对我来说足够了。 MP4原生支持strimming(伪流)。通过流媒体在浏览器中观看视频效果非常好。
res.setHeader('Content-Type', 'video/mp4');
res.status(200).sendFile(full_path, function (err) {
if (err) { ... } else { ... }
});