Real-Time PCM Audio Streaming in Web Applications

Introduction:

PCM (Pulse Code Modulation) is an audio encoding format that converts analog audio signals into digital data, commonly used for audio recording and storage. While it offers high-quality, lossless audio reproduction, PCM files are typically large and require specialized hardware or software support. Players like MPlayer and Audacity can handle PCM files, and various converters can transform PCM into more common formats like MP3.

Web browsers cannot directly play PCM audio files because this format lacks the necessary metadata that players require to properly interpret the audio data. PCM represents sound as raw digital values without headers containing information about sample rate, channel count, bit depth, or data size.

To implement real-time PCM audio playback in web browsers, we can use the pcm-player JavaScript library combined with WebSockets for streaming audio data.

1. Installing the pcm-player Package

The pcm-player library enables PCM audio playback in browser environments. This JavaScript package handles the conversion of raw PCM data into audible sound, making it ideal for web applications requiring real-time audio processing.

npm install pcm-player

2. Importing the Library

import AudioStreamer from 'pcm-player'

3. Creating an Audio Streaming Module

The following implementation establishes a WebSocket connection to receive PCM audio data and streams it to the browser using the pcm-player library:

import AudioStreamer from 'pcm-player';

let audioConnection = null;
const audioStreamer = new AudioStreamer({
    encoding: '16bitInt', // Bit depth
    channels: 1, // Mono channel
    sampleRate: 16000, // Sampling rate
    flushingTime: 1000, // PCM buffer flush interval
    onstatechange: (node, event, status) => {}, // State change handler
    onended: (node, event) => {} // Playback completion handler
});

function establishAudioStream(serverUrl) {
    // Check WebSocket support
    if (typeof(WebSocket) !== "function") {
        alert("Your browser doesn't support WebSocket protocol. Please use a compatible browser.");
        return;
    }
    
    audioConnection = new WebSocket(serverUrl);
    
    // Message handler
    audioConnection.onmessage = function(event) {
        const response = JSON.parse(event.data);
        if (response.audioData && response.audioData !== "") {
            const pcmBuffer = convertBase64ToAudioBuffer(response.audioData);
            audioStreamer.feed(pcmBuffer); // Send PCM data to the audio streamer
        }
    };
    
    // Connection close handler
    audioConnection.onclose = function(event) {
        console.log("Audio stream connection closed");
    };
    
    // Connection open handler
    audioConnection.onopen = function() {
        console.info("Audio stream connection established");
    };
    
    // Error handler
    audioConnection.onerror = function(error) {
        console.error("WebSocket connection error occurred");
    };
}

function convertBase64ToAudioBuffer(base64String) {
    const decodedData = window.atob(base64String);
    const byteLength = decodedData.length;
    const audioBuffer = new Uint8Array(byteLength);
    
    for (let i = 0; i < byteLength; i++) {
        audioBuffer[i] = decodedData.charCodeAt(i);
    }
    
    return audioBuffer;
}

function sendAudioCommand(command) {
    if (audioConnection && audioConnection.readyState === WebSocket.OPEN) {
        audioConnection.send(JSON.stringify(command));
        console.log("Command sent:", command);
    }
}

function terminateAudioStream() {
    if (audioConnection) {
        audioConnection.close();
        console.info("Audio stream terminated");
    }
}

// Export public methods for external use
export {
    establishAudioStream,
    terminateAudioStream,
    sendAudioCommand
}

4. Starting Audio Playback

audioStreamer.continue()

5. Pausing Audio Playback

audioStreamer.pause()

Tags: web-audio WebSocket pcm-streaming real-time-audio javascript-audio

Posted on Sun, 24 May 2026 18:48:13 +0000 by raja9911