Chuyển giọng nói thành văn bản theo thời gian thực
Liên tục gửi âm thanh PCM qua WebSocket Muse Voice Transcribe và nhận các sự kiện chuyển giọng nói thành văn bản theo thời gian thực.
Muse Voice Transcribe nhận âm thanh PCM thô qua kết nối WebSocket liên tục và trả về các sự kiện tiến độ, lượt nói và chuyển giọng nói thành văn bản. API này chỉ tạo văn bản, không tạo phản hồi giọng nói.
wss://api.agtcloud.cn/v1/asr/realtimeXác thực và kết nối
Sau khi thiết lập WebSocket, gửi khung văn bản JSON đầu tiên trong vòng 10 giây. Bearer API Key nằm trong authorization.accessToken, không nằm trong Header bắt tay WebSocket.
| Mục | Giá trị |
|---|---|
| Địa chỉ kết nối | wss://api.agtcloud.cn/v1/asr/realtime |
| Vị trí xác thực | authorization.accessToken trong khung văn bản JSON đầu tiên |
| Mô hình | muse-voice-transcribe-1.0 |
| Tham số truy vấn tùy chọn | sessionId, chỉ truyền nguyên trạng ID phiên, không có nghĩa là hỗ trợ khôi phục kết nối hoặc truy vấn phiên trước |
Khung đầu tiên không chứa type và có dung lượng tối đa 64 KiB. Chỉ bắt đầu gửi âm thanh sau khi nhận phản hồi thành công có sessionId; nâng cấp WebSocket thành công không có nghĩa là xác thực khung đầu tiên đã thành công.
Quy trình phiên
- Thiết lập kết nối WebSocket.
- Gửi khung đầu tiên chứa thông tin xác thực, mô hình và cấu hình âm thanh.
- Chờ máy chủ trả về
sessionId. - Gửi các khung PCM nhị phân thô theo tốc độ thời gian thực, đồng thời liên tục nhận sự kiện.
- Khi hết âm thanh, gửi
{"type":"endStream"}. - Tiếp tục nhận các kết quả chuyển giọng nói thành văn bản cuối cùng và thông báo đóng kết nối.
speechComplete chỉ biểu thị một lượt nói đã hoàn tất, không có nghĩa là toàn bộ phiên đã kết thúc. Sau khi gửi endStream, vẫn tiếp tục đọc sự kiện từ máy chủ cho đến khi kết nối đóng.
Tham số khung đầu tiên
| Trường | Kiểu | Mô tả |
|---|---|---|
authorization.accessToken | string | Bắt buộc, định dạng Bearer your-api-key |
model | string | Bắt buộc, sử dụng muse-voice-transcribe-1.0 |
audioEncoding | string | Bắt buộc, âm thanh thời gian thực sử dụng PCM_16KHZ hoặc PCM_24KHZ |
mode | string | Tùy chọn: PUSH_TO_TALK, ENDPOINTING, DIARIZATION |
partialMode | string | Tùy chọn: CUMULATIVE trả về văn bản tích lũy, DELTA trả về văn bản mới |
keywords | string[] | Tùy chọn, gợi ý thuật ngữ hoặc tên riêng |
languageBias | string[] | Tùy chọn, gợi ý ngôn ngữ dự kiến |
emitAudioProgress | boolean | Tùy chọn, có trả về sự kiện tiến độ xử lý âm thanh hay không |
zdrOverride | boolean | Tùy chọn xử lý dữ liệu; hiệu lực tùy thuộc vào dịch vụ hiện tại và quyền của tài khoản |
Âm thanh đầu vào
Âm thanh phải là PCM16 little-endian mono không chứa phần đầu tệp WAV, với tần số lấy mẫu 16 kHz hoặc 24 kHz khớp với cấu hình trong khung đầu tiên. Mỗi khung âm thanh không quá 1 MiB và số byte phải là số chẵn.
Nên gửi các khối âm thanh 100 ms theo tốc độ thời gian thực: 24 kHz tương ứng với 4800 byte, 16 kHz tương ứng với 3200 byte. Nếu cần duy trì dòng thời gian liên tục trong khoảng im lặng, vẫn gửi dữ liệu PCM im lặng có cùng định dạng.
# Tạo âm thanh PCM16 thô, mono, 24 kHz
ffmpeg -i input.mp3 -ac 1 -ar 24000 -c:a pcm_s16le -f s16le audio.pcmVí dụ Python
Cài đặt ứng dụng khách WebSocket, chuẩn bị audio.pcm, rồi chạy ví dụ. Việc gửi và nhận được thực hiện trên các luồng riêng để tránh tải lên âm thanh làm chặn xử lý sự kiện từ máy chủ.
python -m pip install websocket-clientimport 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("Số byte PCM phải là số chẵn")
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("Gửi dữ liệu bị gián đoạn:", 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("Khởi tạo kết nối thất bại: " + 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)Reference sự kiện
audioProcessedMs biểu thị tiến độ xử lý tích lũy; không cộng các giá trị từ nhiều sự kiện. Khi sử dụng CUMULATIVE, văn bản từng phần mới thay thế kết quả tích lũy trước đó; khi sử dụng DELTA, nối thêm văn bản theo từng phần tăng thêm.
audioProgress
Trả về tiến độ xử lý âm thanh tích lũy hiện tại.
| Trường | Kiểu | Bắt buộc | Mô tả | Ví dụ |
|---|---|---|---|---|
type | string | Có | Luôn là audioProgress. | audioProgress |
audioProcessedMs | integer | Có | Thời lượng âm thanh đã xử lý tích lũy, tính bằng mili giây. | 1600 |
{
"type": "audioProgress",
"audioProcessedMs": 1600
}speechComplete.transcript chứa văn bản đầy đủ của lượt nói hiện tại. Khi kết thúc phiên, sự kiện transcript có final: true có thể không chứa văn bản; ứng dụng khách không nên dùng chuỗi rỗng để ghi đè văn bản tích lũy đã lưu hoặc speechComplete.transcript.
Giới hạn phiên và xử lý lỗi
Phiên có thời lượng tối đa khoảng 60 phút. Không có tin nhắn từ ứng dụng khách trong 15 giây liên tiếp có thể kích hoạt kết thúc đầu vào; tình trạng mạng hoặc máy chủ cũng có thể khiến kết nối kết thúc sớm. Ứng dụng khách nên đặt giới hạn tổng thời lượng, thời gian chờ đọc và chiến lược thử lại có giới hạn.
| Mã đóng | Ý nghĩa | Cách xử lý đề xuất |
|---|---|---|
1008 | Lỗi chính sách hoặc giao thức | Kiểm tra cấu trúc khung đầu tiên, xác thực, tham số và các thông điệp điều khiển tiếp theo |
1011 | Máy chủ hoặc upstream bị gián đoạn | Lưu sessionId, sự kiện lỗi và lý do đóng rồi quyết định có thử lại hay không |
1013 | Dịch vụ tạm thời không khả dụng hoặc giới hạn tần suất | Thử lại có giới hạn với chiến lược backoff |
Tính phí
Chuyển giọng nói thành văn bản theo thời gian thực được tính phí theo thời lượng âm thanh đã xử lý; giá cụ thể theo danh mục mô hình trên trang web hiện tại. Giá trị mili giây trong sự kiện tiến độ thể hiện dòng thời gian xử lý, không được cộng từng sự kiện như các khoản phí độc lập.