Amazon S3 - expressjs读取流进入超时

时间:2018-04-20 12:23:34

标签: javascript express amazon-s3 video-streaming aws-sdk-js

我正在尝试从Amazon S3 Bucket流式传输视频。

如果我只调用一次REST端点,则流可以正常工作。但是,如果我想同时从多个浏览器流式传输视频,我会收到以下错误: TimeoutError:120000ms后连接超时

到目前为止我的代码:

var express = require("express");
var fs = require("fs");
var app = express();
var path = require("path");
var AWS = require("aws-sdk");

app.get("/video", function(req, res, next) {
res.set({
    "Accept-Ranges": "bytes",
    "Content-Type": "video/mp4",
    "Content-Length": 41811600,
    "Cache-Control": "max-age=31536000"
});

var stream;
if (req.headers.range) {
    const size = 41811600;
    const parts = req.headers.range.replace(/bytes=/, "").split("-");
    const start = parseInt(parts[0], 10);
    const end = parts[1] ? parseInt(parts[1], 10) : size - 1;
    const length = end - start + 1;
    res.set({
    "Content-Range": `bytes ${start}-${end}/${size}`,
    "Content-Length": length
    });
    stream = getReadStream(start, end);
} else {
    stream = getReadStream(undefined, undefined);
}
res.writeHead(res.getHeader("Content-Range") ? 206 : 200);
return stream.pipe(res);
});

function getReadStream(startByte, endByte) {
const params = {
    Bucket: "s3-fancy-test-bucket",
    Key: path.join(
    "SOME_KEY"
    ),
    Range: "bytes=" + (startByte || 0) + "-" + (endByte || "")
};
const stream = getS3Instance()
    .getObject(params)
    .createReadStream();
stream.on("error", err => {
    console.error(`Unable to get File Stream for ${params.Key} - ${err}`);
});
return stream;
}

function getS3Instance() {
AWS.config.update({
    accessKeyId: "ACCESS_KEY_ID",
    secretAccessKey: "SECRET",
    signatureVersion: "v4",
    region: "eu-central-1"
});
return new AWS.S3({ apiVersion: "2006-03-01" });
}

app.listen(process.env.PORT || 3000);

我不太确定这是aws-sdk-js的问题还是流的一般问题......

我做错了什么? 是否有人遇到过同样的问题?

2 个答案:

答案 0 :(得分:0)

与此同时,我发现,上述行为在很大程度上取决于视频的创建方式。我使用 ffmpeg 将视频转换为mp4。使用快速入门标志转换视频会对范围请求数量产生很大影响。一旦我有了faststart标志,浏览器的范围请求就会少得多,以便加载视频。 由于现在请求较少,express / aws-sdk似乎能够处理它。不再有超时。

答案 1 :(得分:0)

我们正在尝试完全相同的事情,只是因为我们希望在将视频流式传输给用户之前限制通过后端访问视频。因此,直接从 s3 提供视频不是一种选择。我意识到视频流传输得很好,但即使在流成功结束后,getObject() 也会超时 120000 毫秒(aws 默认超时持续时间)。 aws-sdk 存储库中似乎存在与此相关的活跃问题,但仍未解决。

https://github.com/aws/aws-sdk-js/issues/2087