【问题标题】:Amazon S3 - expressjs read stream runs into timeoutAmazon S3 - expressjs 读取流遇到超时
【发布时间】:2021-06-19 15:50:30
【问题描述】:

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

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

到目前为止我的代码:

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 的问题还是流的一般问题...

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

【问题讨论】:

  • 通过 node.js 传输视频而不是直接从 S3 提供服务的原因是什么?如果出于访问限制原因,您始终可以创建一个预签名的 S3 url。这可能会为您提供更简单的设置。
  • 根据我们产品的部署环境(云/本地),我们希望使用 S3 或本地文件系统来提供视频。到目前为止,该决定发生在系统的后端。但是,如果我们无法处理当前的问题,直接从 S3 提供视频绝对是一种选择。
  • 有道理,不幸的是,我对节点对此类事情的处理知之甚少。只是觉得那里有那个代理很奇怪。但在你的情况下,我可以看到这是有道理的。

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


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2013-09-09
      • 1970-01-01
      • 2015-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-31
      • 1970-01-01
      相关资源
      最近更新 更多