Azure AI 语音实时翻译 (VoiceLive TS)
@azure/ai-voicelive (JavaScript/TypeScript)
用于在 Node.js 和浏览器环境中构建基于 Azure AI 的双向语音助手的实时语音 AI SDK。
安装
npm install @azure/ai-voicelive @azure/identity
TypeScript 用户
npm install @types/node当前版本: 1.0.0-beta.3
支持的环境:
- Node.js LTS 版本 (20+)
- 现代浏览器 (Chrome, Firefox, Safari, Edge)
环境变量
AZURE_VOICELIVE_ENDPOINT=https://<resource>.cognitiveservices.azure.com
可选:如果不使用 Entra ID,请提供 API 密钥
AZURE_VOICELIVE_API_KEY=<your-api-key>
可选:日志级别
AZURE_LOG_LEVEL=info身份验证
Microsoft Entra ID (推荐)
import { DefaultAzureCredential } from "@azure/identity";
import { VoiceLiveClient } from "@azure/ai-voicelive";
const credential = new DefaultAzureCredential();
const endpoint = "https://your-resource.cognitiveservices.azure.com";
const client = new VoiceLiveClient(endpoint, credential);
API 密钥
import { AzureKeyCredential } from "@azure/core-auth";
import { VoiceLiveClient } from "@azure/ai-voicelive";
const endpoint = "https://your-resource.cognitiveservices.azure.com";
const credential = new AzureKeyCredential("your-api-key");
const client = new VoiceLiveClient(endpoint, credential);
客户端层级结构
VoiceLiveClient
└── VoiceLiveSession (WebSocket 连接)
├── updateSession() → 配置会话选项
├── subscribe() → 事件处理器 (Azure SDK 模式)
├── sendAudio() → 流式传输音频输入
├── addConversationItem() → 添加消息/函数输出
└── sendEvent() → 发送原始协议事件快速上手
import { DefaultAzureCredential } from "@azure/identity";
import { VoiceLiveClient } from "@azure/ai-voicelive";
const credential = new DefaultAzureCredential();
const endpoint = process.env.AZURE_VOICELIVE_ENDPOINT!;
// 创建客户端并启动会话
const client = new VoiceLiveClient(endpoint, credential);
const session = await client.startSession("gpt-4o-mini-realtime-preview");
// 配置会话
await session.updateSession({
modalities: ["text", "audio"],
instructions: "你是一个得力的 AI 助手。请自然地回答。",
voice: {
type: "azure-standard",
name: "en-US-AvaNeural",
},
turnDetection: {
type: "server_vad",
threshold: 0.5,
prefixPaddingMs: 300,
silenceDurationMs: 500,
},
inputAudioFormat: "pcm16",
outputAudioFormat: "pcm16",
});
// 订阅事件
const subscription = session.subscribe({
onResponseAudioDelta: async (event, context) => {
// 处理流式音频输出
const audioData = event.delta;
playAudioChunk(audioData);
},
onResponseTextDelta: async (event, context) => {
// 处理流式文本
process.stdout.write(event.delta);
},
onInputAudioTranscriptionCompleted: async (event, context) => {
console.log("用户说道:", event.transcript);
},
});
// 从麦克风发送音频
function sendAudioChunk(audioBuffer: ArrayBuffer) {
session.sendAudio(audioBuffer);
}
会话配置
await session.updateSession({
// 模态 (Modalities)## 事件处理 (Azure SDK 模式)
SDK 采用了基于订阅的事件处理模式:
const subscription = session.subscribe({
// 连接生命周期
onConnected: async (args, context) => {
console.log("已连接:", args.connectionId);
},
onDisconnected: async (args, context) => {
console.log("已断开:", args.code, args.reason);
},
onError: async (args, context) => {
console.error("错误:", args.error.message);
},
// 会话事件
onSessionCreated: async (event, context) => {
console.log("会话已创建:", context.sessionId);
},
onSessionUpdated: async (event, context) => {
console.log("会话已更新");
},
// 音频输入事件 (VAD)
onInputAudioBufferSpeechStarted: async (event, context) => {
console.log("语音开始于:", event.audioStartMs);
},
onInputAudioBufferSpeechStopped: async (event, context) => {
console.log("语音结束于:", event.audioEndMs);
},
// 转录事件
onConversationItemInputAudioTranscriptionCompleted: async (event, context) => {
console.log("用户说:", event.transcript);
},
onConversationItemInputAudioTranscriptionDelta: async (event, context) => {
process.stdout.write(event.delta);
},
// 响应事件
onResponseCreated: async (event, context) => {
console.log("响应已开始");
},
onResponseDone: async (event, context) => {
console.log("响应已完成");
},
// 文本流
onResponseTextDelta: async (event, context) => {
process.stdout.write(event.delta);
},
onResponseTextDone: async (event, context) => {
console.log("\n--- 文本完成 ---");
},
// 音频流
onResponseAudioDelta: async (event, context) => {
const audioData = event.delta;
playAudioChunk(audioData);
},
onResponseAudioDone: async (event, context) => {
console.log("音频完成");
},
// 音频转录 (助手所说内容)
onResponseAudioTranscriptDelta: async (event, context) => {
process.stdout.write(event.delta);
},
// 函数调用
onResponseFunctionCallArgumentsDone: async (event, context) => {
if (event.name === "get_weather") {
const args = JSON.parse(event.arguments);
const result = await getWeather(args.location);
await session.addConversationItem({
type: "function_call_output",
callId: event.callId,
output: JSON.stringify(result),
});
await session.sendEvent({ type: "response.create" });
}
},
// 调试通用捕获
onServerEvent: async (event, context) => {
conso
le.log("Event:", event.type);
},
});
// 完成后清理
await subscription.close();
## 函数调用 (Function Calling)// 在会话配置中定义工具
await session.updateSession({
modalities: ["audio", "text"],
instructions: "帮助用户获取天气信息。",
tools: [
{
type: "function",
name: "get_weather",
description: "获取指定地点的当前天气",
parameters: {
type: "object",
properties: {
location: {
type: "string",
description: "城市及州或国家",
},
},
required: ["location"],
},
},
],
toolChoice: "auto",
});
// 处理函数调用
const subscription = session.subscribe({
onResponseFunctionCallArgumentsDone: async (event, context) => {
if (event.name === "get_weather") {
const args = JSON.parse(event.arguments);
const weatherData = await fetchWeather(args.location);
// 发送函数执行结果
await session.addConversationItem({
type: "function_call_output",
callId: event.callId,
output: JSON.stringify(weatherData),
});
// 触发响应生成
await session.sendEvent({ type: "response.create" });
}
},
});
## 语音选项
| 语音类型 | 配置 | 示例 |
|------------|--------|---------|
| Azure Standard | { type: "azure-standard", name: "..." } | "en-US-AvaNeural" |
| Azure Custom | { type: "azure-custom", name: "...", endpointId: "..." } | 自定义语音端点 |
| Azure Personal | { type: "azure-personal", speakerProfileId: "..." } | 个人语音克隆 |
| OpenAI | { type: "openai", name: "..." } | "alloy", "echo", "shimmer" |
支持的模型
| 模型 | 描述 | 使用场景 |
|-------|-------------|----------|
| gpt-4o-realtime-preview | 支持实时音频的 GPT-4o | 高质量对话式 AI |
| gpt-4o-mini-realtime-preview | 轻量级 GPT-4o | 快速、高效的交互 |
| phi4-mm-realtime | Phi 多模态 | 高性价比应用 |
话轮检测 (Turn Detection) 选项
// Azure 语义 VAD (更智能的检测)
turnDetection: {
type: "azure_semantic_vad",
}
// Azure 语义 VAD (英语优化)
turnDetection: {
type: "azure_semantic_vad_en",
}
// Azure 语义 VAD (多语言)
turnDetection: {
type: "azure_semantic_vad_multilingual",
}
## 音频格式
| 格式 | 采样率 | 使用场景 |
|--------|-------------|----------|
| pcm16 | 24kHz | 默认,高质量 |
| pcm16-8000hz | 8kHz | 电话通信 |
| pcm16-16000hz | 16kHz | 语音助手 |
| g711_ulaw | 8kHz | 电话通信 (美国) |
| g711_alaw | 8kHz | 电话通信 (欧洲) |
关键类型参考
| 类型 | 用途 |
|------|---------|
| VoiceLiveClient | 用于创建会话的主客户端 |
| VoiceLiveSession | 活跃的 WebSocket 会话 |
| VoiceLiveSessionHandlers | 事件处理接口 |
| VoiceLiveSubscription | 活跃的事件订阅 |
| ConnectionContext | 连接事件的上下文 |
| SessionContext | 会话事件的上下文 |
| ServerEventUnion | 所有服务器事件的联合类型 |
错误处理
const subscription = session.
subscribe({
onError: async (args, context) => {
const { error } = args;
if (error instanceof VoiceLiveConnectionError) {
console.error("连接错误:", error.message);
} else if (error instanceof VoiceLiveAuthenticationError) {
console.error("认证错误:", error.message);
} else if (error instanceof VoiceLiveProtocolError) {
console.error("协议错误:", error.message);
}
},
onServerError: async (event, context) => {
console.error("服务器错误:", event.error?.message);
},
});
## 日志记录import { setLogLevel } from "@azure/logger";
// 启用详细日志
setLogLevel("info");
// 或通过环境变量设置
// AZURE_LOG_LEVEL=info
## 浏览器使用// 浏览器环境需要打包工具 (Vite, webpack 等)
import { VoiceLiveClient } from "@azure/ai-voicelive";
import { InteractiveBrowserCredential } from "@azure/identity";
// 使用兼容浏览器的凭据
const credential = new InteractiveBrowserCredential({
clientId: "your-client-id",
tenantId: "your-tenant-id",
});
const client = new VoiceLiveClient(endpoint, credential);
// 请求麦克风权限
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const audioContext = new AudioContext({ sampleRate: 24000 });
// 处理音频并发送至会话
// ... (完整实现请参考示例)
``
最佳实践
1. 始终使用 DefaultAzureCredential —— 切勿在代码中硬编码 API 密钥。
2. 设置两种模态 —— 为语音助手包含 ["text", "audio"]。subscription.close()`。
3. 使用 Azure Semantic VAD —— 比基础服务器 VAD 具有更好的话轮检测能力。
4. 处理所有错误类型 —— 包括连接、认证和协议错误。
5. 清理订阅 —— 完成后调用
6. 使用合适的音频格式 —— 推荐使用 24kHz 的 PCM16 以获得最佳质量。
参考链接
| 资源 | URL |
|----------|-----|
| npm 包 | https://www.npmjs.com/package/@azure/ai-voicelive |
| GitHub 源码 | https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/ai/ai-voicelive |
| 示例代码 | https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/ai/ai-voicelive/samples |
| API 参考 | https://learn.microsoft.com/javascript/api/@azure/ai-voicelive |
适用场景
此技能适用于执行概览中所描述的工作流或操作。局限性
- 仅在任务与上述范围明确匹配时使用此技能。
- 不要将输出结果视为针对特定环境的验证、测试或专家评审的替代方案。
- 如果缺少必要的输入、权限、安全边界或成功标准,请停止并请求进一步说明。