S3 视频未在 iOS 上使用 React 进行流式传输

S3 video not streaming on iOS with React

正如标题所说,我有一些视频保存在 s3 存储桶中。我将我的 nodejs 设置为在我的 React 应用程序上流式传输它。它在除 iOS 以外的所有设备上都能正常工作。我做了一些搜索,但找不到问题。服务器将初始字节请求返回为 206。我检查了 headers 但找不到问题: 这是我的节点: 到达路径后:

 if (!range) {
      res.status(400).send("returning err!");
      return;
    }
    s3.headObject({
      Bucket: process.env.AWS_BUCKET_NAME,
      Key: req.params.key
    }, function (err, data) {
      if (err) {
        // an error occurred
        console.error(err);
        return res.status(500).send("returning err");
      }
      
      const videoSize = Number(data.ContentLength);
      const CHUNK_SIZE = 10 ** 6;  // 1MB
      const start = Number(range.replace(/\D/g, ""));
      const end = Math.min(start + CHUNK_SIZE, videoSize - 1);


      var params = {
        Bucket: process.env.AWS_BUCKET_NAME,
        Key: req.params.key,
        Range: range,
      };
      var stream = s3.getObject(params).createReadStream();

      res.status(206);
      res.set('Content-Type', data.ContentType);
      res.set('Content-Disposition','inline');
      res.set('Accept-Ranges','bytes');
      res.set('Accept-Encoding', 'Identity');
      res.set('Content-Range',  'bytes ' + start + '-' + end + '/' + videoSize);
      res.set('Content-Length', data.ContentLength);
      res.set('X-Playback-Session-Id', req.header('X-Playback-Session-Id')); // Part of the attempt to fix
      res.set('Connection', 'keep-alive');
      res.set('Last-Modified', data.LastModified);
      res.set('ETag', data.ETag);
      stream.pipe(res);

这是我的前端 React 播放器代码:

    <ReactPlayer
      ref={player}
      // onProgress={onProgress}
      playsinline={true}
      url={[{ src: source, type: 'video/mp4;' }]} // video location
      controls  // gives the front end video controls 
      width='100%'
      className='react-player'
      height='100%'
      allow='autoplay; encrypted-media'
      allowFullScreen
      // muted={true}
      playing={playing}
      onPlay={() => setPlaying(true)}
      // onPause={() => setPlaying(false)} //part of the attempt to fix
      // onSeek={(seek) => playerSeeker(seek)} //part of the attempt to fix
      config={{
        file: {
          attributes: {
            controlsList: 'nodownload'
          }
        }
      }}
      onContextMenu={e => e.preventDefault()}
      onEnded={(e) => onVideoEnded(e)}
      onError={(e) => onVideoError(e)}
    />

同样,iOS 上的第一个请求返回 206 成功,但节点总是在开始播放之前结束流。

原来只是

  res.set('Content-Length', data.ContentLength);

我需要 return 计算范围的长度,而不是发送视频的完整长度。