Javascript 视频流不适用于iOS/Safari

Javascript 视频流不适用于iOS/Safari,javascript,ios,node.js,html,Javascript,Ios,Node.js,Html,我有一个web应用程序,它依赖于第三方对象存储(SoftLayer)来提供视频文件。当用户请求视频时,my node.js-server从对象存储中获取文件并将其流式传输到客户端。我有适用于Android和Firefox浏览器以及桌面机器上Chrome浏览器的代码。不幸的是,该视频没有在Safari/iOS中播放 node.js-code的简化版本(从w3c网站流式传输视频)如下所示: router.get('/testFile', function (req, res) { var ran

我有一个web应用程序,它依赖于第三方对象存储(SoftLayer)来提供视频文件。当用户请求视频时,my node.js-server从对象存储中获取文件并将其流式传输到客户端。我有适用于Android和Firefox浏览器以及桌面机器上Chrome浏览器的代码。不幸的是,该视频没有在Safari/iOS中播放

node.js-code的简化版本(从w3c网站流式传输视频)如下所示:

router.get('/testFile', function (req, res) {
  var range = req.headers.range;
  var positions = range.replace(/bytes=/, "").split("-");
  var start = parseInt(positions[0], 10);

  var objectPath = "http://www.w3schools.com/html/mov_bbb.mp4"
    request.get({
      url: objectPath,
      headers: {},
      encoding: null
    }, function (err, data) {
      if (err) {
        console.log('error', err);
      }else {
        var total = data.body.length;
        var end = positions[1] ? parseInt(positions[1], 10) : total - 1;
        var chunksize = (end - start) + 1;
        console.log("bytes " + start + "-" + end + "/" + total);
        res.writeHead(206, {
          "Content-Range": "bytes " + start + "-" + end + "/" + total,
          "Accept-Ranges" : "bytes",
          "Content-Length": chunksize
        });
        var bodyStream = new streambuffers.ReadableStreamBuffer({
          frequency: 1,
          chunksize: 256
        });
        bodyStream.pipe(res);
        bodyStream.put(data.body);
      }
    });
});
“/testFile”然后用作HTML5视频播放器的src:

<!DOCTYPE html>
<html>
  <head>
    <title>Movie</title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1>Test video</h1>
    <video controls="true" preload="none">
      <source src="/testFile" type="video/mp4"/>
    </video>
  </body>
</html>

电影
测试视频
此简单项目可在此处检出:


要运行它,只需运行“node bin/www”并浏览到即可。

iOS非常注重视频的服务方式

承载iOS媒体文件的HTTP服务器必须支持字节范围 请求,iOS用于在媒体播放中执行随机访问

如果不确定媒体服务器是否支持字节范围请求,可以使用curl命令行工具从服务器上的文件下载一小段:

curl --range 0-99 http://example.com/test.mov -o /dev/null
如果工具报告已下载100字节,则媒体服务器将正确处理字节范围请求

确保HTTP服务器为电影文件扩展名发送正确的MIME类型

扩展MIME类型

  • .mov:视频/快速时间
  • .mp4:视频/mp4
  • .m4v:视频/x-m4v
  • .3gp:视频/3gpp

另请参阅我的答案。

我不会尝试自己在节点中重新创建流媒体服务器

服务器性能会很差 使用您拥有的代码,您的应用服务器将首先从SoftLayer下载完整文件,然后从RAM将其流式传输到客户端。这对于大量文件或客户端来说都是不可持续的

在全球范围内行动缓慢 如果您的服务器位于布鲁塞尔,则不同大陆上的每个客户机都会看到传输缓慢。在移动网络上,这将是一件特别痛苦的事情,而移动网络大概就是您想要获得最佳性能的地方

流媒体很难 使用最好的工具来完成这项工作。您不会在几行节点中创建尽可能最好的流媒体服务器。相信像NGINX这样的专用HTTP服务器可以为您解决这个问题。此外,您没有编写的代码中不可能有bug

建议:
使用。它是专门为解决您的问题而构建的。注:我与他们无关。如果您的内容在S3上,我建议您使用CloudFront。这里的关键是将CDN用于流式视频。

为什么不直接响应304重定向到视频?在我的情况下,这是不可能的,因为文件托管在SoftLayer上。我的客户端没有登录SoftLayer的凭据。在我在这里发布的示例中,这是可能的,因为w3c是一个公共链接,但在实际项目中,这不是一种可能的方法。为什么不在请求中传递范围标头,然后将其传递给res?谢谢您的回答。我将正确的头添加到与请求一起传递的headers对象(头:{'content-type':'video/mp4'})。我还认为媒体服务器正确地处理字节范围请求。这是CURL工具的输出:我不完全确定,但我认为这是正确的输出?不幸的是,在Safari中仍然没有运气。虽然信息很好,但这并不能回答问题