Api publique.
Introduction
Speaqr fournit des services de traduction en temps réel via une API construite sur Socket.IO. Les clients peuvent se connecter, envoyer des données audio et recevoir des résultats traités, tels que des transcriptions, des traductions et de la voix synthétisée.Speaqr est conçu pour les conversations, où la vitesse est cruciale pour offrir une expérience de qualité. Pour cette raison, l'api de Speaqr suit la philosophie de "session on socket".Une fois authentifié, le consommateur maintient une connexion ouverte via socket jusqu'à la déconnexion, gérant la plupart des interactions à travers des événements, sauf quelques exceptions.Pour utiliser l'API tu as besoin d'une clé API valide. Pour l'obtenir, contactez-nous via le formulaire de contact.Url
L'url d'accès à l'api est :https://public.speaqr.ai
Postman
Tu pouvez télécharger la collection de Postman et l'environnement pour tester les méthodes de l'API.N'oublie pas de mettre dans l'environnement taclé API
valide.Télécharger la collectionTélécharger l'environnementErreurs
Les erreurs sont toujours renvoyées dans un JSON avec les champs suivants :Champ d'application | Explication |
---|---|
code | Le code général de l'erreur. |
error | Le code d'erreur spécifique dans l'erreur générale. |
description | La description textuelle de l'erreur. |
Exemple
{
"code": "bad_file",
"error": "language_not_detected",
"description": "The audio language could not be determined"
}
Méthodes
L'API dispose de plusieurs méthodes. Ci-dessous, leurs utilisations et configurations sont détaillées.api/languages
Obtenez la liste des langues prises en charge par le SDK pour la transcription, la traduction et la synthèse vocale.Endpoint
GET https://public.speaqr.ai/api/languages
En-têtes
Exemple
const myHeaders = new Headers();
myHeaders.append("x-api-key", "xxxxxxx"); //Your valid api key
const requestOptions = {
method: "GET",
headers: myHeaders
};
fetch("https://public.speaqr.ai/api/languages", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.error(error));
import requests
headers = {
"x-api-key": "xxxxxxx" # Your valid api key
}
response = requests.get("https://public.speaqr.ai/api/languages", headers=headers)
if response.status_code == 200:
print("Languages available:", response.json())
else:
print("Error:", response.status_code, response.text)
import okhttp3.*;
public class Languages {
public static void main(String[] args) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://public.speaqr.ai/api/languages")
.header("x-api-key", "xxxxxxx") //Your valid api key
.get()
.build();
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful() && response.body() != null) {
System.out.println("Languages available: " + response.body().string());
} else {
System.out.println("Error: " + response.code());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Réponse
/api/voices
Obtenez la liste des voix disponibles pour la synthèse vocale (TTS) dans une langue. Il est possible de filtrer le résultat par genre de voix, mode de réponse et/ou moteur de voix.Par ce moyen, on peut savoir si une configuration de langue, de genre, de mode de réponse et de moteur peut être réalisée, car il n'existe pas de voix pour toutes les combinaisons.Endpoint
GET https://public.speaqr.ai/api/voices
En-têtes
Paramètres
QUERY
Exemple
const apiKey = 'xxxxxxx'; // Your valid API key
const params = new URLSearchParams({
language: 'en-gb',
mode: 'block',
voiceGender: 'M',
voiceEngine: 'neural',
voiceEngine: 'standard'
});
const requestOptions = {
method: 'GET',
headers: {
'x-api-key': apiKey
}
};
fetch(`https://public.speaqr.ai/api/voices?${params.toString()}`, requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.error(error));
import requests
params = {
"language": "es-es",
"mode": "block",
"voiceEngine": ["neural", "standard"],
"voiceGender": "M"
}
headers = {
"x-api-key": "xxxxxxx" # Your valid API key
}
response = requests.get("https://public.speaqr.ai/api/voices", params=params, headers=headers)
if response.status_code == 200:
print("Voices available:", response.json())
else:
print("Error:", response.status_code, response.text)
import okhttp3.*;
public class ListAvailableVoices {
public static void main(String[] args) {
OkHttpClient client = new OkHttpClient();
HttpUrl url = HttpUrl.parse("https://public.speaqr.ai/api/voices").newBuilder()
.addQueryParameter("language", "en-gb")
.addQueryParameter("mode", "block")
.addQueryParameter("voiceGender", "M")
.addQueryParameter("voiceEngine", "neural")
.addQueryParameter("voiceEngine", "standard")
.build();
Request request = new Request.Builder()
.url(url)
.get()
.addHeader("x-api-key", "xxxxxxx") // Your valid API key
.build();
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful() && response.body() != null) {
System.out.println("Voices available: " + response.body().string());
} else {
System.out.println("Error: " + response.code() + " - " + response.message());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Réponse
batch/file
Traitez un fichier audio et effectuez l'opération spécifiée dansmode
. Le résultat dépendra du mode sélectionné.Endpoint
POST https://public.speaqr.ai/api/batch/file
En-têtes
Paramètres
FORM DATA
Exemple
const myHeaders = new Headers();
myHeaders.append("x-api-key", "xxxxxxx"); //Your valid api key
const wavFile = getWav();
const formData = new FormData();
formData.append("mode", "stt");
formData.append("file", wavFile, "dummy.wav");
const requestOptions = {
method: "POST",
headers: myHeaders,
body: formData,
};
fetch("https://public.speaqr.ai/api/batch/file", requestOptions)
.then((response) => response.text())
.then((result) => console.log("Response:", result))
.catch((error) => console.error("Error:", error));
//Function to generate a dummy wav
function getWav(){
const sampleRate = 16000;
const numChannels = 1;
const duration = 2;
const bitsPerSample = 16;
//We generate empty data (silence)
const numSamples = sampleRate * duration;
const buffer = new ArrayBuffer(numSamples * (bitsPerSample / 8));
const view = new DataView(buffer);
//We write the WAV header
writeString(view, 0, "RIFF"); // ChunkID
view.setUint32(4, 36 + buffer.byteLength, true); // ChunkSize
writeString(view, 8, "WAVE") // Format
writeString(view, 12, "fmt ") // Subchunk1ID
view.setUint32(16, 16, true); // Subchunk1Size
view.setUint16(20, 1, true); // AudioFormat (PCM)
view.setUint16(22, numChannels, true); // NumChannels
view.setUint32(24, sampleRate, true); // SampleRate
view.setUint32(28, sampleRate * numChannels * (bitsPerSample / 8), true); // ByteRate
view.setUint16(32, numChannels * (bitsPerSample / 8), true); // BlockAlign
view.setUint16(34, bitsPerSample, true); // BitsPerSample
writeString(view, 36, "data") // Subchunk2ID
view.setUint32(40, buffer.byteLength, true); // Subchunk2Size
//We create a valid Blob in WAV format
const wavBlob = new Blob([buffer], { type: "audio/wav" });
return new File([wavBlob], "dummy.wav", { type: "audio/wav" });
}
//Function to write text to WAV header
function writeString(view, offset, string) {
for (let i = 0; i < string.length; i++) {
view.setUint8(offset + i, string.charCodeAt(i));
}
}
import requests
import struct
# //Function to generate a dummy wav
def generate_wav():
sample_rate = 16000
num_channels = 1
duration = 2
bits_per_sample = 16
num_samples = sample_rate * duration
byte_rate = sample_rate * num_channels * (bits_per_sample // 8)
block_align = num_channels * (bits_per_sample // 8)
# Cabecera WAV
wav_header = struct.pack(
'<4sI4s4sIHHIIHH4sI',
b'RIFF', # ChunkID
36 + num_samples * block_align, # ChunkSize
b'WAVE', # Format
b'fmt ', # Subchunk1ID
16, # Subchunk1Size
1, # AudioFormat (PCM)
num_channels, # NumChannels
sample_rate, # SampleRate
byte_rate, # ByteRate
block_align, # BlockAlign
bits_per_sample, # BitsPerSample
b'data', # Subchunk2ID
num_samples * block_align # Subchunk2Size
)
# We generate empty data (silence)
audio_data = b'\x00' * (num_samples * block_align)
with open("dummy.wav", "wb") as f:
f.write(wav_header + audio_data)
return "dummy.wav"
wav_file = generate_wav()
files = {
"file": ("dummy.wav", open(wav_file, "rb"), "audio/wav")
}
data = {
"mode": "stt",
}
headers = {
"x-api-key": "xxxxxxx" # Your valid api key
}
response = requests.post("https://public.speaqr.ai/api/batch/file", headers=headers, files=files, data=data)
print("Response:", response.text)
import okhttp3.*;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class BatchFile {
public static void main(String[] args) {
String apiUrl = "https://public.speaqr.ai/api/batch/file";
String apiKey = "xxxxxxx"; //Your valid api key
// Generate dummy WAV file
String wavFilePath = "dummy.wav";
generateWavFile(wavFilePath);
// Send request to API
sendFileToApi(apiUrl, apiKey, wavFilePath);
}
// Function to generate a dummy WAV file
public static void generateWavFile(String filePath) {
int sampleRate = 16000;
int numChannels = 1;
int duration = 2;
int bitsPerSample = 16;
int numSamples = sampleRate * duration;
int byteRate = sampleRate * numChannels * (bitsPerSample / 8);
int blockAlign = numChannels * (bitsPerSample / 8);
int subchunk2Size = numSamples * blockAlign;
int chunkSize = 36 + subchunk2Size;
try (FileOutputStream fos = new FileOutputStream(filePath);
DataOutputStream dos = new DataOutputStream(fos)) {
// Write WAV header
dos.writeBytes("RIFF"); // ChunkID
dos.writeInt(Integer.reverseBytes(chunkSize)); // ChunkSize
dos.writeBytes("WAVE"); // Format
dos.writeBytes("fmt "); // Subchunk1ID
dos.writeInt(Integer.reverseBytes(16)); // Subchunk1Size
dos.writeShort(Short.reverseBytes((short) 1)); // AudioFormat (PCM)
dos.writeShort(Short.reverseBytes((short) numChannels)); // NumChannels
dos.writeInt(Integer.reverseBytes(sampleRate)); // SampleRate
dos.writeInt(Integer.reverseBytes(byteRate)); // ByteRate
dos.writeShort(Short.reverseBytes((short) blockAlign)); // BlockAlign
dos.writeShort(Short.reverseBytes((short) bitsPerSample)); // BitsPerSample
dos.writeBytes("data"); // Subchunk2ID
dos.writeInt(Integer.reverseBytes(subchunk2Size)); // Subchunk2Size
// Write silent audio data (zeros)
byte[] silence = new byte[subchunk2Size];
dos.write(silence);
System.out.println("WAV file generated: " + filePath);
} catch (IOException e) {
e.printStackTrace();
}
}
// Function to send file to API
public static void sendFileToApi(String apiUrl, String apiKey, String filePath) {
OkHttpClient client = new OkHttpClient();
// Create file request body
File file = new File(filePath);
RequestBody fileBody = RequestBody.create(file, MediaType.get("audio/wav"));
// Create multipart form-data request
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("mode", "stt")
.addFormDataPart("file", file.getName(), fileBody)
.build();
// Build HTTP request
Request request = new Request.Builder()
.url(apiUrl)
.post(requestBody)
.addHeader("x-api-key", apiKey)
.build();
// Execute request
try (Response response = client.newCall(request).execute()) {
String responseBody = (response.body() != null) ? response.body().string() : "No response body";
if (response.isSuccessful()) {
System.out.println("Response: " + responseBody);
} else {
System.out.println("Error: " + response.code() + " - " + response.message());
System.out.println("Response Body: " + responseBody); // Print JSON error response
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Réponse
Le JSON de réponse contiendra uniquement les champs du résultat spécifié dans mode
. Le champ file.data
est un ArrayBuffer
au format mp3.
Erreurs
Raccordement à la prise
Compatibilité
Pour utiliser l'api, il faut développer dans un langage compatible avec un client socket.io : Javascript, Java, C++, Swift, Dart, Python, .Net, Rust, Kotlin, PHP. https://socket.io/docs/v4Espaces de noms
Les sockets sont organisés par espaces de noms séparés selon la fonction à réaliser, transcription, traduction, synthèse vocale, ou le cycle complet.La façon de les instancier est indépendante de l'espace de noms à utiliser, bien que chacun d'eux reçoive ses propres paramètres.Exemple
const namespace = 'translator';
const params = {
languageIdSource: 'en-gb',
languageIdTarget: 'fr-fr'
};
const Sockets = io("https://public.speaqr.ai/" + namespace, {
transports: ['websocket'],
upgrade: false,
auth: {token: "xxxxxxx"}, //Your valid api key
autoConnect: false,
reconnection: false,
query: params
});
Sockets.on('connect', () => console.log('connect!'));
Sockets.on('disconnect', reason => console.log('disconnect!', reason));
console.debug('Connecting to sockets...');
Sockets.connect();
setTimeout(() => Sockets.disconnect(), 5000);
import socketio
import threading
sio = socketio.Client()
api_key = "xxxxxxx"
params = {
"languageIdSource": "en-gb",
"languageIdTarget": "fr-fr"
}
query_string = "&".join(f"{k}={v}" for k, v in params.items())
@sio.on("connect", namespace="/translator")
def connect():
print("Connected to /translator")
@sio.on("disconnect", namespace="/translator")
def disconnect():
print("Disconnected from /translator")
@sio.on("connect_error", namespace="/translator")
def connect_error(data):
print("Connection error:", data)
sio.connect(
f"https://public.speaqr.ai/translator?{query_string}",
auth={"token": api_key},
transports=["websocket"],
namespaces=["/translator"]
)
print("Socket:", sio.connected)
print("Socket ID:", sio.sid)
print("Connected:", sio.connected)
print("Transport:", sio.transport())
threading.Timer(5, sio.disconnect).start()
sio.wait()
import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;
import java.util.HashMap;
import java.util.Map;
import java.net.URI;
import java.net.URISyntaxException;
public class Sockets_connect {
public static void main(String[] args) {
try {
// Define connection parameters
String params = "languageIdTarget=fr-fr&languageIdSource=en-gb";
String url = "https://public.speaqr.ai/translator?" + params;
// Configure WebSocket options
IO.Options options = new IO.Options();
options.transports = new String[]{"websocket"};
options.forceNew = true;
options.reconnection = false;
Map authData = new HashMap<>();
authData.put("token", "xxxxxxx");
options.auth = authData;
// Create socket instance
Socket socket = IO.socket(new URI(url), options);
// Event listeners
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("connect!");
}
});
socket.on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("disconnect! Reason: " + (args.length > 0 ? args[0] : "unknown"));
System.exit(0);
}
});
// Connecting
System.out.println("Connecting to sockets...");
socket.connect();
// Disconnect after 5 seconds
Thread.sleep(5000);
socket.disconnect();
} catch (URISyntaxException | InterruptedException e) {
e.printStackTrace();
}
}
}
Espaces de noms
Les espaces de noms pris en charge par l'API de Speaqr pour sa connexion par sockets sont décrits ci-dessous.Transcription
Effectuez la transcription de l'audio qui tu est envoyé.Url
https://public.speaqr.ai/stt
Paramètres
Traduction
Réalisez la traduction du texte qui tu est envoyé d'une langue à une autre.Url
https://public.speaqr.ai/translator
Paramètres
Synthèse vocale
Générer un audio à partir du texte envoyé.Url
https://public.speaqr.ai/tts
Paramètres
Transcription - traduction - synthèse
Il transcrit l'audio qui lui est envoyé, le traduit et synthétise un nouvel audio avec la traduction obtenue.Url
https://public.speaqr.ai/sts
Paramètres
Événements reçus
Les événements spécifiques des sockets de l'api sont décrits ci-dessous.connected
Si cet événement est reçu, c'est que la connexion a réussi. Il reçoit un objet avec les paramètres qui ont été utilisés pour la connexion.Réponse
start
Jusqu'à ce que cet événement soit reçu, les sockets ne seront pas prêts à recevoir du texte ou de l'audio, il est donc important d'attendre de recevoir cet événement avant d'envoyer quoi que ce soit. Une réponse booléenne peut être reçue, ou si l'audio en streaming a été invoqué, l'URL pour récupérer cet audio.Exemple de "connecté" et "démarrer"
const namespace = 'sts';
const params = {
languageIdTarget: 'fr-fr',
languageIdSource: 'en-gb',
sendAudio: JSON.stringify({
broadcastVia: 'chunk'
}),
receiveAudio: JSON.stringify({
obtainVia: 'chunk',
codec: 'mp3',
sampleRate: 16000
})
};
const Sockets = io("https://public.speaqr.ai/" + namespace, {
transports: ['websocket'],
upgrade: false,
auth: {token: "xxxxxxx"}, //Your valid api key
autoConnect: false,
reconnection: false,
query: params
});
Sockets.on('connect', () => {
console.log('connect!');
console.log('Waiting to be able to send data...');
});
Sockets.on('connected', (status) => {
console.log('Connection status', status);
});
Sockets.on('start', () => {
console.log('Speaqr is ready to receive data!');
setTimeout(() => Sockets.disconnect(), 5000);
});
Sockets.on('disconnect', reason => console.log('disconnect!', reason));
console.debug('Connecting to sockets...');
Sockets.connect();
import socketio
import urllib.parse
import os
api_key = "xxxxxxx"
params = {
"languageIdSource": "en-gb",
"languageIdTarget": "fr-fr",
"sendAudio": '{"broadcastVia": "chunk"}',
"receiveAudio": '{"obtainVia": "chunk", "codec": "mp3", "sampleRate": 16000}'
}
query_string = urllib.parse.urlencode(params)
sio = socketio.Client()
@sio.event(namespace="/sts")
def connect():
print("connect!")
print("Waiting to be able to send data...")
@sio.on("connected", namespace="/sts")
def on_connected(status):
print("Connection status:", status)
@sio.on("start", namespace="/sts")
def on_start(data):
print("Speaqr is ready to receive data.")
sio.sleep(5)
sio.disconnect()
@sio.event(namespace="/sts")
def disconnect(reason=None):
print("disconnect!", reason)
os._exit(0)
print("Connecting to Speaqr sockets...")
sio.connect(
f"https://public.speaqr.ai/sts?{query_string}",
auth={"token": api_key},
transports=["websocket"],
namespaces=["/sts"]
)
sio.wait()
import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
public class Sockets_evt_status_con {
public static void main(String[] args) {
try {
// Define connection parameters
String params = "languageIdTarget=fr-fr&languageIdSource=en-gb" +
"&sendAudio=" + encode("{\"broadcastVia\": \"chunk\"}") +
"&receiveAudio=" + encode("{\"obtainVia\": \"chunk\", \"codec\": \"mp3\", \"sampleRate\": 16000}");
String url = "https://public.speaqr.ai/sts?" + params;
// Configure WebSocket options
IO.Options options = new IO.Options();
options.transports = new String[]{"websocket"};
options.forceNew = true;
options.reconnection = false;
// Set authentication token
Map authData = new HashMap<>();
authData.put("token", "xxxxxxx"); // Your valid API key
options.auth = authData;
// Create socket instance
Socket socket = IO.socket(new URI(url), options);
// Event listeners
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("connect!");
System.out.println("Waiting to be able to send data...");
}
});
socket.on("connected", new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("Connection status: " + args[0]);
}
});
socket.on("start", new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("Speaqr is ready to receive data!");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
socket.disconnect();
}
});
socket.on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("disconnect! Reason: " + (args.length > 0 ? args[0] : "unknown"));
System.exit(0);
}
});
// Connecting
System.out.println("Connecting to sockets...");
socket.connect();
} catch (URISyntaxException e) {
e.printStackTrace();
System.exit(1);
}
}
// Helper method to encode JSON in query params
private static String encode(String value) {
return value.replace("{", "%7B").replace("}", "%7D")
.replace("\"", "%22").replace(":", "%3A")
.replace(",", "%2C").replace(" ", "%20");
}
}
result
Les champs de l'objet reçu dépendront de l'espace de noms utilisé. Voici un objet pour l'espace de nomssts
qui contient tous les champs possibles.Réponse
error
Cet événement reçoit un objet avec différentes descriptions d'erreurs qui pourraient survenir, soit en raison de défaillances dans la programmation pour instancier les modes d'utilisation, soit dans les données qui sont tentées d'être traitées. Les erreurs d'exécution possibles sont listées.Erreurs
Diffusion d'événements
Les envois pour le traitement des données qui prennent en charge les sockets sont décrits ci-dessous. Les fonctions d'émission reçoivent unack
avec le statut de l'envoi.text
Envoyez un texte à traiter.Exemple
const namespace = 'translator';
const params = {
languageIdSource: 'en-gb',
languageIdTarget: 'fr-fr'
};
const Sockets = io("https://public.speaqr.ai/" + namespace, {
transports: ['websocket'],
upgrade: false,
auth: {token: "xxxxxxx"}, //Your valid api key
autoConnect: false,
reconnection: false,
query: params
});
Sockets.on('connect', () => {
console.log('connect!');
console.log('Waiting to be able to send data...');
});
Sockets.on('error', (error) => {
console.log('error!', error);
});
Sockets.on('connected', (status) => {
console.log('Connection status', status);
});
Sockets.on('start', () => {
console.log('Speaqr is ready to receive data!');
console.log('I send text to translate...');
Sockets.emit('text', 'Hello word!. I want to translate it into French.', (ack) =>{
console.log('ack emit text', ack);
});
});
Sockets.on('result', (response) => {
console.log('response', response);
Sockets.disconnect();
});
Sockets.on('disconnect', reason => console.log('disconnect!', reason));
console.debug('Connecting to sockets...');
Sockets.connect();
import socketio
import urllib.parse
import os
api_key = "xxxxxxx"
params = {
"languageIdSource": "en-gb",
"languageIdTarget": "fr-fr"
}
query_string = urllib.parse.urlencode(params)
sio = socketio.Client()
@sio.event(namespace="/translator")
def connect():
print("connect!")
print("Waiting to be able to send data...")
@sio.on("error", namespace="/translator")
def on_error(error):
print("error!", error)
@sio.on("connected", namespace="/translator")
def on_connected(status):
print("Connection status", status)
@sio.on("start", namespace="/translator")
def on_start(data):
print("Speaqr is ready to receive data!")
print("I send text to translate...")
sio.emit("text", "Hello world! I want to translate it into French.", namespace="/translator", callback=on_ack)
@sio.on("result", namespace="/translator")
def on_result(response):
print("response", response)
sio.disconnect()
@sio.event(namespace="/translator")
def disconnect(reason=None):
print("disconnect!", reason)
os._exit(0)
def on_ack(ack):
print("ack emit text", ack)
print("Connecting to sockets...")
sio.connect(
f"https://public.speaqr.ai/translator?{query_string}",
auth={"token": api_key},
transports=["websocket"],
namespaces=["/translator"]
)
sio.wait()
import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;
import io.socket.client.Ack;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
public class Sockets_emit_text {
public static void main(String[] args) {
try {
// Define connection parameters
String params = "languageIdSource=en-gb&languageIdTarget=fr-fr";
String url = "https://public.speaqr.ai/translator?" + params;
// Configure WebSocket options
IO.Options options = new IO.Options();
options.transports = new String[]{"websocket"};
options.forceNew = true;
options.reconnection = false;
// Set authentication token
Map authData = new HashMap<>();
authData.put("token", "xxxxxxx"); // Your valid API key
options.auth = authData;
// Create socket instance
Socket socket = IO.socket(new URI(url), options);
// Event listeners
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("connect!");
System.out.println("Waiting to be able to send data...");
}
});
socket.on("error", new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("error! " + (args.length > 0 ? args[0] : "unknown"));
}
});
socket.on("connected", new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("Connection status: " + (args.length > 0 ? args[0] : "unknown"));
}
});
socket.on("start", new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("Speaqr is ready to receive data!");
System.out.println("I send text to translate...");
// Emit text and handle acknowledgment
socket.emit("text", "Hello world! I want to translate it into French.", new Ack() {
@Override
public void call(Object... ackArgs) {
System.out.println("ack emit text: " + (ackArgs.length > 0 ? ackArgs[0] : "No ack received"));
}
});
}
});
socket.on("result", new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("response: " + (args.length > 0 ? args[0] : "unknown"));
socket.disconnect();
}
});
socket.on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("disconnect! Reason: " + (args.length > 0 ? args[0] : "unknown"));
System.exit(0);
}
});
// Connecting
System.out.println("Connecting to sockets...");
socket.connect();
} catch (URISyntaxException e) {
e.printStackTrace();
System.exit(1);
}
}
}
write_stream
Envoyez un extrait audio pour être traité.Exemple
Dans l'exemple suivant, le microphone de l'appareil est capturé et la transcription de la première phrase entendue est effectuée.
let mediaRecorder = null;
const namespace = 'stt';
const params = {
languageIdSource: 'en-gb',
sendAudio: JSON.stringify({
broadcastVia: 'chunk'
})
};
const Sockets = io("https://public.speaqr.ai/" + namespace, {
transports: ['websocket'],
upgrade: false,
auth: {token: "xxxxxxx"}, //Your valid api key
autoConnect: false,
reconnection: false,
query: params
});
Sockets.on('connect', () => {
console.log('connect!');
console.log('Waiting to be able to send data...');
});
Sockets.on('error', (error) => {
console.log('error!', error);
});
Sockets.on('connected', (status) => {
console.log('Connection status', status);
});
Sockets.on('start', () => {
console.log('Speaqr is ready to receive data. Speak now in English!!!!');
start();
});
Sockets.on('result', (response) => {
console.log('first response\n-----------------------\n\n');
console.log(response);
console.log('\n\n-----------------------\n\n');
console.log('We stopped listening!');
stop();
Sockets.disconnect();
});
Sockets.on('disconnect', reason => console.log('disconnect!', reason));
console.debug('Connecting to sockets...');
Sockets.connect();
// Start capturing and processing microphone audio
const start = async () => {
navigator.mediaDevices.getUserMedia({ audio: true })
.then(stream => {
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = ondataavailable;
mediaRecorder.start(500);
})
.catch(error => {
console.error("Error starting recording:", error);
});
}
// Here you receive each audio fragment in a Blob
const ondataavailable = (event) => {
if (event.data && event.data.size > 0) {
const audioChunk = event.data;
console.log('audio chunk', audioChunk);
Sockets.emit('write_stream', audioChunk, (ack) => {
if (!ack) console.error("Error write_stream", ack);
});
}
};
// Stop the process
const stop = async () => {
try {
//We stop the MediaRecorder
if (mediaRecorder){
mediaRecorder.stop();
mediaRecorder = null;
}
} catch (error) {
console.error("Error while stopping resources", error);
}
}
import socketio
import sounddevice as sd
import numpy as np
import urllib.parse
import signal
import sys
import threading
import time
SAMPLE_RATE = 16000
CHANNELS = 1
CHUNK_SIZE = 1024
api_key = "xxxxxxx"
params = {
"languageIdSource": "en-gb",
"sendAudio": '{"broadcastVia": "chunk", "codec": "linear16", "sampleRate": 16000}',
}
query_string = urllib.parse.urlencode(params)
sio = socketio.Client()
stream = None
should_exit = False
@sio.event(namespace="/stt")
def connect():
print("connect!")
@sio.on("connected", namespace="/stt")
def on_connected(status):
print("Connection status", status)
@sio.on("start", namespace="/stt")
def on_start(_):
print("Speaqr is ready to receive data. Speak now in English!")
start_recording()
@sio.on("result", namespace="/stt")
def on_result(response):
print("response:\n", response)
stop()
@sio.event(namespace="/stt")
def disconnect(reason=None):
print("disconnect!", reason)
global should_exit
should_exit = True
@sio.on("error", namespace="/stt")
def on_error(error):
print("error!", error)
def audio_callback(indata, frames, time, status):
if status:
print(status)
audio_data = indata.copy().astype(np.int16).tobytes()
sio.emit("write_stream", audio_data, namespace="/stt", callback=on_ack)
def on_ack(ok):
if not ok:
print("write_stream ack = False")
def start_recording():
global stream
stream = sd.InputStream(samplerate=SAMPLE_RATE, channels=CHANNELS, dtype='int16',
blocksize=CHUNK_SIZE, callback=audio_callback)
stream.start()
print("Recording... Press Ctrl+C to stop.")
def stop():
global stream, should_exit
if stream:
print("Stopping and closing stream...")
stream.stop()
stream.close()
stream = None
print("Disconnecting socket...")
sio.disconnect()
should_exit = True
def signal_handler(sig, frame):
print("Ctrl+C pressed. Exiting...")
stop()
signal.signal(signal.SIGINT, signal_handler)
print("Connecting to sockets...")
sio.connect(
f"https://public.speaqr.ai/stt?{query_string}",
auth={"token": api_key},
transports=["websocket"],
namespaces=["/stt"]
)
# Espera activa (se puede interrumpir con Ctrl+C en Windows)
while not should_exit:
time.sleep(0.2)
import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;
import javax.sound.sampled.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class Sockets_emit_write_stream {
private static Socket socket;
private static boolean recording = false;
private static TargetDataLine microphone;
public static void main(String[] args) {
try {
// Define connection parameters
String params = "languageIdSource=en-gb" +
"&sendAudio=" + encode("{\"broadcastVia\": \"chunk\", \"codec\": \"linear16\", \"sampleRate\": 16000}");
String url = "https://public.speaqr.ai/stt?" + params;
// Configure WebSocket options
IO.Options options = new IO.Options();
options.transports = new String[]{"websocket"};
options.forceNew = true;
options.reconnection = false;
// Set authentication token
Map authData = new HashMap<>();
authData.put("token", "xxxxxxx"); // Your valid API key
options.auth = authData;
// Create socket instance
socket = IO.socket(new URI(url), options);
// Event listeners
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("connect!");
System.out.println("Waiting to be able to send data...");
}
});
socket.on("error", new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("error! " + (args.length > 0 ? args[0] : "unknown"));
}
});
socket.on("connected", new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("Connection status: " + (args.length > 0 ? args[0] : "unknown"));
}
});
socket.on("start", new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("Speaqr is ready to receive data. Speak now in English!!!!");
startRecording();
}
});
socket.on("result", new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("first response\n-----------------------\n\n");
System.out.println(args.length > 0 ? args[0] : "unknown");
System.out.println("\n\n-----------------------\n\n");
System.out.println("We stopped listening!");
stopRecording();
socket.disconnect();
}
});
socket.on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("disconnect! Reason: " + (args.length > 0 ? args[0] : "unknown"));
System.exit(0);
}
});
// Connecting
System.out.println("Connecting to sockets...");
socket.connect();
} catch (URISyntaxException e) {
e.printStackTrace();
System.exit(1);
}
}
// Start capturing and processing microphone audio
private static void startRecording() {
recording = true;
new Thread(() -> {
try {
AudioFormat format = new AudioFormat(16000, 16, 1, true, false);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
if (!AudioSystem.isLineSupported(info)) {
System.err.println("Microphone not supported");
return;
}
microphone = (TargetDataLine) AudioSystem.getLine(info);
microphone.open(format);
microphone.start();
byte[] buffer = new byte[1024];
ByteArrayOutputStream out = new ByteArrayOutputStream();
System.out.println("Recording...");
while (recording) {
int bytesRead = microphone.read(buffer, 0, buffer.length);
if (bytesRead > 0) {
// Print a small portion of the buffer for debugging
System.out.println("Captured audio data: " + Arrays.toString(Arrays.copyOf(buffer, 10)) + "...");
socket.emit("write_stream", buffer);
}
}
microphone.stop();
microphone.close();
out.close();
System.out.println("Recording stopped.");
} catch (LineUnavailableException | IOException e) {
e.printStackTrace();
}
}).start();
}
// Stop the process
private static void stopRecording() {
recording = false;
}
// Helper method to encode JSON in query params
private static String encode(String value) {
return value.replace("{", "%7B").replace("}", "%7D")
.replace("\"", "%22").replace(":", "%3A")
.replace(",", "%2C").replace(" ", "%20");
}
}
Ce site web utilise des cookies
Les cookies de ce site web sont utilisées pour personnaliser le contenu et analyser le trafic.
Tu pouvez trouver les détails de celles-ci dans la section Politique de confidentialité