1

Can you help me convert Twilio mu-law 8Hz audio format into a playable format for real-time use in Discord.js? I'm trying to create a Discord bot that can stream audio received from a Twilio call, but I'm having trouble with the format conversion. Any suggestions on how I can achieve this?

const { WebSocketServer } = require("ws");
const base64 = require("base64-js");
const Discord = require("discord.js");
const client = new Discord.Client();
const { VoiceConnectionStatus, Events } = require("@discordjs/voice");
const { getVoiceConnection, createAudioResource, createAudioPlayer, NoSubscriberBehavior, joinVoiceChannel, StreamType, createDefaultAudioReceiveStreamOptions } = require("@discordjs/voice");
const { createReadStream } = require("node:fs");
const { Readable } = require("stream");
const WaveFile = require("wavefile").WaveFile;
const { OpusEncoder } = require("@discordjs/opus");

const wss = new WebSocketServer({ port: 5000 });

wss.on("connection", (ws) => {
    console.log("Connection accepted");

    ws.on("message", (message) => {
        const msg = JSON.parse(message);

        switch (msg.event) {
            case "connected":
                console.log("A new call has connected");
                break;
            case "start":
                console.log(`Starting media stream...`, msg);
                break;
            case "media":
                console.log("Receiving audio...");

                const payload = Buffer.from(msg.media.payload, "base64");

// CONVERT THE MU-LAW 8KHZ 1 CHANNEL PAYLOAD INTO SOMETHING PLAYABLE BY DISCORD ???

                const resource = createAudioResource(createReadStream(payload), { 
                    inputType: StreamType.Raw
                });

                player.play(resource);

                connection.subscribe(player);
            case "stop":
                console.log("Call has ended");

                break;
            default:
                break;
        }
    });

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

I have tried to convert the payload in PCM, and then in opus but without success because the @discord/opus lib return "Error: Cannot create a Buffer larger than 0x100000000 bytes". Someone explained here : https://github.com/discordjs/opus/issues/51 what i should do to prevent this problem but i am unable to apply that.

This is what i tried to do :

const wav = new WaveFile();
wav.fromScratch(1, 8000, '16', payload);
wav.fromMuLaw();

const pcmBuffer = wav.toBuffer();

const paddingBytes = Math.ceil(pcmBuffer.length / 160) * 160 - pcmBuffer.length;

if (paddingBytes > 0) {
   const paddingBuffer = Buffer.alloc(paddingBytes);
   pcmBuffer = Buffer.concat([pcmBuffer, paddingBuffer]);
}

// Create the encoder.
// Specify 16kHz sampling rate and 2 channel size.
const encoder = new OpusEncoder(8000, 1);

// Encode and decode.
const encoded = encoder.encode(pcmBuffer);
Axio Axio
  • 11
  • 2

0 Answers0