https://d226lax1qjow5r.cloudfront.net/blog/blogposts/play-an-audio-file-into-a-voice-call-with-java-and-spark-dr/audio-file-java.png

Wiedergabe einer Audiodatei in einem Voice-Anruf mit Java und Spark

Zuletzt aktualisiert am April 30, 2021

Lesedauer: 16 Minuten

Dieses Tutorial zeigt Ihnen, wie Sie mit der Nexmo Voice API Audio in einen Anruf streamen können.

Der offensichtlichste Anwendungsfall ist das Abspielen von Warteschleifenmusik oder Nachrichten. Niemand mag es besonders gern, wenn er in der Warteschleife hängt. Aber Sie können die Wartezeit so angenehm wie möglich gestalten, indem Sie Ihren Anrufern etwas zu hören geben, anstatt Stille. Studien haben gezeigt, dass die Zeit schneller vergeht, wenn der Anrufer etwas zu hören bekommt, und dass dies auch den Angstpegel deutlich senken kann - ideal, wenn der Anrufer sich bei Ihrem Kundendienst beschweren möchte.

Dieselben Studien haben jedoch auch ergeben, dass Anrufer negativ reagieren können, wenn ihnen nicht gefällt, was sie hören müssen. Wählen Sie also Ihre Musik oder Ihre Botschaft mit Bedacht aus, und, was immer Sie tun, tun Sie es nicht Rick Roll sie!

Um einen eingehenden Anruf zu beantworten, müssen Sie einen öffentlich zugänglichen Webhook erstellen und Ihren Nexmo Account so konfigurieren, dass Sie ihn verwenden können. Wir werden Java und das Spark Web-Framework um den Webhook zu erstellen. Sobald der Aufruf erfolgt ist, verwenden wir die Nexmo REST API Client-Bibliothek für Java um Audio zu streamen. Eine Version des Codes für dieses Tutorial finden Sie auf GitHub.

Voraussetzungen

  • Das JDK oder sein Open-Source-Äquivalent OpenJDK. Dieses Tutorial wurde unter Verwendung von OpenJDK 11 geschrieben, aber auch Version 8 oder höher sollte ausreichen.

  • Gradle (Version 3.4 oder höher), um Ihr Projekt zu erstellen und seine Abhängigkeiten zu verwalten.

  • ngrok um Ihren Webhook über das öffentliche Internet verfügbar zu machen.

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.

Kauf einer Nexmo-Nummer

Sie benötigen eine virtuelle Nexmo-Nummer, mit der Sie eingehende Anrufe entgegennehmen können. Sie können eine solche Nummer direkt über das Entwickler-Dashboard erwerben, aber in diesem Tutorial werden Sie das Nexmo CLI-Werkzeug stattdessen.

Installieren Sie die Nexmo CLI:

npm install -g nexmo-cli

Dann konfigurieren Sie es mit Ihren NEXMO_API_KEY und NEXMO_API_SECRET über das Entwickler-Dashboard:

nexmo setup NEXMO_API_KEY NEXMO_API_SECRET

Verwenden Sie die Nexmo CLI, um die Numbers anzuzeigen, die voice anzuzeigen, die in Ihrem Land zum Kauf verfügbar sind, indem Sie GB in dem folgenden Befehl durch Ihren eigenen zweistelligen Ländercode:

nexmo number:search GB --voice --verbose

Wählen Sie eine Nummer und kaufen Sie sie:

nexmo number:buy NEXMO_NUMBER

Ihre Anwendung über das Internet zugänglich machen

Sie müssen Ihren Webhook für die APIs von Nexmo zugänglich machen. Eine gute Möglichkeit, dies während der Entwicklung zu tun, ist die Verwendung von ngrok. Um mehr zu erfahren, lesen Sie unseren Blog-Beitrag über ngrok.

Herunterladen und installieren ngrokund führen Sie dann den folgenden Befehl aus, um Ihre Anwendung auf Port 3000 für das öffentliche Internet freizugeben:

ngrok http 3000

Notieren Sie sich die öffentlichen URLs, die ngrok bereitstellt, und lassen Sie sie für die Dauer dieses Tutorials laufen (denn Sie müssen Ihre Anwendung mit diesen URLs konfigurieren und ngrok gibt Ihnen jedes Mal neue, zufällige URLs, wenn Sie sie ausführen, es sei denn, Sie melden sich für einen kostenpflichtigen Plan):

Terminal showing the ngrok URLsTerminal showing the ngrok URLs

Ihr Projekt erstellen

Erstellen Sie ein Verzeichnis für Ihr Projekt mit dem Namen play-audio-into-callan, wechseln Sie in dieses Verzeichnis und verwenden Sie dann gradle um das Projekt zu initialisieren:

mkdir play-audio-into-call cd play-audio-into-call gradle init --type=java-application

Akzeptieren Sie alle Standardeinstellungen und öffnen Sie dann das generierte Projekt in Ihrer IDE.

Abhängigkeiten initialisieren

Suchen Sie die Datei build.gradle Datei und ändern Sie das Abhängigkeitsrepository von jcenter() in mavenCentral():

repositories {
    mavenCentral()
}

Ersetzen Sie den dependencies Abschnitt durch den folgenden:

dependencies {
    // Spark framework
    implementation 'com.sparkjava:spark-core:2.8.0'
 
    // Nexmo client library
    implementation 'com.nexmo:client:4.4.0'

    // Use JUnit test framework
    testImplementation 'junit:junit:4.12'
}

In diesem Beispiel werden wir nicht JUnit in diesem Beispiel nicht verwenden, aber Sie können es vorerst drin lassen.

Erstellen einer Webanwendung mit Spark

Gradle erstellt die App Klasse im Verzeichnis src/main/java/play/audio/into/call Verzeichnis.

Öffnen Sie App.java in Ihrer IDE. Entfernen Sie die getGreeting() Methode, die gradle für Sie erstellt wurde und fügen Sie die notwendige import Anweisung für das spark Paket hinzu.

Rufen Sie dann die Spark port auf, um anzugeben, dass Ihre Anwendung auf Anfragen an Port 3000 wartet.

Ihre App.java sollte folgendermaßen aussehen:

package play.audio.into.call;

import static spark.Spark.*;

public class App {
    public static void main(String[] args) throws Exception {       
        port(3000);
        System.out.println("I'm listening!");
    }
}

Führen Sie Ihre Anwendung durch Ausführen von gradle run im Verzeichnis play-audio-into-call Verzeichnis. Prüfen Sie, ob sie funktioniert, indem Sie die Seite http://localhost:3000 in Ihrem Browser aufrufen und die Meldung "I'm listening" sehen, die auf der Seite angezeigt wird.

Generierung einer Voice API Applikation

Eine Voice API Application ist ein Nexmo-Konstrukt und sollte nicht mit der Anwendung verwechselt werden, die Sie schreiben werden. Stattdessen ist sie ein "Container" für die Authentifizierungs- und Konfigurationseinstellungen, die Sie für die Arbeit mit der API benötigen.

Sie können eine Voice API Application mit der Nexmo CLI erstellen. Sie müssen einen Namen für die Anwendung und die URLs von zwei Webhook-Endpunkten angeben: Der erste ist derjenige, an den die Nexmo-APIs eine Anfrage stellen, wenn Sie einen eingehenden Anruf auf Ihrer virtuellen Nummer erhalten, und der zweite ist derjenige, an den die API Ereignisdaten senden kann.

In diesem Tutorial interessieren wir uns nur für den "answer"-Webhook, Sie können also eine beliebige URL für den "event"-Webhook angeben. Ersetzen Sie den Domainnamen im folgenden Nexmo CLI-Befehl durch Ihren ngrok Domainnamen und führen Sie ihn im Stammverzeichnis Ihres Projekts aus:

nexmo app:create “Play Audio Example” https://41acbcd0.ngrok.io/webhooks/answer https://example.com/webhooks/events --keyfile private.key

Dieser Befehl lädt eine Datei namens private.key herunter, die Authentifizierungsinformationen enthält und eine eindeutige Anwendungs-ID zurückgibt. Notieren Sie sich diese ID, da Sie sie in den folgenden Schritten benötigen werden.

Verknüpfung Ihrer Nexmo-Nummer

Sie müssen nun Ihre virtuelle Nexmo-Nummer mit Ihrer Voice API Application verknüpfen. Führen Sie den folgenden Nexmo CLI-Befehl aus und ersetzen Sie NEXMO_NUMBER durch Ihre virtuelle Nexmo-Nummer (einschließlich der internationalen Vorwahl, aber ohne führende Nullen) und APPLICATION_ID durch die Anwendungs-ID, die Sie im vorangegangenen Schritt erzeugt haben:

nexmo link:app NEXMO_NUMBER APPLICATION_ID

Das war's mit der Konfiguration. Nun können wir uns wieder dem Programmieren Ihrer Anwendung widmen.

Entgegennahme eines eingehenden Anrufs

Wenn Nexmo einen eingehenden Anruf auf Ihrer virtuellen Nummer erhält, sendet es eine GET Anfrage an Ihren /webhooks/answer Endpunkt. Dieser Endpunkt existiert noch nicht, aber Sie werden ihn in Kürze erstellen.

Nexmo erwartet, dass Ihr Webhook eine Antwort liefert, die ein Nexmo Anrufsteuerungsobjekt (NCCO). Dies ist ein Array von Objekten im JSON-Format, von denen jedes ein action das Nexmo mitteilt, wie der Anruf zu behandeln ist.

In diesem Beispiel wird dem Anrufer eine Begrüßungsnachricht per Text-to-Speech vorgelesen und er wird dann in eine Konferenz geschaltet. Die beiden NCCO-Aktionen, die dies erreichen, sind talk und conversationentsprechend. Der NCCO, den Sie in Ihre Antwort aufnehmen müssen, sieht also wie folgt aus:

[
  {
    "action": "talk",
    "voiceName": "Russell",
    "text": "Please wait while we connect you to the conference"
  },
  {
    "action": "conversation",
    "name": "Test Conference"
  }
]

Die talk Aktion sollte ziemlich selbsterklärend sein. Alles, was Sie tun, ist das Lesen der text Zeichenkette an den Benutzer zurück in die Russell Stimme. (Eine vollständige Liste der verfügbaren Voices finden Sie finden Sie hier).

Die conversation Aktion erfordert die Angabe eines name für die Konferenz anzugeben, damit Sie mehrere Anrufer in dieselbe Konferenz einbinden können. In diesem Lernprogramm werden Sie wahrscheinlich der einzige Anrufer sein, aber Sie müssen trotzdem einen Namen angeben. Wir verwenden die conversation Aktion nur, um den Anruf offen zu halten, damit wir später Audio in ihn streamen können.

Die Nexmo REST API Client-Bibliothek für Java stellt einige Hilfsklassen zur Verfügung, um dieses NCCO zu erstellen, also lassen Sie uns diese zuerst konfigurieren.

Instanziierung des Nexmo-Clients

Nehmen Sie den folgenden Import in Ihre App.java Datei ein:

import com.nexmo.client.NexmoClient;

Dann, in Ihrer main Methode, direkt unter dem Aufruf von port(3000)die Client-Bibliothek instanziieren, indem Sie /path/to/your/private.key durch den Pfad zu Ihrer private.key Datei und APPLICATION_ID durch Ihre Voice API Application ID:

public class App {
    public static void main(String[] args) throws Exception {
        port(3000);
        NexmoClient client = NexmoClient.builder()
            .applicationId("APPLICATION_ID")
            .privateKeyPath("/path/to/your/private.key")
            .build();
    }
}

Erstellen des Antwort-Webhooks

Zuerst müssen Sie also diesen Endpunkt erstellen. Die Route, die Sie dafür verwenden werden, lautet /webhooks/answer.

Fügen Sie die folgenden import Aussagen:

import com.nexmo.client.voice.VoiceName;
import com.nexmo.client.voice.ncco.Ncco;
import com.nexmo.client.voice.ncco.TalkAction;
import com.nexmo.client.voice.ncco.ConversationAction;

Und fügen Sie diesen Code in Ihre main Methode ein:

get("/webhooks/answer", (req, res) -> {
    String callId = req.queryParams("uuid");
    System.out.println("Call answered. The UUID for this call is: " + callId);
    TalkAction intro = TalkAction.builder("Please wait while we connect you to the conference.")
        .voiceName(VoiceName.RUSSELL)
        .build();
    ConversationAction conversation = ConversationAction.builder("Test conference")
        .build();
    res.type("application/json");
    return new Ncco(intro, conversation).toJson();
});

Dieser Code verwendet die TalkAction und ConversationAction Hilfsklassen der Nexmo-Clientbibliothek, um den NCCO zu erstellen, der dann in der Antwort an Nexmo zurückgegeben wird.

Testen Sie es, indem Sie zunächst sicherstellen, dass ngrok läuft und führen Sie dann gradle run. Rufen Sie dann Ihre virtuelle Nexmo-Nummer an. Ihre Anwendung zeigt die Anruf-UUID an und Sie sollten die Begrüßungsnachricht hören. Die Leitung bleibt offen, bis Sie die Verbindung beenden.

Audio in den Anruf einspielen

Jetzt brauchen Sie eine Möglichkeit, Audio in die Telefonkonferenz einzuspielen. Zu diesem Zweck erstellen Sie eine Route namens /play/:idwobei die :id die UUID des Anrufs ist, in den Sie Audio streamen möchten. Sie rufen diese Route manuell auf, sobald die Telefonkonferenz begonnen hat.

Fügen Sie die folgende import Anweisung:

import com.nexmo.client.voice.StreamResponse;

Die Erstellung der /play/:id Route in Ihrer main Methode:

get("/play/:id", (req, res) -> {
    String id = req.params(":id");
    final String URL = "http://example.com/your/audio/file.mp3";
    System.out.println("Playing audio into " + id.toString());
    StreamResponse startStreamResponse = client.getVoiceClient().startStream(id, URL, 0);
    System.out.println(startStreamResponse.getMessage());
    Thread.sleep(5000);
    client.getVoiceClient().stopStream(id);
    return "";
});

Ersetzen Sie URL durch die URL zu einer Audiodatei Ihrer Wahl. Sie können https://nexmo-community.github.io/ncco-examples/assets/voice_api_audio_streaming.mp3 zum Testen verwenden.

Diese Route entfernt die Anruf-UUID aus der GET Anfrage-URL und verwendet sie in der startStream Methode, um den richtigen Aufruf zu identifizieren, an den das Audio gestreamt werden soll. Sie spielt den Ton fünf Sekunden lang ab und beendet die Wiedergabe dann durch den Aufruf von stopStream. Wenn Sie die Wiedergabe nicht auf diese Weise stoppen würden, würde sie unbegrenzt weiterlaufen, wie durch den dritten Parameter von startStream der Nexmo mitteilt, wie oft der Ton abgespielt werden soll, wobei Null unendlich bedeutet.

Probieren Sie es aus

Sie haben alles vorbereitet! Jetzt können Sie es testen.

Führen Sie Ihre Java-Anwendung in Ihrem Anwendungsverzeichnis aus:

gradle run

Rufen Sie Ihre virtuelle Nummer an, hören Sie sich die Begrüßungsansage an und notieren Sie sich die in der Konsole angezeigte Anruf-UUID.

Erstellen Sie in einem Browser oder mit Postman oder einem ähnlichen Tool eine GET Anfrage an den /play Endpunkt, indem Sie z. B. die UUID des Aufrufs eingeben:

http://localhost:3000/play/d2af966a2fa415b7080b2762940a828c

Sie sollten einen Ton hören, der nach fünf Sekunden beendet wird.

Schlussfolgerung

In diesem Lernprogramm haben Sie gelernt, wie Sie eine Java-Anwendung mit dem Spark-Framework erstellen, um einen Anruf auf Ihrer virtuellen Nexmo-Nummer mithilfe der Voice API anzunehmen, eine Konferenz zu erstellen und dann Audio in diese zu streamen. Laden Sie einen Freund ein, die Nummer zur gleichen Zeit wie Sie anzurufen, damit Sie beide in die Konferenz aufgenommen werden können. Experimentieren Sie mit verschiedenen Audiodateien und erstellen Sie einen separaten /stop/:id Endpunkt zu erstellen, damit Sie die Dauer des Audios manuell steuern können.

Weitere Lektüre

Teilen Sie:

https://a.storyblok.com/f/270183/384x384/637d0e41eb/marklewin.png
Mark LewinVonage Ehemalige

Ehemaliger technischer Redakteur bei Vonage. Liebt es, mit APIs zu spielen und sie zu dokumentieren.