Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to proxy a media stream in Node?

I want to be able to proxy a remote icecast stream to client. I've been fiddling around a lot in the past few days to no avail.

Use case:

Be able to extract analyser data out of an <audio> tag src without running into CORS issues.

My solution so far

In order to address CORS issues preventing me to create an leverage sound data directly out of the <audio>'s source, I've tried to write a tiny proxy which would pipe requests to a specific stream and return statics in any other case. Here is my code:

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);

The problem

The client receives a response from the proxy but this gets stalled to 60kb of data about and subsequent chunks are not received, in spite of being received by the proxy:

enter image description here

enter image description here

Any suggestion is welcome!

like image 618
Tristan Hamel Avatar asked Mar 12 '26 06:03

Tristan Hamel


1 Answers

I've found a solution, use stream pipe.

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);
like image 167
Shivam Gupta Avatar answered Mar 14 '26 20:03

Shivam Gupta



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!