Documentación para desarrolladores

Api pública.

Introducción

Speaqr proporciona servicios de traducción en tiempo real mediante un api construida sobre Socket.IO. Los clientes pueden conectarse, enviar datos de audio y recibir resultados procesados, como transcripciones, traducciones y voz sintetizada.Speaqr está diseñado para conversaciones, donde la velocidad es crucial para ofrecer una experiencia de calidad. Por esta razón, el api de Speaqr sigue la filosofía de "session on socket".Una vez autenticado, el consumidor mantiene una conexión abierta vía socket hasta la desconexión, gestionando la mayoría de las interacciones a través de eventos, salvo algunas excepciones.Para usar el api necesitas un api key válido. Para obtenerlo ponte en contacto con nostros a través del formulario de contratación.

Url

La url de acceso a la api es: https://public.speaqr.ai

Postman

Puedes descargarte la colección de Postman y el entorno para probar los métodos de la api.Recuerda poner en el entorno tu api key válida.Descargar la colecciónDescargar el entorno

Errores

Los errores siempre se devuelven en un JSON con los siguientes campos:
CampoExplicación
codeEl código general del error.
errorEl código expecifico de error dentro del error general.
descriptionLa descripción textual del error.

Ejemplo


				{
					"code": "bad_file",
					"error": "language_not_detected",
					"description": "The audio language could not be determined"
				}
			

Métodos

La api dispone de varios métodos. A continuación, se detallan sus usos y configuraciones.

api/languages

Obtiene la lista de idiomas soportados por el SDK para transcripción, traducción y síntesis de voz.

Endpoint

GET https://public.speaqr.ai/api/languages

Cabeceras

Ejemplo

Javascript
Python
Java

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

Respuesta


						

/api/voices

Obtiene la lista de voces disponibles para la síntesis de voz (TTS) en un idioma. Opcionalmente se puede filtrar el resultado por género de voz, modo de respuesta y/o motor de voz.Por este medio se puede saber si una configuración de idioma, género, modo de respuesta y motor puede ser realizada, ya que no para todas las combinaciones existen voces.

Endpoint

GET https://public.speaqr.ai/api/voices

Cabeceras

Parámetros

QUERY

Ejemplo

Javascript
Python
Java

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

Respuesta


						

batch/file

Procesa un archivo de audio y realiza la operación especificada en mode. El resultado dependerá del modo seleccionado.

Endpoint

POST https://public.speaqr.ai/api/batch/file

Cabeceras

Parámetros

FORM DATA

Ejemplo

Javascript
Python
Java

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

Respuesta

El JSON de respuesta contendrá solo los campos del resultado especificado en mode. El campo file.data es un ArrayBuffer en formato mp3.

						

Errores

Conexión por sockets

Compatibilidad

Para usar el api hay que hacer el desarrollo en un lenguaje compatible con un cliente de socket.io: Javascript, Java, C++, Swift, Dart, Python, .Net, Rust, Kotlin, PHP. https://socket.io/docs/v4

Espacios de nombres

Los sockets están organizados por espacios de nombres seprados según la función a realizar, transcripcion, traducción, síntexis de voz, o el ciclo completo.La forma de instanciarlos es independiente del espacio de nombres a usar, aunque cada uno de ellos recibe sus propios parámetros.

Ejemplo

Javascript
Python
Java

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

Espacios de nombres

A continuación se describen los espacios de nombres que soporta la api de Speaqr para su conexión por sockets.

Transcripción

Realiza la transcripción del audio que se le envía.

Url

https://public.speaqr.ai/stt

Parámetros

Traducción

Realiza la traducción del texto que se le envía de un idioma a otro.

Url

https://public.speaqr.ai/translator

Parámetros

Síntesis de voz

Genera un audio a partir del texto que se le envía.

Url

https://public.speaqr.ai/tts

Parámetros

Transcripción - traducción - síntexis

Realiza la transcripción del audio que se le envía, la traduce, y sintetiza un nuevo audio con la traducción obtenida.

Url

https://public.speaqr.ai/sts

Parámetros

Eventos recibidos

A continuación se describen los eventos especificos de los sockets de la api.

connected

Si se recibe este evento es que la conexión ha tenido éxito. Recibe un objeto con los parámetros que se han usado para la conexión.

Respuesta


						

start

Hasta que no se recibe este evento los sockets no estarán preparados para recibir texto o audio, por lo que antes de hacer un envío es importante esperar a recibir este evento. Se puede recibir una respuesta boleana, o si se invocó el recibir audio por streaming, la url para recoger dicho audio.

Ejemplo de "connected" y "start"

Javascript
Python
Java

								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

Los campos del objeto que se recibe dependerá del espacio de nombres que se usó. A continuación un objeto para el espacio de nombres sts que contiene todos los campos posibles.

Respuesta


						

error

Este evento recibe un objeto con distintas descripciones de errores que pudierán ocurrir, bien por fallos en programación de instanciar los modos de uso, como en los datos que se intentan procesar. Se listan los posibles errores de ejecución.

Errores

Eventos emitidos

A continuación se describen los envíos para el procesado de datos que soportan los sockets. Las funciones de emisión reciben un ack con el status del envío.

text

Envía un texto para ser procesado.

Ejemplo

Javascript
Python
Java

									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

Envía un fragmento de audio para ser procesado.

Ejemplo

En el siguiente ejemplo se captura el micrófono del dispositivo y se realiza la transcripción de la primera frase que se escuche.
Javascript
Python
Java

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

Esta página web usa cookies

Las cookies de este sitio web se usan para personalizar el contenido y analizar el tráfico.
Puedes encontrar los detalles de las mismas en la sección Politica de privacidad