实时通讯
This commit is contained in:
@@ -1,90 +1,90 @@
|
||||
package com.realtime.config;
|
||||
|
||||
import com.realtime.service.DoubaoVoiceService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.bytedeco.javacv.FFmpegFrameGrabber;
|
||||
import org.bytedeco.javacv.FFmpegFrameRecorder;
|
||||
import org.bytedeco.javacv.Frame;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.socket.BinaryMessage;
|
||||
import org.springframework.web.socket.CloseStatus;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
import org.springframework.web.socket.handler.BinaryWebSocketHandler;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.EOFException;
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ClientVoiceHandler extends BinaryWebSocketHandler {
|
||||
private final DoubaoVoiceService doubaoVoiceService;
|
||||
|
||||
public ClientVoiceHandler(DoubaoVoiceService doubaoVoiceService) {
|
||||
this.doubaoVoiceService = doubaoVoiceService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
|
||||
// 客户端会话
|
||||
// 建立与豆包 API 的连接
|
||||
|
||||
System.out.println(session);
|
||||
doubaoVoiceService.connect(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {
|
||||
System.out.println("2");
|
||||
// 接收客户端的音频数据(如 PCM 片段)
|
||||
byte[] audioData = message.getPayload().array();
|
||||
// 预处理:确保格式符合豆包 API 要求(如采样率、位深)
|
||||
byte[] processedData = preprocessAudio(audioData);
|
||||
// 发送给豆包 API
|
||||
doubaoVoiceService.sendAudio(processedData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
|
||||
// 关闭与豆包 API 的连接
|
||||
doubaoVoiceService.close();
|
||||
}
|
||||
|
||||
private byte[] preprocessAudio(byte[] audioData) {
|
||||
if (audioData == null || audioData.length == 0) {
|
||||
log.warn("接收到空的音频数据,跳过处理");
|
||||
return new byte[0]; // 返回空数组,避免后续错误
|
||||
}
|
||||
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
|
||||
try (FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(new ByteArrayInputStream(audioData));
|
||||
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputStream, 1)) {
|
||||
|
||||
grabber.start();
|
||||
// 打印输入音频信息(调试用)
|
||||
log.debug("输入音频格式:{},采样率:{},声道:{}",
|
||||
grabber.getFormat(), grabber.getSampleRate(), grabber.getAudioChannels());
|
||||
|
||||
recorder.setFormat("s16le");
|
||||
recorder.setSampleRate(16000);
|
||||
recorder.setAudioChannels(1);
|
||||
recorder.start();
|
||||
|
||||
Frame frame;
|
||||
int frameCount = 0;
|
||||
while ((frame = grabber.grab()) != null) {
|
||||
recorder.record(frame);
|
||||
frameCount++;
|
||||
}
|
||||
log.debug("成功处理 {} 帧音频", frameCount);
|
||||
|
||||
recorder.stop();
|
||||
grabber.stop();
|
||||
return outputStream.toByteArray();
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("音频预处理失败", e);
|
||||
return new byte[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
//package com.realtime.config;
|
||||
//
|
||||
//import com.realtime.service.DoubaoVoiceService;
|
||||
//import lombok.extern.slf4j.Slf4j;
|
||||
//import org.bytedeco.javacv.FFmpegFrameGrabber;
|
||||
//import org.bytedeco.javacv.FFmpegFrameRecorder;
|
||||
//import org.bytedeco.javacv.Frame;
|
||||
//import org.springframework.stereotype.Component;
|
||||
//import org.springframework.web.socket.BinaryMessage;
|
||||
//import org.springframework.web.socket.CloseStatus;
|
||||
//import org.springframework.web.socket.WebSocketSession;
|
||||
//import org.springframework.web.socket.handler.BinaryWebSocketHandler;
|
||||
//
|
||||
//import java.io.ByteArrayInputStream;
|
||||
//import java.io.ByteArrayOutputStream;
|
||||
//import java.io.EOFException;
|
||||
//@Slf4j
|
||||
//@Component
|
||||
//public class ClientVoiceHandler extends BinaryWebSocketHandler {
|
||||
// private final DoubaoVoiceService doubaoVoiceService;
|
||||
//
|
||||
// public ClientVoiceHandler(DoubaoVoiceService doubaoVoiceService) {
|
||||
// this.doubaoVoiceService = doubaoVoiceService;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void afterConnectionEstablished(WebSocketSession session) throws Exception {
|
||||
// // 客户端会话
|
||||
// // 建立与豆包 API 的连接
|
||||
//
|
||||
// System.out.println(session);
|
||||
// doubaoVoiceService.connect(session);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {
|
||||
// System.out.println("2");
|
||||
// // 接收客户端的音频数据(如 PCM 片段)
|
||||
// byte[] audioData = message.getPayload().array();
|
||||
// // 预处理:确保格式符合豆包 API 要求(如采样率、位深)
|
||||
// byte[] processedData = preprocessAudio(audioData);
|
||||
// // 发送给豆包 API
|
||||
// doubaoVoiceService.sendAudio(processedData);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
|
||||
// // 关闭与豆包 API 的连接
|
||||
// doubaoVoiceService.close();
|
||||
// }
|
||||
//
|
||||
// private byte[] preprocessAudio(byte[] audioData) {
|
||||
// if (audioData == null || audioData.length == 0) {
|
||||
// log.warn("接收到空的音频数据,跳过处理");
|
||||
// return new byte[0]; // 返回空数组,避免后续错误
|
||||
// }
|
||||
//
|
||||
// ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
//
|
||||
// try (FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(new ByteArrayInputStream(audioData));
|
||||
// FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputStream, 1)) {
|
||||
//
|
||||
// grabber.start();
|
||||
// // 打印输入音频信息(调试用)
|
||||
// log.debug("输入音频格式:{},采样率:{},声道:{}",
|
||||
// grabber.getFormat(), grabber.getSampleRate(), grabber.getAudioChannels());
|
||||
//
|
||||
// recorder.setFormat("s16le");
|
||||
// recorder.setSampleRate(16000);
|
||||
// recorder.setAudioChannels(1);
|
||||
// recorder.start();
|
||||
//
|
||||
// Frame frame;
|
||||
// int frameCount = 0;
|
||||
// while ((frame = grabber.grab()) != null) {
|
||||
// recorder.record(frame);
|
||||
// frameCount++;
|
||||
// }
|
||||
// log.debug("成功处理 {} 帧音频", frameCount);
|
||||
//
|
||||
// recorder.stop();
|
||||
// grabber.stop();
|
||||
// return outputStream.toByteArray();
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// log.error("音频预处理失败", e);
|
||||
// return new byte[0];
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
Reference in New Issue
Block a user