Realtime API 是一个有状态的、基于事件的 API,通过 WebSocket 进行通信。您可以使用 Realtime API 调用边缘大模型网关平台预置的 Doubao-语音识别模型。
注意
Realtime API 仍处于测试阶段。
与 RealTime API 建立 WebSocket 连接以调用平台预置的 Doubao-语音识别模型,需要以下参数:
URL: wss://ai-gateway.vei.volces.com/v1/realtime
查询参数: ?model=bigmodel
请求头: Authorization: Bearer $YOUR_API_KEY
说明
$YOUR_API_KEY
必须替换成绑定了(平台预置模型)Doubao-语音识别 的网关访问密钥的 API key。详情请参见调用平台预置模型。
边缘大模型网关 Realtime API 兼容 OpenAI 的 Realtime 接口,并在其基础上扩充了一些事件。与 Doubao-语音识别模型相关的所有事件如下表所示。
事件类型 | 事件 | 说明 |
---|---|---|
客户端 | transcription_session.update | 客户端发送此事件以更新语音识别会话的默认配置。此事件必须且仅在连接初始化后发送。 |
input_audio_buffer.append | 客户端发送此事件以将音频数据上报服务端。 | |
input_audio_buffer.commit | 客户端发送此事件以通知服务端本次音频上报结束。 | |
服务端 | transcription_session.updated | 服务端已完成参数配置及连接建立。 |
conversation.item.input_audio_transcription.result | 服务端实时输出识别过程中的语音识别累计结果。 | |
conversation.item.input_audio_transcription.completed | 服务端输出该次音频的完整语音识别结果。 |
客户端与服务端基于 Realtime API 进行事件交互的过程如下图所示。
客户端发送此事件以更新语音识别会话的默认配置。此事件必须且仅在连接初始化后发送。
参数:
type
: string
事件类型,取值为 transcription_session.update
。
session
: object
包含以下字段:
input_audio_format
: stringinput_audio_codec
: stringinput_audio_sample_rate
: intinput_audio_channel
: intinput_audio_bits
: intinput_audio_transcription
: objectmodel
: stringmodel
一致。prompt
: stringlanguage
: string示例:
{ "type": "transcription_session.update", "session": { "input_audio_format": "pcm", "input_audio_codec": "raw", "input_audio_sample_rate": 16000, "input_audio_bits": 16, "input_audio_channel": 1, "input_audio_transcription": { "model": "bigmodel" } } }
客户端发送此事件以将待识别的音频数据上报到服务端。
参数:
event_id
: string
可选字段,由客户端生成的事件 ID。
type
: string
事件类型,取值为 input_audio_buffer.append
。
audio
: string
Base64 编码的 audio bytes。
示例:
{ "type": "input_audio_buffer.append", "event_id": "event_01", "audio": "base64_encoded_audio_data" }
客户端发送此事件以确认客户端更新的会话配置。
event_id
: string
可选字段,由客户端生成的事件 ID。
type
: string
事件类型,取值为 input_audio_buffer.commit
。
示例:
{ "type": "input_audio_buffer.commit" }
服务端发送此事件以更新语音识别会话的配置。此事件必须且仅在连接初始化后发送。
参数:
type
: string
事件类型,取值为 transcription_session.updated
。
session
: object
包含以下字段:
input_audio_format
: string
输入的音频格式。
input_audio_codec
: string
输入的音频容器格式。
input_audio_sample_rate
: int
输入的音频采样率。
input_audio_channel
: int
输入的音频声道数。
input_audio_bits
: int
输入的音频采样位宽。
input_audio_transcription
: object
语音识别的其他配置。
model
: string
使用的语音识别模型,与查询参数中的 model
一致。
prompt
: string
暂不支持。
language
: string
暂不支持。
示例:
{ "type": "transcription_session.updated", "session": { "input_audio_format": "pcm", "input_audio_codec": "raw", "input_audio_sample_rate": 16000, "input_audio_bits": 16, "input_audio_channel": 1, "input_audio_transcription": { "model": "bigmodel" } } }
包含截止当前时间点全量的语音识别结果,仅当使用的语音识别模型支持该输出方式时输出。
参数:
type
: string
事件类型,取值为 conversation.item.input_audio_transcription.result
。
event_id
: string
可选字段,由服务端生成的事件 ID。
item_id
: string
响应 item 的 ID。
transcript
: string
截至当前时间,全量的语音识别结果。
示例:
{ "type": "conversation.item.input_audio_transcription.result", "event_id": "event_001", "item_id": "item_001", "transcript": "Hello, how?" }
当客户端发送 input_audio_buffer.commit,且服务端完成所有语音识别之后返回,包含当次完整的最终识别结果。
参数:
type
: string
事件类型,取值为 conversation.item.input_audio_transcription.completed
。
event_id
: string
可选字段,由服务端生成的事件 ID。
item_id
: string
响应 item 的 ID。
transcript
: string
全量的最终语音识别结果。
words
: list of object
语音识别结果的分词信息。
word
: string
具体的分词结果。
start
: float
该词在音频中的起始时间。
end
: float
该词在音频中的结束时间。
示例:
{ "event_id": "event_2122", "type": "conversation.item.input_audio_transcription.completed", "item_id": "msg_003", "transcript": "Hello, how are you today?", "words": [ { "start": 0.28, "end": 0.36, "word": "Hello" }, { "start": 0.76, "end": 0.84, "word": "How" }, { "start": 0.84, "end": 0.92, "word": "are" }, { "start": 0.92, "end": 1, "word": "you" }, { "start": 1.22, "end": 1.3, "word": "today" }, ] }
import asyncio import base64 import json import numpy as np import soundfile as sf from scipy.signal import resample import websockets import logging logger = logging.getLogger('my_logger') def resample_audio(audio_data, original_sample_rate, target_sample_rate): number_of_samples = round(len(audio_data) * float(target_sample_rate) / original_sample_rate) resampled_audio = resample(audio_data, number_of_samples) return resampled_audio.astype(np.int16) async def send_audio(client, audio_file_path: str): sample_rate = 16000 duration_ms = 100 samples_per_chunk = sample_rate * (duration_ms / 1000) bytes_per_sample = 2 bytes_per_chunk = int(samples_per_chunk * bytes_per_sample) extra_params = ( { "samplerate": sample_rate, "channels": 1, "subtype": "PCM_16", } if audio_file_path.endswith(".raw") else {} ) audio_data, original_sample_rate = sf.read(audio_file_path, dtype="int16", **extra_params) if original_sample_rate != sample_rate: audio_data = resample_audio(audio_data, original_sample_rate, sample_rate) audio_bytes = audio_data.tobytes() for i in range(0, len(audio_bytes), bytes_per_chunk): await asyncio.sleep((duration_ms - 20) / 1000) chunk = audio_bytes[i: i + bytes_per_chunk] base64_audio = base64.b64encode(chunk).decode("utf-8") append_event = { "type": "input_audio_buffer.append", "audio": base64_audio } await client.send(json.dumps(append_event)) print("send complete") commit_event = { "type": "input_audio_buffer.commit" } await client.send(json.dumps(commit_event)) async def receive_messages(client, cancel=False): while not client.closed: message = await client.recv() print(message) event = json.loads(message) message_type = event.get("type") if message_type == 'conversation.item.input_audio_transcription.completed': break continue def get_session_update_msg(): config = { "input_audio_format": "pcm", "input_audio_codec": "raw", "input_audio_sample_rate": 16000, "input_audio_bits": 16, "input_audio_channel": 1, "input_audio_transcription": { "model": "bigmodel" }, } event = { "type": "transcription_session.update", "session": config } return json.dumps(event) async def with_openai(audio_file_path: str): key = "your_api_key" ws_url = "wss://ai-gateway.vei.volces.com/v1/realtime?model=bigmodel" headers = { "Authorization": f"Bearer {key}", } async with websockets.connect(ws_url, ping_interval=None, logger=logger, extra_headers=headers) as client: session_msg = get_session_update_msg() await client.send(session_msg) await asyncio.gather(send_audio(client, audio_file_path), receive_messages(client,False)) if __name__ == "__main__": file_path = "hello.wav" asyncio.run(with_openai(file_path))
创建一个 asr.py 文件,将 Python 示例代码粘贴进来。
下载以下依赖文件(requirements.txt)和音频样例文件(hello.wav)。
运行 pip install requirements.txt
安装依赖。
运行 python3 asr.py
。