如何在Node中代理媒体流?

3
我希望能够代理远程icecast流到客户端。在过去的几天里,我一直在尝试,但没有成功。
使用情况:
能够从<audio>标签的src中提取分析器数据而不会遇到CORS问题。
我的解决方案:
为了解决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
{btsdaf} - Brad
1个回答

4
我找到了一个解决方案,使用流管道。
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);

如果我想在流式转发音频之前对其进行一些处理,有什么解决方案吗?您可能有一个解决方案吗? - Dean Koštomaj
1
是的,我们也可以通过简单的调整来实现这一点,因为我们正在使用管道,我们可以连接2个或多个管道。 例如:假设我们想在发送回目标内容之前压缩它们,我们可以修改我们的管道代码如下。var zlib = require('zlib'); var gzip = zlib.createGzip();req.pipe(request.get(target)).pipe(gzip).pipe(res); - Shivam Gupta
1
如果您需要更多代理控制,可以尝试使用NPM模块-密西西比 - Shivam Gupta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接