Conversion d'un flux audio twilio mu-law 8Hz pour une lecture en temps réel avec Discord.js

a marqué ce sujet comme résolu.

Pouvez-vous m’aider à convertir le format audio Twilio mu-law 8Hz en un format lisible en temps réel dans Discord.js? J’essaie de créer un bot Discord qui peut diffuser l’audio reçu d’un appel Twilio, mais j’ai des problèmes avec la conversion de format. Avez-vous des suggestions sur la façon dont je peux y parvenir?

Je sais qu’ici il y a des cracks.

Voilà ce que j’ai essayé. Je reçois un payload mulaw, 8khz, 1 canal encodé en base64, que je décode, puis tente de convertir en PCM pour qu’il soit lu par discord.js, mais ça ne marche pas. J’ai également essayé de le convertir en opus avec la librairie @discord.js/opus, mais la conversion de marche pas je tombe sur message d’erreur (Error: Cannot create a Buffer larger than 0x100000000 bytes, cf https://github.com/discordjs/opus/issues/51).

console.log("Receiving audio...");
// ici, je voudrais essayer de convertir le payload dans un format qui puisse être lu par discord.js
// J'essaye de le convertir en PCM, mais sans succès.
const payload = msg.media.payload;
const wav = new WaveFile();
wav.fromScratch(1, 8000, "8m", Buffer.from(payload, "base64"));
wav.fromMuLaw();
// You can resample.
wav.toSampleRate(16000);
// You can write this straight to a file (will have the headers)
const results = wav.toBuffer();
// Or you can access the samples without the WAV header
const samples = wav.data.samples;

fs.writeFileSync('./stream.wav', results);

try {
    const resource = createAudioResource('./stream.wav');
    player.play(resource);
} catch (ex) {
    console.log(ex);
}

Code complet:

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 RADIO_VOICE_CHANNEL = "1000397725231235205";
const RADIO_TEXT_CHANNEL = "1000397055442817096";
const { createReadStream } = require("node:fs");
const { Readable } = require("stream");
const WaveFile = require("wavefile").WaveFile;
const fs = require("fs");
const { OpusEncoder } = require("@discordjs/opus");
const pcmUtil = require("pcm-util");
const wav = require("wav");
const convert = require("pcm-convert");

client.login(`TOKEN`);

client.on("ready", () => {
   console.log(`Logged in as ${client.user.tag}!`);

   const channel = client.channels.cache.get(RADIO_VOICE_CHANNEL);

   if (!channel) {
       return console.error("The channel does not exist!");
   }

   connection = joinVoiceChannel({
       channelId: channel.id,
       guildId: channel.guild.id,
       adapterCreator: channel.guild.voiceAdapterCreator,
       selfDeaf: false,
       selfMute: false,
   });

   connection.on(VoiceConnectionStatus.Ready, () => {
       console.log("Connection ready");
   });
});

let resource = null;

let player = createAudioPlayer({
   behaviors: {
       noSubscriber: NoSubscriberBehavior.Pause,
   },
});

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

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



   connection.subscribe(player);

   ws.on("message", async (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...");

               // ici, je voudrais essayer de convertir le payload dans un format qui puisse être lu par discord.js
               // J'essaye de le convertir en PCM, mais sans succès.

               const payload = msg.media.payload;

               const wav = new WaveFile();
               wav.fromScratch(1, 8000, "8m", Buffer.from(payload, "base64"));
               wav.fromMuLaw();
               // You can resample.
               wav.toSampleRate(16000);
               // You can write this straight to a file (will have the headers)
               const results = wav.toBuffer();
               // Or you can access the samples without the WAV header
               const samples = wav.data.samples;

               fs.writeFileSync('./stream.wav', results);

             


               try {
                   const resource = createAudioResource('./stream.wav');

                   player.play(resource);

                   
               } catch (ex) {
                   console.log(ex);
               }

               break;
           case "stop":
               console.log("Call has ended");

               break;
           default:
               break;
       }
   });

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

Au sujet de l’erreur: Error: Cannot create a Buffer larger than 0x100000000 bytes

La réponse a été donnée.

You need to make sure that the length of the argument to encoder.encode() is a multiple of 2.5ms.

L’équation est mal passé au markdown mais 1622.5=8016*2*2.5 = 80, je te laisse calculer avec ton cas.

Sinon, il n’est pas ce que tu souhaites faire. Tu parles d’encoder en PCM mais c’est déjà ce que te fourni Twilo (même si encodé par la loi µ).

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte