https://d226lax1qjow5r.cloudfront.net/blog/blogposts/multitrack-call-transcription-split-recording-voice-dr/MultiTrack-Call-Transcription_1200x675.jpg

Transcription d'appels multipistes avec enregistrement fractionné

Publié le May 10, 2021

Temps de lecture : 6 minutes

En avril, nous avons annoncé que l'enregistrement fractionné était disponible dans le cadre de l'API Voice de Nexmo. L'enregistrement fractionné vous permet d'enregistrer une conversation en stéréo, un participant dans chaque canal. Cela rend les cas d'utilisation courants tels que la transcription beaucoup plus faciles à gérer.

Cependant, il y a un inconvénient à l'enregistrement fractionné - si vous avez plus de deux participants, le premier participant sera sur le canal 0 et tous les autres seront sur le canal 1, ce qui signifie que nous perdons la possibilité de transcrire ce que chacun a dit individuellement.

Et si je vous disais que Nexmo prend désormais en charge non pas un, ni deux, mais trois ( !) canaux distincts dans un enregistrement ? Cela vous ferait-il plaisir ? Et si je vous disais que nous pouvons en supporter quatre ? Cinq ? Nous avons le plaisir de vous annoncer que dès à présent, Nexmo prend en charge jusqu'à 32 canaux dans chaque enregistrement. Vous avez bien lu, nous pouvons fournir 32 canaux audio distincts, chacun contenant un seul participant que vous pouvez traiter comme bon vous semble.

Comme la dernière fois, nous allons étudier ensemble un cas d'utilisation simple. Dans ce scénario, Alice doit discuter d'un projet professionnel avec Bob et Charlie, et ils ont tous convenu que ce serait une bonne idée d'enregistrer l'appel. Pour ce faire, Alice a créé une petite application Node.js qui utilise Nexmo pour la connecter à Bob et Charlie et enregistrer la conversation.

Tout le code de ce billet est disponible sur Github.

L'amorçage de votre application

La première chose à faire est de créer une nouvelle application et d'installer toutes nos dépendances. Pour ce faire, nous utiliserons npm pour initialiser un projet et installer express et body-parser pour gérer nos requêtes HTTP, et dotenv pour gérer la configuration de notre application. Nous devrons également installer le client nexmo afin que nous puissions accéder à l'enregistrement de notre appel une fois que nous aurons reçu une notification indiquant qu'il est disponible et que nous pourrons transcrire l'audio. @google-cloud/speech pour transcrire l'audio.

npm init -y
npm install express body-parser dotenv nexmo @google-cloud/speech --save

Une fois que vous avez installé toutes vos dépendances, vous devez créer une application et louer un numéro que les gens peuvent appeler.

Vonage API Account

To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.

This tutorial also uses a virtual phone number. To purchase one, go to Numbers > Buy Numbers and search for one that meets your needs.

Nexmo envoie des requêtes HTTP à votre application chaque fois qu'un événement se produit dans votre application. Cela peut être lorsqu'un appel commence à sonner, lorsqu'il est pris ou lorsqu'un enregistrement d'appel est disponible, pour n'en citer que quelques-uns. Pour ce faire, Nexmo doit pouvoir accéder à votre application, ce qui est difficile lorsque l'application est exécutée localement sur votre ordinateur portable. Pour exposer votre application locale via l'internet, vous pouvez utiliser un outil appelé ngrok. Pour plus d'informations, vous pouvez lire notre introduction à ngrok sur notre blog.

Exposez votre serveur maintenant en exécutant ngrok http 3000. Vous devriez voir un texte qui ressemble à http://2afec62c.ngrok.io -> localhost:3000. La première section est l'URL de votre ngrok, et c'est ce dont vous avez besoin pour le reste de cet article.

Nous sommes enfin prêts à créer une application Nexmo et à y associer un numéro. Vous devrez remplacer http://2afec62c.ngrok.io par votre propre URL ngrok dans ces exemples :

# Create an application
nexmo app:create "MultiTranscription" http://2afec62c.ngrok.io/webhooks/answer http://2afec62c.ngrok.io/webhooks/event --keyfile private.key
# Application created: aaaaaaaa-bbbb-cccc-dddd-0123456789ab <- Make a note of this, you'll need it later

# Purchase a number
nexmo number:buy --country_code GB
# Number purchased: 442079460005 <- You'll need this too

# Link our number to our application
nexmo link:app NUMBER APPLICATION_ID

Si vous appelez maintenant le numéro que vous avez acheté, Nexmo adressera une demande à http://[id].ngrok.io/webhooks/answer pour savoir comment traiter l'appel. Comme nous n'avons pas encore construit cette application, l'appel échouera.

Traitement d'un appel entrant

Construisons notre application pour traiter les appels entrants.

Créez le fichier index.js et saisissez le code ci-dessous. Ce code requires toutes nos dépendances, configure le client Nexmo et crée une nouvelle instance de express instance :

require("dotenv").config();

const express = require("express");
const bodyParser = require("body-parser");
const Nexmo = require("nexmo");

const nexmo = new Nexmo({
    apiKey: "not_used", // Voice applications don't use the API key or secret
    apiSecret: "not_used", 
    applicationId: process.env.NEXMO_APPLICATION_ID,
    privateKey: process.env.NEXMO_PRIVATE_KEY_PATH
});

const app = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

Ensuite, nous devons créer notre /webhooks/answer qui renverra un NCCO et indiquer à Nexmo comment traiter notre appel. Dans notre NCCO, nous utilisons deux actions connect pour composer automatiquement les numéros de téléphone de Bob et Charlie et les ajouter à la conversation, et une action qui indiquera à Nexmo d'enregistrer l'appel. record qui indique à Nexmo d'enregistrer l'appel.

C'est dans l'action que la magie opère. record est l'endroit où la magie opère. Nous indiquons à Nexmo de diviser l'audio en canaux séparés en définissant split: conversation et que l'audio doit être divisé en trois canaux en définissant channels: 3.

app.get('/webhooks/answer', (req, res) => {
    return res.json([
        {
            action: 'connect',
            endpoint: [{
                type: 'phone',
                number: process.env.BOB_PHONE_NUMBER
            }]
        },
        {
            action: 'connect',
            endpoint: [{
                type: 'phone',
                number: process.env.CHARLIE_PHONE_NUMBER
            }]
        },
        {
            "action": "record",
            "eventUrl": [`${req.protocol}://${req.get('host')}/webhooks/recording`],
            "split": "conversation",
            "channels": 3,
            "format": "wav"
        }
    ]);
});

Nous devrons fournir les numéros de téléphone de Bob et de Charlie pour que cela fonctionne, mais finissons de créer nos points d'extrémité avant de configurer notre application.

Créer le point de terminaison /webhooks/event qui sera informé lorsque des événements sont déclenchés lors de l'appel. Pour l'instant, tout ce que nous allons faire est d'enregistrer les paramètres que nous avons reçus et de confirmer que nous les avons reçus en renvoyant une 204 réponse.

app.post('/webhooks/event', (req, res) => {
    console.log(req.body);
    return res.status(204).send("");
});

Enfin, nous devons mettre en œuvre notre/webhooks/recording . Cette URL a été définie dans notre NCCO dans l'action record et sera notifiée lorsqu'un enregistrement est disponible. Nous transcrirons automatiquement l'audio plus tard, mais pour l'instant, enregistrons les paramètres de la requête afin de voir ce qui est disponible.

app.post('/webhooks/recording', (req, res) => {
    transcribeRecording(req.body);
    return res.status(204).send("");
});

function transcribeRecording(params) {
    console.log(params);
}

app.listen(3000, () => console.log(`Listening`))

À ce stade, il ne reste plus qu'une chose à faire : remplir notre fichier .env afin de fournir les informations dont notre application a besoin. Vous aurez besoin de votre application_idainsi que des numéros de téléphone de Bob et Charlie pour vous aider à tester. Créez un fichier .env et ajoutez-y ce qui suit, en veillant à remplacer l'identifiant de l'application et les numéros de téléphone par vos propres valeurs :

NEXMO_APPLICATION_ID="aaaaaaaa-bbbb-cccc-dddd-0123456789ab"
NEXMO_PRIVATE_KEY_PATH="./private.key"

BOB_PHONE_NUMBER="442079460000"
CHARLIE_PHONE_NUMBER="442079460001"

GOOGLE_APPLICATION_CREDENTIALS="./google_creds.json"

Veillez à ajouter la ligne relative aux informations d'identification Google, même si nous n'avons pas encore créé ce fichier. Nous le créerons dans la section suivante

Une fois que vous avez fait cela, vous pouvez tester votre application en exécutant node index.js et en appelant le numéro Nexmo que vous avez acheté. Il devrait appeler automatiquement les deux Numbers que vous avez ajoutés au fichier .env et une fois que tout le monde a raccroché, votre point de terminaison /webhooks/recording devrait recevoir une URL d'enregistrement.

Connexion à Google

Nous allons utiliser le service Speech-To-Text de Google pour transcrire l'enregistrement de notre appel. Pour commencer, vous devez générer des informations d'identification Google Cloud dans la console Google. Téléchargez le fichier JSON fourni, renommez-le en google_creds.json et placez-le à côté de index.js. C'est ce fichier que le SDK de Google essaiera de lire pour récupérer vos informations d'authentification.

Pour transcrire nos données audio, nous allons nous connecter à l'API Google Speech, en passant la langue attendue, le nombre de canaux dans l'enregistrement et le flux audio lui-même. Mettez à jour votre méthode transcribeRecording pour qu'elle contienne le code suivant :

function transcribeRecording(params) {
    const client = new speech.SpeechClient();

    const config = {
        encoding: `LINEAR16`,
        languageCode: params.language,
        audioChannelCount: params.channelCount,
        enableSeparateRecognitionPerChannel: true,
    };

    const request = {
        config: config,
        audio: {
            content: params.audio.toString('base64'),
        }
    };

    return client.recognize(request);
}

Cela renvoie un promise du SDK vocal de Google Cloud, qui sera résolu lorsque la transcription sera disponible. Avant de pouvoir utiliser le SDK vocal, nous devons l'exiger, donc ajoutez ce qui suit à votre section require au début de votre fichier :

const speech = require('@google-cloud/speech').v1p1beta1;

À ce stade, nous sommes prêts à transcrire notre audio. L'étape finale consiste à récupérer l'enregistrement de Nexmo lorsque nous recevons une demande à l'adresse /webhooks/recording et de transmettre l'audio au service de transcription de Google. Pour ce faire, nous utilisons la méthode nexmo.files.get et transmettons l'audio renvoyé à notre méthode transcribeRecording méthode :

app.post('/webhooks/recording', (req, res) => {
    nexmo.files.get(req.body.recording_url, (err, audio) => {
        if (err) { console.log(err); return; }

        transcribeRecording({
            "language": "en-US",
            "channelCount": 3,
            "audio": audio,
        }).then((data) => {
            const response = data[0];
            const transcription = response.results
                .map(
                    result =>
                    ` Channel Tag: ` +
                    result.channelTag +
                    ` ` +
                    result.alternatives[0].transcript
                )
                .join('n');
            console.log(`Transcription: n${transcription}`);
        });
    });
    return res.status(204).send("");
});

En plus de passer l'audio en paramètre, nous indiquons à notre méthode transcribeRecording qu'il y a 3 canaux dans l'audio et que nous voulons transcrire en utilisant le en-US modèle de langage. Une fois la promesse résolue par le Google Speech SDK, nous lisons les résultats et produisons une transcription de la conversation, y compris le canal d'où provient l'audio.

Si vous appelez maintenant votre numéro Nexmo, vous serez mis en relation avec Bob et Charlie. Une fois l'appel terminé, raccrochez et attendez que Nexmo vous envoie un webhook d'enregistrement. Une fois l'enregistrement reçu, nous l'envoyons à Google et la transcription s'affiche dans la console. Voici ce que cela donne pour moi :

Transcription:
Channel Tag: 1 this is channel one
Channel Tag: 2 and this is channel two
Channel Tag: 3 and a test from channel three
Channel Tag: 1 great

Conclusion

Nous venons de créer un système de conférence téléphonique avec transcription automatique en seulement 76 lignes de code. Non seulement il transcrit automatiquement l'appel, mais il transcrit aussi chaque canal séparément, ce qui vous permet de savoir qui a dit quoi pendant l'appel. Pour plus d'informations sur les options disponibles lors de l'enregistrement d'un appel, vous pouvez consulter la rubrique record action dans notre référence NCCOou voir un exemple de mise en œuvre du NCCO requis dans plusieurs langues.

Partager:

https://a.storyblok.com/f/270183/384x384/1c8825919c/mheap.png
Michael HeapAnciens de Vonage

Michael est un ingénieur logiciel polyglotte qui s'attache à réduire la complexité des systèmes et à les rendre plus prévisibles. Travaillant avec une variété de langages et d'outils, il partage son expertise technique avec des publics du monde entier lors de groupes d'utilisateurs et de conférences. Au quotidien, Michael est un ancien défenseur des développeurs chez Vonage, où il a passé son temps à apprendre, enseigner et écrire sur toutes sortes de technologies.