javascript - Node.js如何流式传输音频文件

标签 javascript node.js google-chrome http audio

我有一个 node.js,我想将音频文件流式传输到浏览器。这是我处理它的路线:

routes['/v1/tracks/:id/file'] = {
  get: async (ctx, next) => {
    let tracks = await File.find({
      trackId: ctx.params.id,
      sort: 'bitrate',
      direction: 'desc',
      limit: 3
    });
    let stat = fs.statSync(tracks[0].data.path);
    let mimeType = 'audio/mpeg';

    let opts = {}, res = 200;

    let resHeaders = {
      'Content-Type': mimeType,
      'Content-Length': stat.size,
      'Accept-Ranges': 'bytes'
    };
    if (ctx.headers.accept !== '*/*') {
      ctx.res.writeHead(200, resHeaders);
      return;
    }
    if (ctx.headers['range']) {
      let [b, range] = ctx.headers['range'].split('=');
      console.log(b, range);
      if (b === 'bytes') {
        let [start, end] = range.split('-');

        if (!end || end === '' || end < start)
          end = stat.size;

        opts = {
          start: start - 0,
          end: end - 0
        };

        res = 206;
        resHeaders['Content-Range'] = `bytes ${start}-${end}/${stat.size}`;
      }
    }
    ctx.res.writeHead(res, resHeaders);

    ctx.body = fs.createReadStream(tracks[0].data.path, opts);
  }
}

然后,当我尝试访问 chrome 中的 URL 时,它会发送两个请求。

第一:
Request Headers:
    GET /v1/tracks/ghHxLPNt8Fayfx1d/file HTTP/1.1
    Host: localhost:3000
    Connection: keep-alive
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    Accept-Encoding: gzip, deflate, sdch, br
    Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Response Headers:
    HTTP/1.1 200 OK
    X-Powered-By: Express
    Content-Type: audio/mpeg
    Content-Length: 5986643
    Accept-Ranges: bytes
    Date: Fri, 23 Dec 2016 14:09:27 GMT
    Connection: keep-alive

第二个:
Request headers:
    GET /v1/tracks/ghHxLPNt8Fayfx1d/file HTTP/1.1
    Host: localhost:3000
    Connection: keep-alive
    Accept-Encoding: identity;q=1, *;q=0
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36
    Accept: */*
    Referer: http://localhost:3000/v1/tracks/ghHxLPNt8Fayfx1d/file
    Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
    Range: bytes=0-
Response headers:
    HTTP/1.1 206 Partial Content
    X-Powered-By: Express
    Content-Type: audio/mpeg
    Content-Length: 5986643
    Accept-Ranges: bytes
    Content-Range: bytes 0-5986643/5986643
    Date: Fri, 23 Dec 2016 14:09:28 GMT
    Connection: keep-alive

但是它不起作用。 Chrome 只显示带有播放按钮的空白轨道,但没有显示轨道长度,我无法与之交互。 Safari 只显示加载。

编辑:

如果我删除一堆代码(关于部分内容的所有内容),我可以让它工作,但它不会让我进入一个位置,只能从头到尾播放它。我也可以使用我在此处编写的代码(Ctrl + S)下载它,然后正常播放

最佳答案

经过大量挖掘终于确定,单个字节是问题的原因。

新代码:

if (ctx.headers['range']) {
  let [b, range] = ctx.headers['range'].split('=');
  console.log(b, range);
  if (b === 'bytes') {
    let [start, end] = range.split('-');

    if (!end || end === '' || end < start)
      end = stat.size - 1;

    opts = {
      start: start - 0,
      end: end - 0
    };

    res = 206;
    resHeaders['Content-Range'] = `bytes ${start}-${end}/${stat.size}`;
    resHeaders['Content-Length'] = end - start + 1;
  }
}

另见 Streaming a video file to an html5 video player with Node.js so that the video controls continue to work?

关于javascript - Node.js如何流式传输音频文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41303102/

相关文章:

javascript - Node.js:Mongoose 的内部服务器错误

javascript - Meteor jQuery 插件由 onRendered 初始化

javascript - 在 mongodb 中使用 $inc 和 $addToSet

javascript - JavaScript 中字符串连接的性能很糟糕?

node.js - 编写自己的 Node.js 回调的最佳实践是什么?

html - Chrome 信用卡到期自动填充格式

jquery - 使用输入元素上的修饰键触发单击事件

javascript - 从chrome打包的应用程序写入的文件都是空的

javascript - 如何向 JavaScript Date 对象添加年、月、日、小时、分钟或秒?

javascript - JS 不断更新网格中的 CSS 背景颜色 - 关闭?