Skip to main content

Key Points

URL Parameters:
  • sampleRate (default: 16000)
  • noiseSuppression (0/1)
  • gainControl (0/1)
  • backgroundVoiceSuppression (0/1)
Authentication:
  • Backend: Bearer token in the Authorization header
  • Frontend: API key in the first message

Backend to Backend

const WebSocket = require('ws');
const fs = require('fs');
const wav = require('wav');
const AudioContext = require('web-audio-api').AudioContext;
const audioContext = new AudioContext();

// Connection parameters
const uri = 'wss://api-dev.meeamitech.com/audio/v1/uploads/stream?sampleRate=16000&noiseSuppression=1&gainControl=1&backgroundVoiceSuppression=1';
const apiKey = 'YOUR_API_KEY';

class AudioClient {
    constructor() {
        this.ws = new WebSocket(uri, {
            headers: {
                'Authorization': `Bearer ${apiKey}`
            }
        });
        this.setupWebSocket();
    }

    setupWebSocket() {
        this.ws.on('open', () => {
            console.log('Connected to WebSocket server');
        });

        this.ws.on('message', (data) => {
            console.log('Received processed audio chunk:', data.length, 'bytes');
            // Handle processed audio...
        });

        this.ws.on('error', (error) => {
            console.error('WebSocket error:', error);
        });

        this.ws.on('close', () => {
            console.log('Connection closed');
        });
    }

    // Example 1: Send raw PCM data
    sendRawPCM() {
        const audioBuffer = fs.readFileSync('input.raw');
        this.sendInChunks(audioBuffer);
    }

    // Example 2: Send WAV file
    sendWavFile() {
        const reader = new wav.Reader();
        const readStream = fs.createReadStream('input.wav');

        reader.on('format', format => {
            console.log('WAV format:', format);
        });

        reader.on('data', (chunk) => {
            this.sendInChunks(chunk);
        });

        readStream.pipe(reader);
    }

    // Example 3: Send audio buffer
    async sendAudioFile(filePath) {
        const audioData = fs.readFileSync(filePath);
        const audioBuffer = await audioContext.decodeAudioData(audioData.buffer);
        const pcmData = this.convertToInt16(audioBuffer);
        this.sendInChunks(pcmData);
    }

    sendInChunks(buffer) {
        const chunkSize = 640; // 320 samples * 2 bytes
        let offset = 0;

        const sendChunk = () => {
            if (offset >= buffer.length) {
                return;
            }

            const chunk = buffer.slice(offset, offset + chunkSize);
            this.ws.send(chunk);
            offset += chunkSize;

            setTimeout(sendChunk, 20);
        };

        sendChunk();
    }

    convertToInt16(audioBuffer) {
        const samples = audioBuffer.getChannelData(0);
        const int16Array = new Int16Array(samples.length);
        for (let i = 0; i < samples.length; i++) {
            int16Array[i] = samples[i] * 32767;
        }
        return Buffer.from(int16Array.buffer);
    }
}

// Usage
const client = new AudioClient();
client.sendWavFile();
// or client.sendAudioFile('input.mp3');
// or client.sendRawPCM();