1
\$\begingroup\$

I have written the following class used to get the metadata out of an internet radio station. It takes a Node Stream and transforms it to grab the metadata out of the mp3 stream and then removes the metadata bytes from the stream so it isn't audibly heard. If you need to know the Shoutcast metadata protocol, see here: https://web.archive.org/web/20111128170936/https://www.smackfu.com/stuff/programming/shoutcast.html

class SpliceMetadata extends Transform {
    private META_INT : number = null;
    private byteCounter: number = 0;
    private iterator: number = 0;
    private tempBuffer: string = "";
    private updateFn: (song: NowPlaying) => void = null;
    constructor(META_INT: number, fn: (song: NowPlaying) => void, opts?: TransformOptions) {
        super({ ...opts})
        this.META_INT = META_INT;
        this.updateFn = fn;
    }
    private extractSongTitle(raw: string): NowPlaying {
        let np: NowPlaying = {title: null, artist: null, albumArtUrl: null};
        let rawProc : string[] = raw.split(`'`)[1].split('-');
        if(rawProc[1]) {
            np.title = rawProc[1].trim();
            np.artist = rawProc[0].trim();
            return np;
        }
        else {
            return null;
        }
    }
    _transform(chunk: Buffer, encoding: BufferEncoding, callback: TransformCallback) {
        let hexArray = chunk.toString('hex').match(/.{2}/g);
        let filteredChunk: string = ''; 
        chunk.forEach((byte, index) => {
            if(this.byteCounter === this.META_INT) {
                this.byteCounter = 0;
                this.iterator = byte * 16;
            }
            else if(this.iterator > 0) {
                this.iterator--;
                if(byte !== 0) {
                    this.tempBuffer += String.fromCharCode(byte);
                }
                if(this.iterator === 0) {
                    this.updateFn(this.extractSongTitle(this.tempBuffer));
                    this.tempBuffer = "";
                }
            }
            else {
                filteredChunk += hexArray[index];
                this.byteCounter++;
            }
        })
        this.push(Buffer.from(filteredChunk, 'hex'));
    callback();
    }
}
\$\endgroup\$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.