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

Discord.Net无法接收语音数据:TryReadFrame始终返回false求助

问题排查与解决方案

针对你遇到的Discord机器人无法读取语音帧的问题,以下是具体的排查方向和修复建议:


1. 修正握手数据包格式

你发送的10字节空数据不符合Discord语音协议要求。Discord采用Opus编码,PCM流需满足48kHz采样率、16位深度、单声道,且每帧为20ms时长(对应1920字节)。应发送完整的静音帧作为握手包:

// 生成符合规格的静音帧:48000Hz * 0.02s * 2字节/采样 = 1920字节
byte[] silenceFrame = new byte[1920];
await outputStream.WriteAsync(silenceFrame, 0, silenceFrame.Length);
await outputStream.FlushAsync();

2. 检查语音流的获取逻辑

确保AudioStream是从IAudioClient的有效接收流中获取的。在Discord.NET中,需通过订阅AudioClient.UserSpeaking事件关联说话用户的语音流,而非直接使用未初始化或错误的流对象。

3. 优化循环判断逻辑

AudioStream.CanRead无法可靠反映异步场景下的流状态,建议改用取消令牌控制循环,并添加短延迟避免空循环占用资源:

private async Task ReadAsync(CancellationToken cancellationToken)
{
    while (!cancellationToken.IsCancellationRequested)
    {
        if (AudioStream.TryReadFrame(default, out var frame))
        {
            Log.Debug("Frame read from user {User}", User.Username);
            // 处理语音帧逻辑
        }
        else
        {
            await _writer!.StandardInput.BaseStream.WriteAsync(_silenceBuffer);
            await _writer!.StandardInput.BaseStream.FlushAsync();
            // 20ms延迟匹配语音帧间隔
            await Task.Delay(20, cancellationToken);
        }
    }
    Log.Debug("Reading voice data of {User} finished.", User.Username);
}

4. 确认权限与网关意图

  • 确保机器人拥有Voice Receive服务器权限,邀请机器人时需勾选该权限;
  • 在Discord开发者门户的Bot设置中,启用Privileged Gateway Intents下的GuildVoiceStates意图,否则机器人无法获取语音状态数据。

5. 验证语音客户端连接状态

在循环中添加连接状态检查,避免在连接异常时无效读取:

if (_audioClient.ConnectionState != ConnectionState.Connected)
{
    Log.Warning("Audio client is not connected, skipping frame read.");
    await Task.Delay(1000);
    continue;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 10:09:58