AGTCloud API Docs
GuidesRéférence APIIntégrations et ressourcesMises à jour et aide
Traitement audioMuse Voice Transcribe

Transcription en temps réel

Envoyez du PCM en continu via le WebSocket Muse Voice Transcribe et recevez les événements de transcription en temps réel.

Muse Voice Transcribe reçoit de l’audio PCM brut via un WebSocket persistant et renvoie en continu des événements de progression, de tours de parole et de transcription. Cette interface produit uniquement du texte, pas de réponse vocale.

WSS
wss://api.agtcloud.cn/v1/asr/realtime

Authentification et connexion

Après l’établissement du WebSocket, envoyez la première trame texte JSON dans les 10 secondes. La clé API Bearer se trouve dans authorization.accessToken, et non dans un Header de la négociation WebSocket.

ÉlémentValeur
URL de connexionwss://api.agtcloud.cn/v1/asr/realtime
Emplacement de l’authentificationauthorization.accessToken dans la première trame texte JSON
Modèlemuse-voice-transcribe-1.0
Paramètre de requête facultatifsessionId, transmis uniquement comme identifiant de session ; il n’implique pas la prise en charge de la reprise après déconnexion ou de la consultation de sessions historiques

La première trame ne contient pas de type et ne doit pas dépasser 64 KiB. Attendez une réponse de réussite contenant sessionId avant d’envoyer l’audio ; la réussite de la mise à niveau WebSocket ne signifie pas que l’authentification de la première trame a réussi.

Déroulement de la session

  1. Établissez la connexion WebSocket.
  2. Envoyez la première trame contenant l’authentification, le modèle et la configuration audio.
  3. Attendez que le serveur renvoie sessionId.
  4. Envoyez les trames binaires PCM brutes à la vitesse du temps réel tout en continuant à recevoir les événements.
  5. À la fin de l’audio, envoyez {"type":"endStream"}.
  6. Continuez à recevoir la transcription finale et les messages de fermeture.

speechComplete indique uniquement la fin d’un tour de parole, pas celle de toute la session. Après l’envoi de endStream, continuez à lire les événements du serveur jusqu’à la fermeture de la connexion.

Paramètres de la première trame

ChampTypeDescription
authorization.accessTokenstringObligatoire, au format Bearer your-api-key
modelstringObligatoire, utilisez muse-voice-transcribe-1.0
audioEncodingstringObligatoire, utilisez PCM_16KHZ ou PCM_24KHZ pour l’audio en temps réel
modestringFacultatif : PUSH_TO_TALK, ENDPOINTING, DIARIZATION
partialModestringFacultatif : CUMULATIVE renvoie le texte cumulé ; DELTA renvoie le nouveau texte
keywordsstring[]Facultatif, indique des termes ou des noms propres
languageBiasstring[]Facultatif, indique la langue attendue
emitAudioProgressbooleanFacultatif, indique s’il faut renvoyer les événements de progression du traitement audio
zdrOverridebooleanOption de traitement des données facultative ; son effet dépend du service actuel et des autorisations du compte

Entrée audio

L’audio doit être du PCM16 little-endian mono sans en-tête de fichier WAV, avec la même fréquence d’échantillonnage de 16 kHz ou 24 kHz que celle déclarée dans la première trame. Chaque trame audio ne doit pas dépasser 1 MiB, et son nombre d’octets doit être pair.

Il est recommandé d’envoyer des blocs audio de 100 ms à la vitesse du temps réel : 4800 octets à 24 kHz, ou 3200 octets à 16 kHz. Pour maintenir une chronologie continue pendant les silences, envoyez aussi des données PCM silencieuses au même format.

# Générer de l’audio PCM16 brut mono à 24 kHz
ffmpeg -i input.mp3 -ac 1 -ar 24000 -c:a pcm_s16le -f s16le audio.pcm

Exemple Python

Installez le client WebSocket et préparez audio.pcm avant d’exécuter l’exemple. L’envoi et la réception utilisent des threads distincts pour éviter que le téléversement audio ne bloque le traitement des événements du serveur.

python -m pip install websocket-client
WSSConnexion de transcription Muse en temps réel
import json
import sys
import threading
import websocket

url = "wss://api.agtcloud.cn/v1/asr/realtime"
stop = threading.Event()
sender = None
ws = websocket.create_connection(url, timeout=40, enable_multithread=True)

def send_audio():
    try:
        with open(sys.argv[1], "rb") as audio:
            while not stop.is_set():
                chunk = audio.read(4800)
                if not chunk:
                    break
                if len(chunk) % 2:
                    raise ValueError("Le nombre d’octets PCM doit être pair")
                ws.send_binary(chunk)
                if stop.wait(len(chunk) / 48000):
                    return
        if not stop.is_set():
            silence = bytes(4800)
            for _ in range(10):
                ws.send_binary(silence)
                if stop.wait(0.1):
                    return
            ws.send(json.dumps({"type": "endStream"}))
    except Exception as exc:
        print("Envoi interrompu :", exc)
        stop.set()
        ws.close()

try:
    ws.send(json.dumps({
        "authorization": {"accessToken": "Bearer your-api-key"},
        "model": "muse-voice-transcribe-1.0",
        "audioEncoding": "PCM_24KHZ",
        "mode": "ENDPOINTING",
        "partialMode": "CUMULATIVE",
        "languageBias": ["Mandarin Chinese"],
        "emitAudioProgress": True
    }))
    ack = json.loads(ws.recv())
    if ack.get("type") == "error" or not ack.get("sessionId"):
        raise RuntimeError("Échec de l’initialisation de la connexion : " + json.dumps(ack, ensure_ascii=False))
    print("sessionId:", ack["sessionId"])
    sender = threading.Thread(target=send_audio, daemon=True)
    sender.start()
    while not stop.is_set():
        message = ws.recv()
        if not message:
            break
        event = json.loads(message)
        print(json.dumps(event, ensure_ascii=False))
        if event.get("type") == "error":
            break
finally:
    stop.set()
    ws.close()
    if sender is not None:
        sender.join(timeout=2)

Référence des événements

audioProcessedMs représente la progression cumulée du traitement ; n’additionnez pas les valeurs de plusieurs événements. Avec CUMULATIVE, le nouveau texte partiel remplace le résultat cumulé précédent ; avec DELTA, ajoutez le texte de manière incrémentale.

Événements du serveur · Progression

audioProgress

Renvoie la progression cumulée actuelle du traitement audio.

ChampTypeObligatoireDescriptionExemple
typestringOuiToujours `audioProgress`.audioProgress
audioProcessedMsintegerOuiDurée cumulée de l’audio traité, en millisecondes.1600
Exemple JSON
{
  "type": "audioProgress",
  "audioProcessedMs": 1600
}

speechComplete.transcript contient la transcription complète du tour de parole actuel. Lors de la clôture de la session, un événement transcript avec final: true peut ne pas contenir de texte ; le client ne doit pas remplacer le texte cumulé déjà enregistré ou speechComplete.transcript par une chaîne vide.

Limites de session et gestion des erreurs

Une session dure environ 60 minutes au maximum. Une absence de messages du client pendant 15 secondes peut déclencher la clôture de l’entrée ; le réseau ou l’état du serveur peuvent aussi fermer la connexion plus tôt. Le client doit prévoir une durée totale maximale, un délai de lecture et un nombre limité de tentatives.

Code de fermetureSignificationTraitement recommandé
1008Erreur de politique ou de protocoleVérifiez la structure de la première trame, l’authentification, les paramètres et les messages de contrôle suivants
1011Interruption du serveur ou du service en amontEnregistrez sessionId, l’événement d’erreur et le motif de fermeture avant de décider de réessayer
1013Service temporairement indisponible ou limitation de débitEffectuez un nombre limité de tentatives avec une stratégie de backoff

Facturation

La transcription en temps réel est facturée selon la durée de l’audio traité. Consultez les tarifs actuels dans le catalogue des modèles du site. Les valeurs en millisecondes des événements de progression représentent la chronologie du traitement ; ne les additionnez pas comme des éléments de facturation indépendants.

Références