我目前正在尝试录制特定用户的音频,或者如果不可能的话,录制整个频道的音频。
我从 Discord.py 开始,但没有成功。目前,机器人会在特定用户连接时加入频道,并应开始录制。使用 python 和 C#,我发现旧的帖子和 github 线程为我的问题提供了解决方案,但这个解决方案似乎不再起作用。 Discord 是否删除了对获取音频流的支持?
我很想拥有他的功能,但我没有找到那么多信息。目前至少在 python 中播放音频没有问题。
编码:
private Task OnVoiceStateUpdated(SocketUser? socketUser, SocketVoiceState before, SocketVoiceState after)
{
_ = Task.Run(async () =>
{
try
{
Logger.Output($"Starting to handle user movements", Logger.LogType.Default);
var currentChannel = after.VoiceChannel ?? before.VoiceChannel;
if (currentChannel == null) return;
var botUser = currentChannel.Guild.Users.FirstOrDefault(u => u.IsBot);
if (before.VoiceChannel == null && after.VoiceChannel != null) // If member joins a voice channel
{
var channel = after.VoiceChannel;
try
{
Logger.Output($"Connect bot to channel '{channel.Name}'", Logger.LogType.Default);
await Task.Delay(1000);
_audioClient = await channel.ConnectAsync();
_cts = new CancellationTokenSource();
if (socketUser is not SocketGuildUser socketGuildUser) return;
if (socketGuildUser.AudioStream is not InputStream inputStream) return;
_ = Task.Run(() =>
ProcessAudioAsync(inputStream)
);
}
catch (Exception e)
{
Logger.Output($"Failed to connect and start recording: {e}", Logger.LogType.Error);
}
}
}
catch (Exception e)
{
Logger.Output($"Handling user movements failed! {e.Message}", Logger.LogType.Error);
}
});
return Task.CompletedTask;
}
private async Task ProcessAudioAsync(InputStream inputStream)
{
// Create a new wave file writer to save the audio stream
string currentTime = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
string filename = Path.Combine(AudioRecordingsPath, $"output_{currentTime}.wav");
// Create the wave file writer to save the audio stream
_writer = new WaveFileWriter(filename, new WaveFormat(48000, 16, 2));
try
{
var buffer = new byte[81920]; // Buffer size can be adjusted as needed
while (!_cts.IsCancellationRequested)
{
var bytesRead = await inputStream.ReadAsync(buffer, 0, buffer.Length, _cts.Token);
// If bytesRead is zero, end of the stream has been reached
if (bytesRead == 0)
{
Task.Delay(1000).Wait();
continue;
}
// Write from buffer to wave file
await _writer.WriteAsync(buffer, 0, bytesRead);
// Flush the writer to ensure data is written to disk
await _writer.FlushAsync();
}
}
catch (OperationCanceledException e)
{
Logger.Output($"Audio processing was cancelled. {e.Message} {e.StackTrace}", Logger.LogType.Error);
}
catch (TimeoutException e)
{
Logger.Output($"Audio processing timed out. {e.Message} {e.StackTrace}", Logger.LogType.Error);
}
catch (InvalidOperationException e)
{
Logger.Output($"Audio processing failed due to stream issue. {e.Message} {e.StackTrace}",
Logger.LogType.Error);
}
catch (Exception e)
{
Logger.Output($"Audio processing failed. {e.Message} {e.StackTrace}", Logger.LogType.Error);
}
finally
{
await inputStream.FlushAsync();
}
}
问题似乎出在这一行“var bytesRead = wait inputStream.ReadAsync(buffer, 0, buffer.Length, _cts.Token);”该函数被调用但永远不会返回。该流似乎从未包含任何数据。
在 C# 或 Python 中是否有可能的解决方案?
非常感谢!
如果您愿意切换库,pycord 具有功能性音频接收器功能(https://guide.pycord.dev/voice/receiving),但它需要一些代码重写。
但是,discord.py 扩展库已创建,允许将语音通道用作接收器。它们可以根据需要自动将音频保存为 .wav 和 .mp3 文件。请参阅 discord-ext-voice-recv 了解更多信息。