Tuesday, 9 October 2018

NodeJS - Live Stream Audio to Specific URL with mp3 audio "chunks"

I'm working on developing an application that will capture audio from the browser in 5 second "chunks" (these are full audio files and not simply partial files), send these 5 second chunks to the server, convert it from webm to mp3 on the server, and then broadcast the mp3 file to clients connected via a websocket or a static url.

I've successfully managed to do parts 1 and 2; however, I'm not quite sure the best approach to transmit this created mp3 audio file to the user. My thinking was to generate a single url for clients to listen in to, e.g http://localhost/livestream.mp3 (a live stream url that would automatically update itself with the latest audio data), or to emit the audio files to the clients over a websocket and attempt to play these sequenced audio files seamlessly without any noticeable gaps between the audio files as they switch out.

Here's a snippet of my [typescript] code where I create the mp3 file, and I've pointed out the area in which I would perform the broadcast operation.

private createAudioFile(audioObj: StreamObject, socket: SocketIO.Socket) : void {
    const directory: string = `${__dirname}/streams/live`;

    fs.writeFile(`${directory}/audio_${audioObj.time}.webm`, audioObj.stream, (err: NodeJS.ErrnoException) => {
        if (err) logger.default.info(err.toString());
        try {
            const process: childprocess.ChildProcess = childprocess.spawn('ffmpeg', ['-i', `${directory}/audio_${audioObj.time}.webm`, `${directory}/audio_${audioObj.time}.mp3`]);

            process.on('exit', () => {
                // Ideally, this is where I would be broadcasting the audio from 
                // the static URL by adding the new stream data to it, or by
                // emitting it out to all clients connected to my websocket
                // const wso = fs.createWriteStream(`${directory}/live.mp3`);
                // const rso = fs.createReadStream(`${directory}/audio_${audioObj.time}.mp3`);
                // rso.pipe(wso);

                if (audioObj.last == true) {
                    this.archiveAudio(directory, audioObj.streamName);
                }
            });
        } catch (e) {
            logger.default.error('CRITICAL ERROR: Exception occurred when converting file to mp3:');
            logger.default.error(e);
        }
    });
}

I've seen a number of questions out there that ask for a similar concept, but not quite the final goal that I'm looking for. Is there a best practice on how to make this work?



from NodeJS - Live Stream Audio to Specific URL with mp3 audio "chunks"

No comments:

Post a Comment