功能概述
基于《JavaUtils系列 - 实时PCM音频播放器(RealtimePcmPlayer)》实现支持语音和图像输入的实时对话系统,使用麦克风输入语音,并可选发送图像数据,接收语音回复并播放。
相关依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dashscope-sdk-java</artifactId>
<version>2.20.9</version>
</dependency>
<dependency>
<groupId>com.googlecode.soundlibs</groupId>
<artifactId>mp3spi</artifactId>
<version>1.9.5.4</version>
</dependency>
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.5.3</version>
</dependency>
核心流程
1. 初始化
String imageB64 = null;
if (EnableVisionInput) {
// 读取图片并转为 Base64
File imageFile = new File("data/cat_480p.jpg");
// ... 读取文件并编码为 Base64
}
2. 配置 Omni 参数
OmniRealtimeParam param = OmniRealtimeParam.builder()
.model("qwen-omni-turbo-realtime-latest")
.build();
3. 创建音频播放器
RealtimePcmPlayer audioPlayer = new RealtimePcmPlayer(24000);
4. 创建对话回调
OmniRealtimeConversation conversation = new OmniRealtimeConversation(param, new OmniRealtimeCallback() {
@Override
public void onEvent(JsonObject message) {
String type = message.get("type").getAsString();
switch(type) {
case "response.audio.delta":
String recvAudioB64 = message.get("delta").getAsString();
audioPlayer.write(recvAudioB64); // 播放回复音频
break;
case "input_audio_buffer.speech_started":
audioPlayer.cancel(); // 用户开始说话,取消当前播放
break;
// ... 其他事件处理
}
}
});
5. 连接并配置会话
conversation.connect();
OmniRealtimeConfig config = OmniRealtimeConfig.builder()
.modalities(Arrays.asList(OmniRealtimeModality.AUDIO, OmniRealtimeModality.TEXT))
.voice("Chelsie")
.enableTurnDetection(true)
.enableInputAudioTranscription(true)
.InputAudioTranscription("gummy-realtime-v1")
.build();
conversation.updateSession(config);
6. 录音和发送数据
TargetDataLine targetDataLine = AudioSystem.getTargetDataLine(audioFormat);
targetDataLine.open(audioFormat);
targetDataLine.start();
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (System.currentTimeMillis() - start < 50000) {
int read = targetDataLine.read(buffer.array(), 0, buffer.capacity());
if (read > 0) {
String audioB64 = Base64.getEncoder().encodeToString(buffer.array());
conversation.appendAudio(audioB64); // 发送音频数据
if (EnableVisionInput && System.currentTimeMillis() - last_photo_time > 500) {
conversation.appendVideo(imageB64); // 每 500ms 发送一次图片
last_photo_time = System.currentTimeMillis();
}
Thread.sleep(20); // 控制发送频率
}
}
7. 结束会话
conversation.commit();
conversation.createResponse(null, null);
conversation.close(1000, "bye");
audioPlayer.waitForComplete();
audioPlayer.shutdown();
系统交互流程
-
初始化:加载图片、创建音频播放器、连接 Omni 服务
-
录音:从麦克风读取音频数据,实时发送到服务端
-
视觉输入:可选定时发送图片数据
-
接收回复:
-
文本回复:打印到控制台
-
音频回复:通过
RealtimePcmPlayer播放
-
-
VAD 检测:检测到用户说话时打断当前播放
-
结束:等待所有音频播放完成后关闭资源
关键技术点
-
多线程音频处理:解码和播放分离,避免阻塞
-
实时音频播放:使用
SourceDataLine实现低延迟播放 -
Base64 编解码:音频和图片数据编码传输
-
事件驱动架构:通过回调处理服务端推送的各种事件
-
VAD 支持:检测用户语音开始,实现打断效果

被折叠的 条评论
为什么被折叠?



