0

我正在尝试从 Amazon S3 存储桶流式传输视频。

如果我只调用一次 REST 端点,流式传输就可以正常工作。但是如果我想同时从多个浏览器流式传输视频,我会收到以下错误: TimeoutError: Connection timed out after 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 的问题还是流的一般问题......

我究竟做错了什么?有没有人遇到同样的问题?

4

2 回答 2

0

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

于 2018-05-02T13:47:00.987 回答
0

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

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

于 2021-06-19T07:50:30.973 回答