Streaming

When a user plays a track, the server calls getAudioProducer(trackId, type) on the relevant development/Library-Handler. The returned AudioProducer tells the server how to deliver the audio. There are two modes: stream and hls.

Stream mode

A stream producer delivers audio as a single continuous byte stream. The server forwards it to the client via HTTP range requests.

{
    type: "stream",
    cacheable: true,

    async getMetadata() {
        return { size: fileSize, mimeType: "audio/flac" };
    },

    async getDuration() {
        return 245.3; // seconds
    },

    async getStream() {
        return fs.createReadStream(filePath);
    },

    async getPart(start, end) {
        return fs.createReadStream(filePath, { start, end });
    },
}

When to use stream mode

Use stream mode when the audio is a single file (local disk, HTTP download, etc.) and seeking by byte offset is cheap. It works well for common formats: FLAC, MP3, AAC, OGG.

cacheable

If cacheable: true, the server may cache the audio data to avoid re-fetching it from the plugin on every request. Set false for live streams or content that changes between requests.

HLS mode

An HLS producer segments the audio into chunks and serves an M3U8 playlist. The frontend uses hls.js for playback, which enables adaptive streaming and seeking by segment.

{
    type: "hls",
    cacheable: false,

    async getMetadata() {
        return { duration: 245.3, mimeType: "audio/mp4" };
    },

    async getPlaylist() {
        return {
            version: 3,
            targetDuration: 10,
            mediaSequence: 0,
            playlistType: "VOD",
            containerType: "fmp4",
            initSegmentId: "init",
            segments: [
                { id: "seg-0", duration: 10 },
                { id: "seg-1", duration: 10 },
                { id: "seg-2", duration: 5.3 },
            ],
        };
    },

    async getSegment(name) {
        if (name === "init") { return initSegmentBuffer; }
        return segmentBuffers[name];
    },
}

When to use HLS mode

Use HLS mode when the audio is already segmented (e.g., an HLS stream from an external service), or when you want to transcode on the fly and deliver segments incrementally. It is also the appropriate mode for content with DRM key rotation.

HLS playlist fields

Field Description
version HLS protocol version (typically 3 or 6+)
targetDuration Maximum segment duration in seconds
mediaSequence Starting sequence number
playlistType "VOD" for complete files, "EVENT" for live
containerType "ts", "fmp4", or "aac"
initSegmentId ID passed to getSegment for the fMP4 init segment
key Optional HLS encryption key descriptor
segments Ordered list of segment descriptors

HLS segments

Each segment has an id (your internal name passed back to getSegment), a duration, and optionally a byteRange and discontinuity flag.

Choosing a mode

If the source gives you a choice, stream is simpler to implement. Use hls when the source is already HLS, when you need per-segment transcoding, or when the audio is too large or live to serve as a single seekable file.

Many identifiers and attribute sources only support reading stream, not hls. However you can circumvent this by caching your library before running attribution or identification tasks, as the library cache automatically converts HLS streams to single files.