You need to enable JavaScript to run this app. Java如何基于Socket实现音频流收发及多人语音群聊功能开发
优惠活动
大模型
产品
解决方案
定价
更多

Java如何基于Socket实现音频流收发及多人语音群聊功能开发

Java 连续音频流传输实现方案

客户端实现

你遇到的AudioSystem.getAudioInputStream限制是因为该接口需要解析完整音频文件的头/尾结构,连续实时流没有固定的文件尾,且音频参数可以提前协商,完全不需要走文件解析逻辑,直接调用底层的录播接口即可,无需修改你现有256字节块加密的Socket传输逻辑。

具体实现步骤:

  • 提前在客户端和服务端统一音频参数,推荐使用通用的低延迟配置,示例定义:
// 双端统一的PCM参数:带符号16位采样、44100Hz采样率、单声道、小端字节序
AudioFormat commonFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 1, 2, 44100, false);
  • 音频录制逻辑:调用TargetDataLine直接读取裸PCM数据块,刚好适配你现有256字节加密块大小,读取后直接送入Socket加密发送即可:
TargetDataLine recordLine = AudioSystem.getTargetDataLine(commonFormat);
recordLine.open(commonFormat);
recordLine.start();

byte[] buffer = new byte[256];
while (isRecording) {
    int readLen = recordLine.read(buffer, 0, buffer.length);
    // 此处调用你现有Socket加密逻辑发送buffer前readLen个字节
}

recordLine.stop();
recordLine.close();
  • 音频播放逻辑:收到Socket解密后的PCM数据块,直接喂给SourceDataLine播放即可,不需要解析任何文件头:
SourceDataLine playLine = AudioSystem.getSourceDataLine(commonFormat);
playLine.open(commonFormat);
playLine.start();

byte[] buffer = new byte[256];
while (isPlaying) {
    int readLen = // 此处调用你现有Socket解密逻辑读取数据到buffer
    if (readLen > 0) {
        playLine.write(buffer, 0, readLen);
    }
}

playLine.drain();
playLine.stop();
playLine.close();
  • 可选优化:增加100ms左右的抖动缓冲区,收到的数据包先存入队列,积累到阈值后再喂给播放设备,避免网络波动导致的断音卡顿。

服务端多路音频混合+群聊实现

实时音频混合直接基于裸PCM的采样值计算即可,不需要编解码,实现复杂度很低:

  • 服务端维护所有群内在线用户的会话,每个会话对应独立的接收缓冲区,存储该用户最新发送的256字节PCM块。
  • 音频混合逻辑:16位采样的PCM每2个字节对应一个采样点,将多路音频同一位置的采样点相加后做溢出裁剪即可,示例代码:
// 输入为所有当前说话用户的256字节PCM块列表,输出混合后的256字节PCM块
public byte[] mixAudio(List<byte[]> userBuffers) {
    byte[] mixed = new byte[256];
    // 每2字节处理一个采样点
    for (int i = 0; i < 256; i += 2) {
        int sum = 0;
        for (byte[] buf : userBuffers) {
            // 按双端统一的小端字节序转成short采样值
            short sample = (short) ((buf[i+1] << 8) | (buf[i] & 0xff));
            sum += sample;
        }
        // 溢出裁剪避免破音
        sum = Math.max(Short.MIN_VALUE, Math.min(Short.MAX_VALUE, sum));
        // 转回小端字节
        mixed[i] = (byte) (sum & 0xff);
        mixed[i+1] = (byte) ((sum >> 8) & 0xff);
    }
    return mixed;
}
  • 分发逻辑:混合后的PCM块排除当前说话用户(避免用户听到自己的声音),加密后分发给所有群内在线用户即可。
  • 可选优化:增加静音检测逻辑,若用户发送的PCM采样值绝对值平均值低于阈值,则不将其纳入混合队列,降低服务端计算开销。

内容的提问来源于stack exchange,提问作者user14831455

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 16:06:03