You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pycord开发Discord机器人:如何合并多段Wave音频实现同步播放?

问题:Discord语音频道多用户音频合成同步播放失败

我正在开发一款Discord机器人,使用Pycord库录制语音频道内的音频,每个用户的音频会生成独立文件。现在需要将这些音频合成为单个Wave文件,实现像Discord客户端那样多人同时说话的同步播放效果,但当前代码仅能完成音频叠加,实际只能听到一个音频流。

当前代码如下:

async def after_recording(self, sink: discord.sinks.WaveSink, channel: discord.VoiceChannel):
    audio_segments = []
    for audio_data in sink.audio_data.values():
        audio_data.file.seek(0)
        audio_segments.append(AudioSegment.from_file(audio_data.file))

    # Determine the maximum duration of the audio files
    max_duration = max([len(segment) for segment in audio_segments])

    # Pad the shorter audio files with silence
    for i, segment in enumerate(audio_segments):
        if len(segment) < max_duration:
            audio_segments[i] = segment + AudioSegment.silent(duration=max_duration - len(segment))

    # Overlay the audio files
    overlaid_segment = audio_segments[0]
    for segment in audio_segments[1:]:
        overlaid_segment = overlaid_segment.overlay(segment)

    # Export the overlaid audio to a BytesIO object
    overlaid_bytes = BytesIO()
    overlaid_segment.export(overlaid_bytes, format='wav')
    overlaid_bytes.seek(0)

    # Send the overlaid audio as a message attachment to the specified channel
    await channel.send(file=discord.File(overlaid_bytes, filename='overlaid_audio.wav'))

    # Cleanup
    for audio_data in sink.audio_data.values():
        audio_data.file.close()

注:代码由ChatGPT辅助生成,已多次审阅修改,是目前能找到的唯一类似解决方案,并非完全由AI生成。


解决方案

出现只能听到一个音频流的核心原因,大概率是各用户音频的采样率、声道数、位深不一致,导致overlay操作无法正确混合;另外AudioSegment.silent默认参数可能和原音频格式不匹配,填充的静音段格式不对也会干扰混合效果。

以下是修正后的代码,关键优化点已标注:

from pydub import AudioSegment
import io
import discord

async def after_recording(self, sink: discord.sinks.WaveSink, channel: discord.VoiceChannel):
    audio_segments = []
    # 先获取第一个音频的格式参数,统一后续所有音频的格式
    first_audio = next(iter(sink.audio_data.values()))
    first_audio.file.seek(0)
    base_segment = AudioSegment.from_file(first_audio.file)
    sample_rate = base_segment.frame_rate
    channels = base_segment.channels
    sample_width = base_segment.sample_width

    audio_segments.append(base_segment)

    # 处理剩余音频,统一格式后加入列表
    for audio_data in list(sink.audio_data.values())[1:]:
        audio_data.file.seek(0)
        segment = AudioSegment.from_file(audio_data.file)
        # 转换为统一格式:采样率、声道、位深与第一个音频一致
        segment = segment.set_frame_rate(sample_rate).set_channels(channels).set_sample_width(sample_width)
        audio_segments.append(segment)

    # 计算最长音频时长
    max_duration = max(len(seg) for seg in audio_segments)

    # 用匹配格式的静音填充短音频
    silent_segment = AudioSegment.silent(
        duration=max_duration,
        frame_rate=sample_rate,
        channels=channels,
        sample_width=sample_width
    )
    padded_segments = []
    for seg in audio_segments:
        # 将原音频叠加到静音段上,保证时长一致且格式匹配
        padded = silent_segment.overlay(seg)
        padded_segments.append(padded)

    # 混合所有音频(替代原有的逐个overlay,效率更高且效果更稳定)
    mixed_segment = padded_segments[0]
    for seg in padded_segments[1:]:
        # 使用"+"操作符实现音频混合,而非overlay(overlay是叠加到原音频的指定位置,"+"是直接混合)
        mixed_segment = mixed_segment + seg

    # 导出混合后的音频
    mixed_bytes = io.BytesIO()
    mixed_segment.export(mixed_bytes, format='wav')
    mixed_bytes.seek(0)

    # 发送文件
    await channel.send(file=discord.File(mixed_bytes, filename='mixed_audio.wav'))

    # 清理文件
    for audio_data in sink.audio_data.values():
        audio_data.file.close()

关键优化说明

  1. 统一音频格式:强制所有用户的音频转换为相同的采样率、声道数和位深,避免格式不兼容导致混合失败。
  2. 匹配格式的静音填充:生成与原音频格式一致的静音段,再将原音频叠加到静音段上,确保填充后的音频格式完全统一。
  3. 改用"+"操作符混合音频:pydub中+操作符会直接将两个音频的波形数据相加(自动处理音量溢出),比overlay更适合多人语音的同步混合场景,overlay更适合将一段音频叠加到另一段的指定位置(比如背景音叠加)。

如果问题仍然存在,可以检查以下几点:

  • 确认Pycord的sink是否正确捕获了所有用户的音频数据,可以单独播放每个用户的音频文件验证。
  • 调整混合后的音频音量,避免多个音频叠加后音量溢出导致失真或被截断。
  • 尝试使用pydub的AudioSegment.from_raw方法读取音频数据,确保解析格式正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 01:28:19