1

我尝试使用 ytdl-core 模块获取纯音频 youtube 视频,并使用 express node.js 对其进行流式传输,它适用于除 safari(iOS safari)之外的所有浏览器。我确实使用了字节范围响应,但仍然出现错误。
这里的服务器端代码:

app.get("/stream/:videoId", async (req, res) => {
  const {videoId} = req.params;
  const isValid = ytdl.validateID(videoId);

  if (!isValid) {
    throw new Error();
  }

  const videoInfo = await ytdl.getInfo(videoId);
  let audioFormat = ytdl.chooseFormat(videoInfo.formats, {
    filter: "audioonly",
    quality: "highestaudio"
  });

  const {itag, container, contentLength} = audioFormat;

  var start;
  var end;
  var total = 0;
  var contentRange = false;
  var content_length = 0;

  var range = req.headers.range;
  if (range) {
    var positions = range.replace(/bytes=/, "").split("-");
    start = parseInt(positions[0], 10);
    total = contentLength;
    end = positions[1] ? parseInt(positions[1], 10) : total - 1;
    var chunksize = end - start + 1;
    contentRange = true;
    content_length = chunksize;
  } else {
    start = 0;
    end = contentLength;
    content_length = contentLength;
  }

  if (start <= end) {
    var responseCode = 200;
    var responseHeader = {
      "Accept-Ranges": "bytes",
      "Content-Length": content_length,
      "Content-Type": `audio/${container}`
    };
    if (contentRange) {
      responseCode = 206;
      responseHeader["Content-Range"] = "bytes " + start + "-" + end + "/" + total;
    }
    res.writeHead(responseCode, responseHeader);

    const range = {start: start, end: end};

    var stream = ytdl(videoId, {filter: format => format.itag === itag, range})
      .on("readable", function () {
        var chunk;
        while (null !== (chunk = stream.read(1024))) {
          res.write(chunk);
        }
      })
      .on("error", function (err) {
        res.end(err);
      })
      .on("end", function (err) {
        res.end();
      });
  } else {
    return res.status(403).send();
  }
});

并通过以下方式获取流音频:
<audio src="/stream/<youtube-video-ID>" controls></audio>

在标头 safari 字节范围请求中是 0-1,然后是 0-allbyte,这是一个错误吗?在 Firefox 浏览器中,请求是 0- 然后是 xxxx-allbyte。我不知道这有什么关系,我不太了解 HTTP 是如何工作的。请帮忙,谢谢

4

0 回答 0