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

MultiTrack-Anruf-Transkription mit geteilter Aufzeichnung

Zuletzt aktualisiert am May 10, 2021

Lesedauer: 6 Minuten

Bereits im April haben wir angekündigt, dass geteilte Aufnahme als Teil der Nexmo Voice API verfügbar ist. Mit der geteilten Aufnahme können Sie ein Gespräch in Stereo aufzeichnen, einen Teilnehmer in jedem Kanal. Dies macht häufige Anwendungsfälle wie die Transkription viel einfacher zu handhaben.

Die geteilte Aufzeichnung hat jedoch einen Nachteil: Bei mehr als zwei Teilnehmern wäre der erste Teilnehmer auf Kanal 0 und alle anderen auf Kanal 1, was bedeutet, dass wir nicht mehr in der Lage sind, das Gesagte individuell zu transkribieren.

Was wäre, wenn ich Ihnen sagen würde, dass Nexmo jetzt nicht nur einen, nicht zwei, sondern drei(!) separate Kanäle in einer Aufnahme unterstützt? Würde Sie das glücklich machen? Wie wäre es, wenn ich Ihnen sagen würde, dass wir vier unterstützen können? Fünf? Wir freuen uns, Ihnen mitteilen zu können, dass Nexmo ab sofort bis zu 32 Kanäle in jeder einzelnen Aufnahme unterstützt. Sie haben richtig gelesen - wir können 32 separate Audiokanäle bereitstellen, von denen jeder einen einzelnen Teilnehmer enthält, den Sie nach Belieben bearbeiten können.

Wie beim letzten Mal werden wir gemeinsam einen einfachen Anwendungsfall durchgehen. In diesem Szenario muss Alice ein Arbeitsprojekt mit Bob und Charlie besprechen, und sie sind sich einig, dass es eine gute Idee wäre, das Gespräch aufzuzeichnen. Um dies zu erreichen, hat Alice eine kleine Node.js-Anwendung erstellt, die Nexmo nutzt, um sich mit Bob und Charlie zu verbinden und das Gespräch aufzuzeichnen.

Der gesamte Code in diesem Beitrag ist auf Github verfügbar.

Bootstrapping Ihrer Anwendung

Als Erstes müssen wir eine neue Anwendung erstellen und alle unsere Abhängigkeiten installieren. Um dies zu tun, verwenden wir npm um ein Projekt zu initialisieren und zu installieren express und body-parser um unsere HTTP-Anfragen zu bearbeiten, und dotenv um unsere Anwendungskonfiguration zu verwalten. Wir müssen auch den nexmo Client installieren, damit wir auf unsere Gesprächsaufzeichnung zugreifen können, sobald wir eine Benachrichtigung erhalten, dass sie verfügbar ist, und @google-cloud/speech das Audio zu transkribieren.

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

Sobald Sie alle Abhängigkeiten installiert haben, müssen Sie eine Anwendung erstellen und eine Nummer mieten, die die Leute anrufen können.

Vonage API-Konto

Um dieses Tutorial durchzuführen, benötigen Sie ein Vonage API-Konto. Wenn Sie noch keines haben, können Sie sich noch heute anmelden und mit einem kostenlosen Guthaben beginnen. Sobald Sie ein Konto haben, finden Sie Ihren API-Schlüssel und Ihr API-Geheimnis oben auf dem Vonage-API-Dashboard.

In diesem Lernprogramm wird auch eine virtuelle Telefonnummer verwendet. Um eine zu erwerben, gehen Sie zu Rufnummern > Rufnummern kaufen und suchen Sie nach einer Nummer, die Ihren Anforderungen entspricht.

Nexmo sendet HTTP-Anfragen an Ihre Anwendung, sobald ein Ereignis innerhalb Ihrer Anwendung eintritt. Das kann sein, wenn ein Anruf läutet, wenn er angenommen wird oder wenn eine Anrufaufzeichnung verfügbar ist, um nur einige Beispiele zu nennen. Dazu muss Nexmo in der Lage sein, Ihre Anwendung zu erreichen, was schwierig ist, wenn die Anwendung lokal auf Ihrem Laptop läuft. Um Ihre lokale Anwendung über das Internet zugänglich zu machen, können Sie ein Tool namens ngrok. Für weitere Informationen lesen Sie bitte unsere Einführung in ngrok Blog-Beitrag.

Geben Sie Ihren Server jetzt frei, indem Sie ngrok http 3000. Sie sollten einen Text sehen, der so ähnlich aussieht wie http://2afec62c.ngrok.io -> localhost:3000. Der erste Abschnitt ist Ihre ngrok-URL, die Sie für den Rest dieses Beitrags benötigen.

Jetzt können wir endlich eine Nexmo-Anwendung erstellen und eine Nummer mit ihr verknüpfen. Sie müssen die http://2afec62c.ngrok.io in diesen Beispielen durch Ihre eigene ngrok-URL ersetzen:

# 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

Wenn Sie nun einen Anruf an die von Ihnen gekaufte Nummer tätigen, stellt Nexmo eine Anfrage an http://[id].ngrok.io/webhooks/answer um herauszufinden, wie der Anruf zu behandeln ist. Da wir diese Anwendung noch nicht entwickelt haben, wird der Anruf fehlschlagen.

Bearbeitung eines eingehenden Anrufs

Lassen Sie uns unsere Anwendung für die Bearbeitung eingehender Anrufe erstellen.

Erstellen Sie die index.js Datei und geben Sie den unten gezeigten Code ein. Dieser requires alle unsere Abhängigkeiten, konfiguriert den Nexmo-Client und erstellt eine neue express Instanz:

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 }));

Als nächstes müssen wir unseren /webhooks/answer Endpunkt erstellen, der ein NCCO zurückgibt und Nexmo mitteilt, wie unser Aufruf zu behandeln ist. In unserem NCCO verwenden wir zwei connect Aktionen, um automatisch die Telefonnummern von Bob und Charlie zu wählen und sie dem Gespräch hinzuzufügen, und eine record Aktion, die Nexmo anweist, das Gespräch aufzuzeichnen.

Die record Aktion ist der Ort, an dem die Magie passiert. Wir weisen Nexmo an, den Ton in separate Kanäle aufzuteilen, indem wir split: conversation und dass der Ton in drei Kanäle aufgeteilt werden soll, indem wir 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"
        }
    ]);
});

Damit dies funktioniert, müssen wir die Telefonnummern von Bob und Charlie angeben, aber bevor wir unsere Anwendung konfigurieren, müssen wir noch unsere Endpunkte erstellen.

Erstellen Sie den /webhooks/event Endpunkt, der informiert werden soll, wenn Ereignisse bei dem Aufruf ausgelöst werden. Im Moment protokollieren wir nur die empfangenen Parameter und bestätigen den Empfang durch das Zurücksenden einer 204 Antwort.

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

Schließlich müssen wir unseren/webhooks/recording Endpunkt implementieren. Diese URL wurde in unserem NCCO in der record Aktion definiert und wird benachrichtigt, wenn eine Aufnahme verfügbar ist. Wir werden die Audiodaten später automatisch transkribieren, aber für den Moment sollten wir die Anfrageparameter protokollieren, damit wir sehen können, was verfügbar ist.

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`))

An diesem Punkt gibt es nur noch eines zu tun - unsere .env Datei mit den Informationen zu füllen, die unsere Anwendung benötigt. Sie benötigen Ihre application_idsowie einige Telefonnummern für Bob und Charlie, die Ihnen beim Testen helfen sollen. Erstellen Sie eine .env Datei und fügen Sie Folgendes hinzu, wobei Sie darauf achten, dass Sie die Anwendungs-ID und die Telefonnummern durch Ihre eigenen Werte ersetzen:

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"

Fügen Sie unbedingt die Zeile mit den Google-Anmeldeinformationen hinzu, auch wenn wir diese Datei noch nicht erstellt haben. Wir werden sie im nächsten Abschnitt erstellen

Wenn Sie dies getan haben, können Sie Ihre Anwendung testen, indem Sie node index.js aufrufen und dann die von Ihnen erworbene Nexmo-Nummer anrufen. Sie sollte automatisch die beiden Nummern anrufen, die Sie in der Datei .env Datei hinzugefügt haben. Sobald der Anrufer aufgelegt hat, sollte Ihr /webhooks/recording Endpunkt eine Aufnahme-URL erhalten.

Verbinden mit Google

Wir werden den Google-Dienst Speech-To-Text verwenden, um unsere Anrufaufzeichnung zu transkribieren. Um damit zu beginnen, müssen Sie Google Cloud-Anmeldeinformationen generieren in der Google-Konsole erstellen. Laden Sie die bereitgestellte JSON-Datei herunter, benennen Sie sie um in google_creds.json und platzieren Sie sie neben index.js. Dies ist die Datei, die das Google SDK versuchen wird zu lesen, um Ihre Authentifizierungsdaten zu erhalten.

Um unsere Audiodaten zu transkribieren, stellen wir eine Verbindung zur Google Speech API her und geben die erwartete Sprache, die Anzahl der Kanäle in der Aufnahme und den Audiostream selbst ein. Aktualisieren Sie Ihre transcribeRecording Methode so, dass sie den folgenden Code enthält:

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);
}

Dies gibt eine promise vom Google Cloud Speech SDK zurück, das aufgelöst wird, wenn die Transkription verfügbar ist. Bevor wir das Sprach-SDK verwenden können, müssen wir es anfordern, also fügen Sie den folgenden Abschnitt zu Ihrer require Abschnitt am Anfang der Datei:

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

Jetzt sind wir bereit, unser Audio zu transkribieren. Der letzte Schritt besteht darin, die Aufnahme von Nexmo abzurufen, wenn wir eine Anfrage an /webhooks/recording und die Audiodaten an den Transkriptionsdienst von Google weiterzuleiten. Hierfür verwenden wir die nexmo.files.get Methode und übergeben das zurückgegebene Audio an unsere transcribeRecording Methode:

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("");
});

Neben der Übergabe des Audios als Parameter teilen wir unserer transcribeRecording Methode mit, dass es 3 Kanäle im Audio gibt und dass wir die Transkription mit Hilfe des en-US Sprachmodells transkribieren wollen. Sobald das Versprechen durch das Google Speech SDK aufgelöst wurde, lesen wir die Ergebnisse und geben eine Transkription des Gesprächs aus, einschließlich des Kanals, aus dem das Audio stammt.

Wenn Sie jetzt Ihre Nexmo-Nummer anrufen, werden Sie sowohl mit Bob als auch mit Charlie verbunden. Sobald der Anruf beendet ist, legen Sie auf und warten Sie, bis Nexmo Ihnen einen Webhook für die Aufnahme sendet. Sobald der Webhook eintrifft, senden wir den Ton an Google und die Transkription erscheint in der Konsole. So sieht es bei mir aus:

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

Schlussfolgerung

Wir haben gerade ein Konferenzanrufsystem mit automatischer Transkription in nur 76 Codezeilen entwickelt. Es transkribiert nicht nur automatisch das Gespräch, sondern auch jeden Kanal separat, so dass Sie wissen, wer was in dem Gespräch gesagt hat. Weitere Informationen zu den Optionen, die bei der Aufzeichnung eines Gesprächs zur Verfügung stehen, finden Sie in der record action in unserer NCCO-Referenzoder sehen Sie eine Beispiel-Implementierung der NCCO erforderlich in mehreren Sprachen.

Teilen Sie:

https://a.storyblok.com/f/270183/384x384/1c8825919c/mheap.png
Michael HeapVonage Ehemalige

Michael ist ein polyglotter Software-Ingenieur, der sich dafür einsetzt, die Komplexität von Systemen zu reduzieren und sie berechenbarer zu machen. Er arbeitet mit einer Vielzahl von Sprachen und Tools und gibt sein technisches Fachwissen auf Benutzergruppen und Konferenzen in der ganzen Welt weiter. Im Alltag ist Michael ein ehemaliger Developer Advocate bei Vonage, wo er seine Zeit damit verbrachte, über alle Arten von Technologie zu lernen, zu lehren und zu schreiben.