Documentação para programadores

API pública.

Introdução

O Speaqr fornece serviços de tradução em tempo real através de uma API construída sobre o Socket.IO. Os clientes podem ligar-se, enviar dados de áudio e receber resultados processados, tais como transcrições, traduções e discurso sintetizado.A Speaqr foi concebida para conversações, em que a velocidade é crucial para proporcionar uma experiência de qualidade. Por este motivo, a API Speaqr segue a filosofia "session on socket".Uma vez autenticado, o consumidor mantém uma ligação aberta através de um socket até à desconexão, tratando a maioria das interações através de eventos, com algumas excepções.Para utilizar a API , é necessária uma chave de API válida. Para a obter, contacte-nos através do formulário de contratação.

Url

O url para aceder à API é: https://public.speaqr.ai

Postman

Pode descarregar a coleção Postman e o ambiente para testar os métodos da API.Lembre-se de colocar a sua chave de API válida no ambiente.Descarregar a coleçãoDescarregar o ambiente

Erros

Os erros são sempre devolvidos num JSON com os seguintes campos:
CampoExplicação
codeO código de erro geral.
errorO código de erro específico no âmbito do erro geral.
descriptionA descrição textual do erro.

Exemplo


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

Métodos

A API tem vários métodos disponíveis. As suas utilizações e configurações são descritas em seguida.

api/languages

Obtém a lista de idiomas suportados pelo SDK para transcrição, tradução e síntese de voz.

Endpoint

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

Cabeçalhos

Exemplo

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

Resposta


						

/api/voices

Obtém a lista de vozes disponíveis para a síntese de voz (TTS) numa língua. Opcionalmente, o resultado pode ser filtrado por género de voz, modo de resposta e/ou motor de voz.Desta forma, é possível descobrir se uma configuração de língua, género, modo de resposta e motor pode ser realizada, uma vez que não existem vozes para todas as combinações.

Endpoint

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

Cabeçalhos

Parâmetros

QUERY

Exemplo

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

Resposta


						

batch/file

Processa um ficheiro áudio e executa a operação especificada no modo. O resultado dependerá do modo selecionado.

Endpoint

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

Cabeçalhos

Parâmetros

FORM DATA

Exemplo

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

Resposta

A resposta JSON conterá apenas os campos do resultado especificado em mode. O campo file.data é um ArrayBuffer em formato mp3.

						

Erros

Ligação de tomada

Compatibilidade

Para utilizar a API, é necessário desenvolver numa linguagem compatível com um cliente socket.io: Javascript, Java, C++, Swift, Dart, Python, .Net, Rust, Kotlin, PHP. https://socket.io/docs/v4

Namespaces

As tomadas são organizadas por namespaces de acordo com a função a desempenhar, transcrição, tradução, síntese de fala ou o ciclo completo.A forma como são instanciados é independente do espaço de nomes a utilizar, embora cada um deles receba os seus próprios parâmetros.

Exemplo

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

Namespaces

Os espaços nominais suportados pela API Speaqr para a ligação de sockets são descritos a seguir.

Transcrição

Transcreve o áudio que lhe é enviado.

Url

https://public.speaqr.ai/stt

Parâmetros

Tradução

Traduz o texto que lhe é enviado de uma língua para outra.

Url

https://public.speaqr.ai/translator

Parâmetros

Síntese de voz

Gera áudio a partir do texto que lhe é enviado.

Url

https://public.speaqr.ai/tts

Parâmetros

Transcrição - tradução - syntexis

Transcreve o áudio que lhe é enviado, traduz-o e sintetiza um novo áudio com a tradução obtida.

Url

https://public.speaqr.ai/sts

Parâmetros

Eventos recebidos

A seguir descrevem-se os eventos específicos dos sockets api.

connected

Se este evento for recebido, a ligação foi bem sucedida. Recebe um objeto com os parâmetros que foram utilizados para a ligação.

Resposta


						

start

Até este evento ser recebido, os sockets não estarão prontos para receber texto ou áudio, por isso, antes de enviar, é importante esperar por este evento. Pode receber uma resposta booleana ou, se invocou o streaming de áudio, o url para captar o áudio.

Exemplo de "ligado" e "iniciar

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

Os campos do objeto que recebe dependerão do espaço de nomes utilizado. Abaixo está um objeto para o espaço de nomes sts que contém todos os campos possíveis.

Resposta


						

endSynth

Este evento é recebido pelos namespaces tts e sts. Ele é recebido quando a síntese de texto é concluída. Se receiveAudio.mode = 'block' ele é recebido imediatamente após o evento result. Se receiveAudio.mode = 'streaming' ele é recebido imediatamente após o último evento result.

Resposta


						

error

Este evento recebe um objeto com diferentes descrições de erros que podem ocorrer, quer devido a erros de programação na instanciação dos modos de utilização, quer nos dados que estão a tentar ser processados. São enumerados os possíveis erros de execução.

Erros

Transmissão de eventos

A seguir descrevem-se as transmissões para tratamento de dados suportadas pelas tomadas. As funções de envio recebem um ack com o estado do envio.

text

Envia um texto para ser processado.

Exemplo

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

Envia um fragmento de áudio para ser processado.

Exemplo

No exemplo seguinte, o microfone do dispositivo é captado e a primeira frase ouvida é transcrita.
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");
										}	
									}
								

Este sítio Web utiliza cookies

Os cookies neste sítio Web são utilizados para personalizar o conteúdo e analisar o tráfego.
Pode encontrar os detalhes destes cookies na secção Política de Privacidade.