Transmita audio a Qwen-ASR-Realtime mediante WebSocket y reciba resultados de transcripción en tiempo real a través del SDK de Python de DashScope.
Requisitos previos
Antes de comenzar, asegúrese de tener:
- SDK de DashScope 1.25.6 o posterior
- Una clave de API
- Comprensión del flujo de interacción
ImportanteAlibaba Cloud Model Studio ha lanzado dominios específicos de espacio de trabajo para las regiones de China (Beijing) y Singapur. Los nuevos dominios dedicados ofrecen un rendimiento superior y una mayor estabilidad para las solicitudes de inferencia. Recomendamos migrar a los nuevos dominios:
- China (Pekín): de
dashscope.aliyuncs.coma{WorkspaceId}.cn-beijing.maas.aliyuncs.com - Singapur: de
dashscope-intl.aliyuncs.coma{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com
Reemplace {WorkspaceId} con su ID de espacio de trabajo real. Los dominios existentes permanecen totalmente funcionales.
Ejemplo completo
NotaEl código de ejemplo lee your_audio_file.pcm (PCM16, 16 kHz, mono). Si solo tiene un MP3, WAV o un formato similar, conviértalo con ffmpeg:
ffmpeg -i your_audio.mp3 -ar 16000 -ac 1 -f s16le your_audio_file.pcm
import logging
import os
import base64
import signal
import sys
import time
import dashscope
from dashscope.audio.qwen_omni import *
from dashscope.audio.qwen_omni.omni_realtime import TranscriptionParams
def setup_logging():
"""Configure log output"""
logger = logging.getLogger('dashscope')
logger.setLevel(logging.DEBUG)
handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.propagate = False
return logger
def init_api_key():
"""Initialize the API Key"""
# The API Key differs between the Singapore and Beijing regions. Get your API Key: https://www.alibabacloud.com/help/model-studio/get-api-key
# If you have not configured the environment variable, replace the following line with your Alibaba Cloud Model Studio API Key: dashscope.api_key = "sk-xxx"
dashscope.api_key = os.environ.get('DASHSCOPE_API_KEY', 'YOUR_API_KEY')
if dashscope.api_key == 'YOUR_API_KEY':
print('[Warning] Using placeholder API key, set DASHSCOPE_API_KEY environment variable.')
class MyCallback(OmniRealtimeCallback):
"""Real-time recognition callback handler"""
def __init__(self, conversation):
self.conversation = conversation
self.handlers = {
'session.created': self._handle_session_created,
'conversation.item.input_audio_transcription.completed': self._handle_final_text,
'conversation.item.input_audio_transcription.text': self._handle_transcription_text,
'input_audio_buffer.speech_started': lambda r: print('======Speech Start======'),
'input_audio_buffer.speech_stopped': lambda r: print('======Speech Stop======')
}
def on_open(self):
print('Connection opened')
def on_close(self, code, msg):
print(f'Connection closed, code: {code}, msg: {msg}')
def on_event(self, response):
try:
handler = self.handlers.get(response['type'])
if handler:
handler(response)
except Exception as e:
print(f'[Error] {e}')
def _handle_session_created(self, response):
print(f"Start session: {response['session']['id']}")
def _handle_final_text(self, response):
print(f"Final recognized text: {response['transcript']}")
def _handle_transcription_text(self, response):
print(f"Got transcription result: {response['text'] + response['stash']}")
def read_audio_chunks(file_path, chunk_size=3200):
"""Read the audio file in chunks"""
with open(file_path, 'rb') as f:
while chunk := f.read(chunk_size):
yield chunk
def send_audio(conversation, file_path, delay=0.1):
"""Send audio data"""
if not os.path.exists(file_path):
raise FileNotFoundError(f"Audio file {file_path} does not exist.")
print("Processing audio file... Press 'Ctrl+C' to stop.")
for chunk in read_audio_chunks(file_path):
audio_b64 = base64.b64encode(chunk).decode('ascii')
conversation.append_audio(audio_b64)
time.sleep(delay)
def main():
setup_logging()
init_api_key()
audio_file_path = "./your_audio_file.pcm"
callback = MyCallback(conversation=None)
conversation = OmniRealtimeConversation(
model='qwen3-asr-flash-realtime',
# The following is the configuration for the Singapore region. When calling, replace "{WorkspaceId}" with your actual workspace ID. Configurations differ by region.
url='wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/realtime',
callback=callback,
)
callback.conversation = conversation # Inject conversation into the callback so its methods can be called within the callback
def handle_exit(sig, frame):
print('Ctrl+C pressed, exiting...')
conversation.close()
sys.exit(0)
signal.signal(signal.SIGINT, handle_exit)
conversation.connect()
transcription_params = TranscriptionParams(
language='zh',
sample_rate=16000,
input_audio_format="pcm"
)
conversation.update_session(
output_modalities=[MultiModality.TEXT],
enable_input_audio_transcription=True,
transcription_params=transcription_params
)
try:
send_audio(conversation, audio_file_path)
# send session.finish and wait for finished and close
conversation.end_session()
except Exception as e:
print(f"Error occurred: {e}")
finally:
conversation.close()
print("Audio processing completed.")
if __name__ == '__main__':
main()
Parámetros de solicitud
Constructor OmniRealtimeConversation
Cree una instancia de OmniRealtimeConversation con los siguientes parámetros.
Haga clic para ver código de ejemplo
from dashscope.audio.qwen_omni import OmniRealtimeConversation, OmniRealtimeCallback
class MyCallback(OmniRealtimeCallback):
"""Callback for real-time recognition"""
def __init__(self, conversation):
self.conversation = conversation
self.handlers = {
'session.created': self._handle_session_created,
'conversation.item.input_audio_transcription.completed': self._handle_final_text,
'conversation.item.input_audio_transcription.text': self._handle_stash_text,
'input_audio_buffer.speech_started': lambda r: print('======Speech Start======'),
'input_audio_buffer.speech_stopped': lambda r: print('======Speech Stop======')
}
def on_open(self):
print('Connection opened')
def on_close(self, code, msg):
print(f'Connection closed, code: {code}, msg: {msg}')
def on_event(self, response):
try:
handler = self.handlers.get(response['type'])
if handler:
handler(response)
except Exception as e:
print(f'[Error] {e}')
def _handle_session_created(self, response):
print(f"Start session: {response['session']['id']}")
def _handle_final_text(self, response):
print(f"Final recognized text: {response['transcript']}")
def _handle_stash_text(self, response):
print(f"Got stash result: {response['stash']}")
conversation = OmniRealtimeConversation(
model='qwen3-asr-flash-realtime',
# The following URL is for the Chinese mainland. For regions outside
# the Chinese mainland, use
# wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/realtime instead.
url='wss://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api-ws/v1/realtime',
callback=MyCallback(conversation=None) # Temporarily pass None and inject it later.
)
# Inject self into the callback.
conversation.callback.conversation = conversation
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
model | str | Sí | Modelo a utilizar. |
callback | OmniRealtimeCallback | Sí | Objeto de callback que maneja los eventos del lado del servidor. |
url | str | Sí | Endpoint WebSocket. China (Beijing): wss://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api-ws/v1/realtime Singapur: wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/realtime. Reemplace {WorkspaceId} con su ID de espacio de trabajo real. |
Configuración de sesión
Después de conectarse, llame a update_session para configurar los parámetros de la sesión.
Haga clic para ver código de ejemplo
from dashscope.audio.qwen_omni import TranscriptionParams, MultiModality
transcription_params = TranscriptionParams(
language='zh',
sample_rate=16000,
input_audio_format="pcm"
)
conversation.update_session(
output_modalities=[MultiModality.TEXT],
enable_turn_detection=True,
turn_detection_type="server_vad",
turn_detection_threshold=0.0,
turn_detection_silence_duration_ms=400,
enable_input_audio_transcription=True,
transcription_params=transcription_params
)
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
output_modalities | List[MultiModality] | Sí | Modalidad de salida. Fija en [MultiModality.TEXT]. |
enable_turn_detection | bool | No | Habilita la Detección de Actividad de Voz (VAD) del lado del servidor. Predeterminado: True. Cuando es False, llame a commit() manualmente para activar el reconocimiento. |
turn_detection_type | str | No | Tipo de VAD del lado del servidor. Fijo en server_vad. |
turn_detection_threshold | float | No | Umbral de sensibilidad de VAD. Predeterminado: 0.2. Recomendado: 0.0. Rango válido: [-1, 1]. Valores más bajos = mayor sensibilidad (puede activarse con ruido de fondo). Valores más altos = menos activaciones false en entornos ruidosos. |
turn_detection_silence_duration_ms | int | No | Duración del silencio (ms) que marca el final de una declaración. Predeterminado: 800. Recomendado: 400. Rango válido: [200, 6000]. Valores más bajos (por ejemplo, 300 ms) = respuesta más rápida pero puede dividir pausas naturales. Valores más altos (por ejemplo, 1200 ms) = mejor manejo de pausas en oraciones largas pero mayor latencia. |
transcription_params | TranscriptionParams | No | Configuraciones de reconocimiento de voz. Consulte TranscriptionParams. |
TranscriptionParams
Configure los ajustes de reconocimiento de voz con el constructor TranscriptionParams.
Haga clic para ver código de ejemplo
transcription_params = TranscriptionParams(
language='zh',
sample_rate=16000,
input_audio_format="pcm"
)
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
language | str | No | Idioma de origen del audio. Valores admitidos: zh (chino: mandarín, sichuanés, minnan, wu), yue (cantonés), en (inglés), ja (japonés), ko (coreano), de (alemán), fr (francés), es (español), pt (portugués), it (italiano), ru (ruso), ar (árabe), hi (hindi), id (indonesio), th (tailandés), tr (turco), uk (ucraniano), vi (vietnamita), cs (checo), da (danés), fi (finlandés), fil (filipino), is (islandés), ms (malayo), no (noruego), pl (polaco), sv (sueco) |
sample_rate | int | No | Tasa de muestreo de audio en Hz. Predeterminado: 16000. Admitidos: 16000, 8000. Con 8000, el servidor realiza un sobremuestreo a 16,000 Hz antes del reconocimiento, lo que puede añadir una ligera latencia. Utilice 8000 solo para audio fuente de 8 kHz, como grabaciones telefónicas. |
input_audio_format | str | No | Formato de audio. Predeterminado: pcm. Admitidos: pcm, opus. |
corpus_text | str | No | Texto de fondo, vocabularios de entidades u otra información de referencia para el sesgo contextual. Máx.: 10,000 tokens. Para más detalles, consulte Sesgo contextual. |
Interfaces clave
Clase OmniRealtimeConversation
from dashscope.audio.qwen_omni import OmniRealtimeConversation
| Método | Evento de respuesta del servidor | Descripción |
|---|---|---|
connect() | session.created, session.updated | Abre una conexión WebSocket con el servidor. |
update_session(...) | session.updated | Configura la sesión. Llame después de connect(). Si se omite, se aplican los valores predeterminados. Consulte Configuración de la sesión para ver los parámetros. |
append_audio(audio_b64: str) | None | Envía un fragmento de audio codificado en Base64 al búfer de entrada del servidor. Con enable_turn_detection=True, el servidor detecta los límites del habla y confirma automáticamente. Con enable_turn_detection=False, el cliente controla el momento de confirmación (máx. 15 MiB por evento). Los fragmentos más pequeños mejoran la capacidad de respuesta de la VAD. |
commit() | input_audio_buffer.committed | Confirma el audio almacenado en el búfer para su reconocimiento. Devuelve un error si el búfer está vacío. Deshabilitado cuando enable_turn_detection=True. |
end_session(timeout: int = 20) | session.finished | Finaliza la sesión después de que el servidor completa el reconocimiento final. En el modo VAD (predeterminado), llame después de enviar todo el audio. En el modo Manual, llame después de commit(). Variante asíncrona: end_session_async(). |
close() | None | Finaliza la tarea y cierra la conexión. |
get_session_id() | None | Devuelve el ID de sesión actual. |
get_last_response_id() | None | Devuelve el ID de respuesta más reciente. |
Interfaz OmniRealtimeCallback
Subclasifique OmniRealtimeCallback e implemente sus métodos para manejar los eventos del servidor.
from dashscope.audio.qwen_omni import OmniRealtimeCallback
| Método | Parámetros | Descripción |
|---|---|---|
on_open() | None | Se llama cuando se establece la conexión WebSocket. |
on_event(message: dict) | message: un evento del servidor | Se llama cuando se recibe un evento del servidor. |
on_close(close_status_code, close_msg) | close_status_code: código de estado; close_msg: mensaje de registro | Se llama cuando se cierra la conexión WebSocket. |