
Teilen Sie:
Javier studied Industrial Engineering back in Madrid where he's from. He is now one of our Solution Engineers, so if you get into trouble using our APIs he may be the one that gives you a hand. Out of work he loves playing football and travelling as much as he can.
Echtzeit-Übersetzung mit Vonage Video API
Lesedauer: 7 Minuten
Einführung
In der sich ständig weiterentwickelnden Landschaft der digitalen Kommunikation ist die Echtzeitübersetzung von Videoanrufen zu einer wichtigen Komponente geworden, um Sprachbarrieren zu überwinden und die globale Zusammenarbeit zu fördern. Mit der Video API von Vonage haben Entwickler die Möglichkeit, diese transformative Fähigkeit nahtlos in ihre Applikationen zu integrieren.
Ganz gleich, ob Sie eine Plattform für grenzüberschreitende Konferenzen, eine App zum Erlernen von Sprachen oder einen globalen Kundensupport entwickeln - unsere Echtzeit-Übersetzungsfunktion beschleunigt Ihre Entwicklung. In diesem Blogbeitrag erfahren Sie, wie Sie inklusive und zugängliche Video-Erlebnisse für ein weltweites Publikum erstellen. Tauchen wir ein!
Echtzeit-Übersetzung Demo
Bevor wir loslegen, sollten wir uns ansehen, was wir bauen werden. Sehen Sie sich dieses Beispielvideo an:
Wenn Sie nun eine Demo einer komplexeren Anwendung mit 2 Benutzern sehen möchten, die in verschiedenen Sprachen sprechen, sehen Sie sich dieses andere Video an:
Voraussetzungen
Ein Vonage Video API Account. Klicken Sie auf . Anmelden um ein Konto zu erstellen, falls Sie noch keins haben.
Node.js installiert Erleben Sie die Composer-API in Ihrem Account aktiviert. Sie können dies im Account-Portal
Ein Google Cloud Platform Account und ein Projekt mit Text-to-Speech, übersetzen und Sprache-zu-Text APIs aktiviert.
In diesem Blogbeitrag wird davon ausgegangen, dass Sie mit der Video API von Vonage vertraut sind.
Das Medien-Engagement Ihrer Website muss hoch sein, damit die Autoplay-Richtlinie von Google Autoplay-Audio nicht blockiert. Erfahren Sie mehr hier. Zu Testzwecken können Sie Folgendes verwenden Entwicklerschalter
Architektur-Diagramm: Was wir bauen werden
Das folgende Diagramm zeigt die Architektur dessen, was wir aufbauen werden. Um zu beginnen, können wir die Audio-Anschluss-API verwenden, um die rohen Audiodaten (PCM 16 Khz/16bit) von unserer Video-Sitzung über eine sichere WebSocket-Verbindung an unseren Server zu senden. Unser Server stellt dann eine Verbindung mit Google Cloud her, um die rohen Audiodaten zu übertragen, sie zu transkribieren, zu übersetzen und die übersetzten Audiodaten zu erhalten.
Real-Time Translation Architectual Diagram
Sobald wir die Untertitel und die Audiodaten übersetzt haben, können wir die Experience Composer-API nutzen, um das Audio in die Video-Sitzung zu integrieren. Mit der Experience Composer-API können Sie den Inhalt einer Website als neuen Stream in einer Vonage Video API-Sitzung veröffentlichen.
Daher können wir eine einfache Webseite bereitstellen, die die Audiodaten von unserem Server empfängt und sie mit der Web-Audio-API. Da der Inhalt dieser Website dank der Leistungsfähigkeit von Experience Composer in einer Sitzung veröffentlicht wird, können alle an dem Anruf beteiligten Benutzer die Übersetzungen hören. Diese Logik wird im nächsten Screenshot beschrieben:
Vonage API Real-Time Translation Logic
Sie fragen sich vielleicht, warum die Audiodaten nicht direkt über eine WebSocket-Verbindung an jeden Benutzer gesendet und lokal abgespielt werden? Nun, die kurze Antwort ist, dass TCP nicht die bevorzugte Option ist, um Audiodaten in Echtzeit zu senden, und unter nicht idealen Netzwerkbedingungen auf der Client-Seite würden wir das übersetzte Audio mit einer ziemlich großen Latenz hören. Wenn wir die Experience Composer-API verwenden, sind wir nicht auf die Netzwerke der einzelnen Benutzer angewiesen. Daher können Sie sich Experience Composer in diesem Fall als einen Benutzer vorstellen, dessen Aufgabe es ist, die von unserem Server übersetzten Audiodaten zu empfangen und sie in den Anruf einzubringen.
Wie wir unsere WebSocket Middleware aufbauen
Der Server ist die Middleware, die für den Empfang der Audiodaten der Videositzung über WebSocket von der Audio Connect API verantwortlich ist und diese an Google zur Spracherkennung, Übersetzung und Text-to-Speech-Verarbeitung sendet.
Wir werden einen API-Endpunkt bereitstellen, der es uns ermöglicht, die Audio-Connector-API-Instanz zu starten, um Audiodaten zu empfangen. Der start streaming Endpunkt wird die startStreamer Funktion mit der streamId des Benutzers auf, und wir übergeben auch die Websocket-URL, über die wir die Audiodaten empfangen wollen. Diese API wird von der Client-Seite aufgerufen, sobald der Benutzer mit der Veröffentlichung in der Sitzung beginnt. Wir werden auch eine Experience Composer-Instanz instanziieren:
app.post('/startStreaming', async (req, res) => {
try {
console.log('someone wants to stream');
const {
streamId,
sessionId
} = req.body;
console.log(streamId, sessionId);
const response = await startStreamer(streamId, sessionId);
const render = await createExperienceComposer(process.env.sessionId);
if (render && response) {
return res.send(response);
}
res.send(response);
} catch (e) {
console.log(e);
}
});
const startStreamer = async (streamId, sessionId) => {
try {
const {
token
} = await opentok.generateToken(sessionId, 'publisher');
const data = JSON.stringify({
sessionId: sessionId,
token: token,
websocket: {
uri: `${process.env.websocket_url}/socket`,
streams: [streamId],
headers: {
from: streamId,
},
},
});
const config = {
method: 'post',
url: `https://api.opentok.com/v2/project/${process.env.VIDEO_API_API_KEY}/connect`,
headers: {
'X-OPENTOK-AUTH': await generateRestToken(),
'Content-Type': 'application/json',
},
data: data,
};
const response = await axios(config);
console.log(response.data);
return response.data;
} catch (e) {
console.log(e);
return e;
}
};
Um Audiodaten auf unserem Server zu empfangen, müssen wir einen Websocket einrichten, damit Vonage uns die Rohdaten senden kann. Wir werden eine Streaming-Client-Verbindung mit Google pro Nutzer einrichten.
app.ws('/socket', async (ws, req) => {
console.log('someone connected');
console.log(`starting connection for user with streamId ${streamId}`)
const uuid = req?.query?.uuid
let sc = new StreamingClient(uuid, 'es', 'en-US');
await sc.init();
const aWss = expressWs.getWss().clients;
sc.setAudioChunkAvailableCallback(function(chunk) {
console.log('audio available. Sending audio to the clients connected to the wss');
const aWss = expressWs.getWss('/socket').clients;
if (ws.readyState === 1) {
aWss.forEach(function(client) {
client.send(chunk);
});
}
});
sc.setTranscriptionAvailableCallback(function(data) {
console.log(‘Sending original and translated captions to the connected clients’);
const aWss = expressWs.getWss('/socket').clients;
aWss.forEach(function(client) {
client.send(JSON.stringify(data));
});
});
sc.startRecognizer();
ws.on('message', (msg) => {
try {
if (typeof msg === 'string') {
let config = JSON.parse(msg);
console.log(config);
sc.setId(config.from);
} else {
console.log(‘Sending audio data to Google
for Speech to text recognition’);
sc.sendMessage(msg);
}
} catch (err) {
console.log('[' + uuid + '] ' + err);
ws.removeAllListeners('message');
ws.close();
}
});
ws.on('close', () => {
console.log('[' + uuid + '] Websocket closed');
sc.closeConversation();
sc = null;
});
});
Sie können die Implementierung des createExperienceComposer in dieser Datei. Um die Anfragen mit der API zu authentifizieren, müssen wir ein JWT-Token erstellen, wie es in der Dokumentation zur Authentifizierung. Ich habe das jsonwebtoken-Paket von npm verwendet, aber Sie können auch jedes andere Paket verwenden. CreateRender" und "DeleteRender" sind Funktionen zum Starten und Stoppen einer Experience Composer-Instanz.
Um die Experience Composer-Instanz zu erstellen, müssen wir gemäß der Dokumentation einige Parameter im JSON-Body übergeben. Einige der Parameter sind obligatorisch, wie zum Beispiel die url, sessionId, token und projectId. Achten Sie besonders auf den URL-Parameter. Stellen Sie sich diesen als die URL vor, die der "unsichtbare Benutzer", den Experience Composer darstellt, besuchen wird. Dann wird der Javascript-Code geladen und der Experience Composer veröffentlicht einen neuen Stream in der sessionId.
Sie haben vielleicht bemerkt, dass es ein zusätzliches Objekt gibt properties enthält, das einen name Parameter enthält. Dieser Name wird sich als nützlich erweisen, wenn wir auf streamCreated Ereignisse auf der Client-Seite hören. Wir werden später darauf zurückkommen, aber im Moment müssen Sie nur wissen, dass dies der Name des Streams ist, den wir in der Sitzung veröffentlichen werden.
app.get('/ec', (req, res) => {
const options = {
root: path.join(__dirname),
};
res.sendFile('public/ec.html', options);
});
Integration mit Google Cloud Text APIs
Sie können sich den fertigen Beispielcode für den Google-Connector ansehen in diesem Repository. Lassen Sie uns jedoch kurz darüber sprechen. Die Hauptfunktion, die die Verbindung mit Google startet, heißt startRecognised. Wir müssen das Konfigurationsobjekt mit der Ausgangssprache, dem Modell und der Kodierung definieren. Die gewählten Parameter können Sie dem Beispielcode entnehmen.
startRecognizer() {
const config = {
encoding: encoding,
sampleRateHertz: sampleRateHertz,
model: model,
enableAutomaticPunctuation: true,
languageCode: this.language,
};
const request = {
config: config,
interimResults: true,
};
this.recognizeStream = this.speechClient.streamingRecognize(request);
this.recognizeStream.on('data', async (data) => {
let originalText = data.results\[0].alternatives\[0].transcript;
console.log('\[' + this.id + ']\[User]' + originalText);
let translatedText = await this.translate(originalText);
if (this.transcriptAvailableCallback) {
this.transcriptAvailableCallback({
original: originalText,
translated: translatedText,
id: this.id,
});
}
this.getAudioData(translatedText);
});
this.recognizeStream.on('error', (err) => {
console.error(err);
this.tryEndAudioStream();
if (this.errorCallback) {
this.errorCallback(err);
}
});
this.recognizeStream.on('finish', (res) => {});
console.log('\[' + this.id + '] Stream Created');
this.waitingRestart = false;
return this.recognizeStream;
}
Sobald wir die Sprache von Google transkribiert haben, können wir sie durch die Übersetzen-API und den übersetzten Text in Audiodaten umwandeln, indem wir die Text To Speech API. Dies ist die Definition der translate-Methode, die zur Übersetzung des Textes in die Zielsprache verwendet wird
async translate(text) {
let output = '';
try {
let [translations] = await this.translationClient.translate(text, this.outputLanguage);
translations = Array.isArray(translations) ? translations : [translations];
translations.forEach((translation, i) => {
output += `${translation}`;
});
} catch (err) {
console.log(err);
}
console.log(output);
return output;
}
Sobald wir den Text übersetzt haben, rufen wir die playTTS-Methode auf, um Audiodaten aus dem übersetzten Text zu erhalten. Die Audiodaten werden noch nicht abgespielt, wir wandeln nur den übersetzten Text in Audiodaten um. Das Request-Objekt enthält mehrere Parameter wie die Kodierung und die Stimme. Sie können es anpassen, indem Sie sich die Google Text-to-Speech-Dokumente
async getAudioData(text, isSessionEnding = false) {
try {
this.sessionEnding = isSessionEnding;
const request = {
input: {
text: text
},
voice: {
languageCode: this.outputLanguage,
ssmlGender: 'NEUTRAL'
},
audioConfig: {
audioEncoding: encoding,
sampleRateHertz: sampleRateHertz,
},
};
const [response] = await this.ttsClient.synthesizeSpeech(request);
if (this.audioChunkAvailableCallback) {
this.audioChunkAvailableCallback(response.audioContent);
}
} catch (err) {
if (this.errorCallback) {
this.errorCallback(err);
}
}
} Schlussfolgerung
Zusammenfassend lässt sich sagen, dass der Einsatz von Videoübersetzung in Echtzeit nicht nur Sprachbarrieren beseitigt, sondern auch eine völlig neue Dimension der globalen Kommunikationsmöglichkeiten eröffnet. Welche neuen Dinge werden Sie entwickeln? Welche neuen Funktionen würden Sie begeistern? Lassen Sie es uns auf unseremr Vonage-Community Slack oder senden Sie uns eine Nachricht auf X, früher bekannt als Twitter.
Haftungsausschluss
Die Anwendungslogik, die Zusammenstellung der Komponenten und die API-Aufrufe, die in diesem Artikel und im entsprechenden Github-Repository beschrieben werden, sind eine Teilmenge der Ansprüche, die Teil eines anhängigen Vonage-Patents sind. Sie können diesen Referenz-Quellcode und die Anwendungslogik für Ihre eigenen kommerziellen Implementierungen verwenden, indem Sie die Video API von Vonage und beliebige KI-Dienstleister für Funktionen wie Spracherkennung, Übersetzung, Text-to-Speech