Question

I'm sending up PCM audio data via a socket to a small node.js service, which I then want to stream with Icecast as "live" audio. I send the data every 5 seconds or so, so I basically have 5 second clips that I wish to stream seamlessly as a series of files or one file. The basic gist is that this is a live recording, and I wish to stream it as it is being written.

I've tried the following approaches:

1) Use ffmpeg to take the audio and convert it to .ogg, and then write the filepath to a playlist file to serve up with a standard ices type basic/playlist config - so that it rolls through the files like a standard playlist.

2) Use ffmpeg to take the audio, convert it to .ogg, and concatonate the newly created .ogg file to a main "super" .ogg file, and serve that up with a standard ices type basic/playlist config.

3) Simply take the PCM data and pipe it to ices with the stdinpcm input every time it's received (so every 5 seconds or so toss the PCM data to ices).

No matter what I try, I'm only able to stream a slice and ices stops. It thinks it's done creating, streaming, and tearing down an icecast mount... and terminates the client connection.

I feel like this is probably fundamentally the wrong approach, so I'm trying to feel out what other people are doing to solve the same problem ("chunking" multiple audio files to create a continous stream).

Thanks in advance for any help!

UPDATE:

Thanks, @Brad. I'm now able to authenticate to Icecast and start the mount/stream. However, if I try to just feed it a file stream for test it plays strangely (like 15 secs in, then suddenly stops). So I think I am getting the streaming part very wrong - is this supposed to happen in the same request - or a new, subsequent request? Here is a code sample:

'use strict';

var http = require('http');
var fs = require('fs');

var options = {
    host: 'iceserver_host.net',
    path: '/stream.ogg',
    port: '8000',
    method: 'SOURCE /stream.ogg ICE/1.0',
    headers: {
        'Authorization': 'Basic ' + new Buffer('source:somepassword').toString('base64'),
        'Content-Type': 'application/ogg',
        'User-Agent': 'mysource/1.0',
        'ice-name': 'Test Stream',
        'ice-url': 'http://server.com',
        'ice-genre': 'talk',
        'ice-bitrate': '128',
        'ice-private': '0',
        'ice-public': '1',
        'ice-description': 'Some description.'
    }
};

var req = http.request(options, function(response) {
    if (response.statusCode == '200') {
        console.log('************* Authenticated! *************');
        // this only sort of works...
        var stream = fs.createReadStream('audio.ogg');
        stream.pipe(req);
    }
});
req.on('error', function(e) {
    console.log('problem with request: ' + e.message);
});

req.end();
Was it helpful?

Solution

I have an app that does the same thing, receiving PCM data from WebSocket clients and sending to SHOUTcast/Icecast servers. My approach is to take interleaved samples, send them to FFmpeg for encoding (over STDIO), take the result from FFmpeg, and send that directly to the SHOUTcast/Icecast server as a stream. I've written source clients for both servers in JavaScript.

This approach works very well. Both Icecast and SHOUTcast are easy to interface with:

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top