Azure AI 语音实时翻译 Java 版

azure-ai-voicelive-java
分类通用
作者Agentic Awesome Skills 社区
许可MIT
评分4.20/5
使用3.5K

Azure AI VoiceLive Java SDK

利用 WebSocket 技术与 AI 助手进行实时、双向的语音对话。

安装

xml
<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-ai-voicelive</artifactId>
    <version>1.0.0-beta.2</version>
</dependency>

环境变量

bash
AZURE_VOICELIVE_ENDPOINT=https://<resource>.openai.azure.com/
AZURE_VOICELIVE_API_KEY=<your-api-key>

身份验证

API 密钥

java
import com.azure.ai.voicelive.VoiceLiveAsyncClient;
import com.azure.ai.voicelive.VoiceLiveClientBuilder;
import com.azure.core.credential.AzureKeyCredential;

VoiceLiveAsyncClient client = new VoiceLiveClientBuilder()
.endpoint(System.getenv("AZURE_VOICELIVE_ENDPOINT"))
.credential(new AzureKeyCredential(System.getenv("AZURE_VOICELIVE_API_KEY")))
.buildAsyncClient();

DefaultAzureCredential (推荐)

java
import com.azure.identity.DefaultAzureCredentialBuilder;

VoiceLiveAsyncClient client = new VoiceLiveClientBuilder()
.endpoint(System.getenv("AZURE_VOICELIVE_ENDPOINT"))
.credential(new DefaultAzureCredentialBuilder().build())
.buildAsyncClient();

核心概念

| 概念 | 描述 |
|---------|-------------|
| VoiceLiveAsyncClient | 语音会话的主入口点 |
| VoiceLiveSessionAsyncClient | 用于流式传输的活动 WebSocket 连接 |
| VoiceLiveSessionOptions | 会话行为的配置选项 |

音频要求

  • 采样率: 24kHz (24000 Hz)
  • 位深: 16-bit PCM
  • 声道: 单声道 (1 channel)
  • 格式: 有符号 PCM,小端序 (little-endian)

核心工作流

1. 启动会话

java
import reactor.core.publisher.Mono;

client.startSession("gpt-4o-realtime-preview")
.flatMap(session -> {
System.out.println("Session started");

// 订阅事件
session.receiveEvents()
.subscribe(
event -> System.out.println("Event: " + event.getType()),
error -> System.err.println("Error: " + error.getMessage())
);

return Mono.just(session);
})
.block();

2. 配置会话选项

java
import com.azure.ai.voicelive.models.*;
import java.util.Arrays;

ServerVadTurnDetection turnDetection = new ServerVadTurnDetection()
.setThreshold(0.5) // 灵敏度 (0.0-1.0)
.setPrefixPaddingMs(300) // 语音前的音频缓冲时间
.setSilenceDurationMs(500) // 结束轮次的静音时长
.setInterruptResponse(true) // 允许打断
.setAutoTruncate(true)
.setCreateResponse(true);

AudioInputTranscriptionOptions transcription = new AudioInputTranscriptionOptions(
AudioInputTranscriptionOptionsModel.WHISPER_1);

VoiceLiveSessionOptions options = new VoiceLiveSessionOptions()
.setInstructions("You are a helpful AI voice assistant.")
.setVoice(BinaryData.fromObject(new OpenAIVoice(OpenAIVoiceName.ALLOY)))
.setModalities(Arrays.asList(InteractionModality.TEXT, InteractionModality.AUDIO))
.setInputAudioFormat(InputAudioFormat.PCM16)
.setOutputAudioFormat(OutputAudioFormat.PCM16)
.setInputAudioSamplingRate(24000)
.setInputAudioNoiseReduction(new AudioNoiseReductio


n(AudioNoiseReductionType.NEAR_FIELD))
.setInputAudioEchoCancellation(new AudioEchoCancellation())
.setInputAudioTranscription(transcription)
.setTurnDetection(turnDetection);

// 发送配置
ClientEventSessionUpdate updateEvent = new ClientEventSessionUpdate(options);
session.sendEvent(updateEvent).subscribe();

code
### 3. 发送音频输入
java
byte[] audioData = readAudioChunk(); // 您的 PCM16 音频数据
session.sendInputAudio(BinaryData.fromBytes(audioData)).subscribe();
code
### 4. 处理事件
java
session.receiveEvents().subscribe(event -> {
ServerEventType eventType = event.getType();

if (ServerEventType.SESSION_CREATED.equals(eventType)) {
System.out.println("会话已创建");
} else if (ServerEventType.INPUT_AUDIO_BUFFER_SPEECH_STARTED.equals(eventType)) {
System.out.println("用户开始说话");
} else if (ServerEventType.INPUT_AUDIO_BUFFER_SPEECH_STOPPED.equals(eventType)) {
System.out.println("用户停止说话");
} else if (ServerEventType.RESPONSE_AUDIO_DELTA.equals(eventType)) {
if (event instanceof SessionUpdateResponseAudioDelta) {
SessionUpdateResponseAudioDelta audioEvent = (SessionUpdateResponseAudioDelta) event;
playAudioChunk(audioEvent.getDelta());
}
} else if (ServerEventType.RESPONSE_DONE.equals(eventType)) {
System.out.println("响应完成");
} else if (ServerEventType.ERROR.equals(eventType)) {
if (event instanceof SessionUpdateError) {
SessionUpdateError errorEvent = (SessionUpdateError) event;
System.err.println("错误: " + errorEvent.getError().getMessage());
}
}
});
code
## 语音配置

OpenAI 语音

java // 可选:ALLOY, ASH, BALLAD, CORAL, ECHO, SAGE, SHIMMER, VERSE VoiceLiveSessionOptions options = new VoiceLiveSessionOptions() .setVoice(BinaryData.fromObject(new OpenAIVoice(OpenAIVoiceName.ALLOY)));
code
### Azure 语音
java // Azure 标准语音 options.setVoice(BinaryData.fromObject(new AzureStandardVoice("en-US-JennyNeural")));

// Azure 自定义语音
options.setVoice(BinaryData.fromObject(new AzureCustomVoice("myVoice", "endpointId")));

// Azure 个人语音
options.setVoice(BinaryData.fromObject(
new AzurePersonalVoice("speakerProfileId", PersonalVoiceModels.PHOENIX_LATEST_NEURAL)));

code
## 函数调用 (Function Calling)
java
VoiceLiveFunctionDefinition weatherFunction = new VoiceLiveFunctionDefinition("get_weather")
.setDescription("获取指定地点的当前天气")
.setParameters(BinaryData.fromObject(parametersSchema));

VoiceLiveSessionOptions options = new VoiceLiveSessionOptions()
.setTools(Arrays.asList(weatherFunction))
.setInstructions("你可以访问天气信息。");

code
## 最佳实践

1. 使用异步客户端 — VoiceLive 需要响应式编程模式
2. 配置 Turn Detection 以实现自然的对话流
3. 启用噪声抑制 以提高语音识别率
4. 优雅处理中断,使用 setInterruptResponse(true)
5. 使用 Whisper 转录 对输入音频进行文本转录
6. 正确关闭会话,在对话结束时释放资源

错误处理

java session.receiveEvents() .doOnError(error -> System.err.println("连接错误: " + error.getMessage())) .onErrorResume(error -> { // 尝试重新连接或清理资源 return Flux.empty(); }) .subscribe(); ```

参考链接

| 资源 | URL | |----------|-----| | GitHub 源码 | https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/ai/azure-ai-voicelive | | 示例 | https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/ai/azure-ai-voicelive/src/samples |

使用场景

本技能适用于执行概览中所描述的工作流或操作。

局限性

  • 仅在任务明确符合上述范围时使用此技能。
  • 不要将输出结果视为特定环境验证、测试或专家评审的替代方案。
  • 如果缺少必要的输入、权限、安全边界或成功标准,请停止操作并寻求澄清。