如何从能够搜索的谷歌云存储对象中获取视频流

Posted

技术标签:

【中文标题】如何从能够搜索的谷歌云存储对象中获取视频流【英文标题】:How to get a video stream from google could storage object that is able to seek 【发布时间】:2021-02-07 06:30:12 【问题描述】:

我正在从 express.js 服务器中的云存储桶流式传输视频文件,并且能够成功地将该流传输到前端的视频元素。但是,由于视频内容现在是逐步加载的,我无法在加载的视频中进行搜索。

我的从云存储对象获取视频流的node.js代码如下。

async function getVideoStream(gcloudFileName,res)
  const bucket = storage.bucket(process.env.GCS_BUCKET);
  const remoteFile = bucket.file(gcloudFileName);
  return remoteFile.createReadStream().pipe(res)

我怎样才能让这个视频流可以被搜索,以便用户可以在前端搜索视频? 非常感谢有用的建议。

编辑:

我尝试了@Rafael 的回答,并在一定程度上让它发挥了作用,但现在的问题是在传送视频的前几块后流停止了。同时,视频也停止播放。

【问题讨论】:

Http 范围请求。 【参考方案1】:

您需要使用范围请求,如@szatmary 评论中所述,以便服务器可以一次发送文件的块而不是整个文件,您可以在this article 中找到完整的解释,但适用于您的代码可以执行以下操作:

async function getVideoStream(req,res)
  const range = req.headers.range;
  if (!range) 
    res.status(400).send("Requires Range header");
  
  const bucket = storage.bucket(process.env.GCS_BUCKET);
  // I added the file name to your request's body
  const remoteFile = bucket.file(req.body);

  //calculates the chunck to be sent based on the video size
  const videoSize = remoteFile.getMetadata().size;
  const CHUNK_SIZE = 10 ** 6; // 1MB
  const start = Number(range.replace(/\D/g, ""));
  const end = Math.min(start + CHUNK_SIZE, videoSize - 1);

  // Create headers
  const contentLength = end - start + 1;
  const headers = 
    "Content-Range": `bytes $start-$end/$videoSize`,
    "Accept-Ranges": "bytes",
    "Content-Length": contentLength,
    "Content-Type": "video/mp4",
  ;

  // HTTP Status 206 for Partial Content
  res.writeHead(206, headers);

  //returns the chunk that you want
  return remoteFile.createReadStream( start, end ).pipe(res)

【讨论】:

@rafael 感谢您对示例代码的详细回答。现在只有我有时间来测试这个。我有点困惑,因为 headers 对象没有在任何地方使用。你能告诉我如何将它提供给createReadStream 函数吗? 实际上我忘了添加将其添加到响应中的行,对此感到抱歉,您可以在共享链接的示例中看到它。我将它添加到代码示例中。 你好@rafael,我已经尝试了你提供的代码示例几天,但只有第一块视频正在播放,之后视频完全没有加载。你能给我一些建议来避免这个问题吗?如果您认为合适,我会提出另一个问题。 我还使用最新的故障排除详细信息编辑了问题。如果您可以查看它,将会有很大的帮助。谢谢。 @RafaelLemos 知道如何调试它吗?由于某种原因,我无法加载视频,并且永远不会调用 on('error') 回调。

以上是关于如何从能够搜索的谷歌云存储对象中获取视频流的主要内容,如果未能解决你的问题,请参考以下文章

带有 gspythonlibrary 的谷歌云存储

访问谷歌云存储的应用引擎项目的默认凭据?

从谷歌云存储获取状态 503

用户多台设备上的谷歌云消息通知

无法上传文件到生产中的谷歌云存储

Android 中的谷歌云消息服务如何工作?