如何在Node中代理媒体流?

时间:2017-10-23 23:05:09

标签: node.js proxy stream audio-streaming icecast

我希望能够将远程icecast流代理到客户端。在过去的几天里我一直在摆弄很多东西而无济于事。

用例

能够从<audio>标记src中提取分析数据,而不会遇到CORS问题。

到目前为止我的解决方案

为了解决阻止我直接从<audio>源创建杠杆声音数据的CORS问题,我尝试编写一个小代理,将请求传递给特定的流并返回静态在任何其他情况下。 这是我的代码:

require('dotenv').config();
const http = require('http');

const express = require('express');

const app = express();

const PORT = process.env.PORT || 4000;

let target = 'http://direct.fipradio.fr/live/fip-midfi.mp3';
// figure out 'real' target if the server returns a 302 (redirect)
http.get(target, resp => {
  if(resp.statusCode == 302) {
    target = resp.headers.location;
  }
});

app.use(express.static('dist'));

app.get('/api', (req, res) => {
  http.get(target, audioFile => {
    res.set(audioFile.headers);

    audioFile.addListener('data', (chunk) => {
      res.write(chunk);
    });
    audioFile.addListener('end', () => {
      res.end();
    });
  }).on('error', err => {
    console.error(err);
  });
});

app.listen(PORT);

问题

客户端收到来自代理的响应,但是尽管被代理收到,但是这个响应被停止到60kb的数据并且没有收到后续的块:

enter image description here

enter image description here

欢迎任何建议!

1 个答案:

答案 0 :(得分:1)

我找到了解决方案,使用流水管道。

const app = express();

const PORT = process.env.PORT || 4000;

let target = 'http://direct.fipradio.fr/live/fip-midfi.mp3';
// figure out 'real' target if the server returns a 302 (redirect)
http.get(target, resp => {
  if(resp.statusCode == 302) {
    target = resp.headers.location;
  }
});

app.use(express.static('dist'));

app.get('/api', (req, res) => {
  req.pipe(request.get(target)).pipe(res);
});

app.listen(PORT);