pycord
pycord copied to clipboard
Voice data stops receiving after ~10 seconds
Summary
The UDP socket for receiving voice data becomes stuck in not ready state.
Reproduction Steps
- Bot joins voice channel
- Bot starts recording
- Talk for 10+ seconds.
- Stop bot recording
- Listen to recorded audio.
Minimal Reproducible Code
examples/audio_recording_merged.py
Expected Results
The UDP socket continues to become ready when more data is available, and the recorded audio file contains the full duration of audio.
Actual Results
The UDP socket becomes stuck in the not ready state, and the audio file cuts off after ~10 seconds.
discord/voice_client.py Line 833 (on main)
# After ~10 seconds, the ready variable is always False
ready, _, err = select.select([self.socket], [], [self.socket], 0.01)
Intents
All
System Information
- Python v3.10.10-final
- py-cord v2.4.1-final (main branch on github, not 2.4.1 release. But also reproducible on 2.4.1 stable)
- aiohttp v3.9.1
- system info: Windows 10 10.0.22635
Checklist
- [X] I have searched the open issues for duplicates.
- [X] I have shown the entire traceback, if possible.
- [X] I have removed my token from display, if visible.
Additional Context
For the first ~10 seconds, the socket cycles between ready and not ready as more voice data is streamed in. However, the socket suddenly becomes stuck in the not ready state for no apparent reason.
I tried it with multiple sinks and logged it in multiple ways. The voice data just stops recording after roughly 14s-15s.
Also replicated on MacOS
Replicated on Linux Debian.
Replicated on Windows.
I tried to maintain the connection by sending audio packets like \xf8\xff\xfe
(frames of silence) when an audio sample was received and it seemed to receive data as normal ever since.
... # existing code from discord/voice_client.py
try:
data = self.socket.recv(4096)
except OSError:
self.stop_recording()
continue
self.unpack_audio(data)
# == ADDED ==
self.empty_socket()
self.send_audio_packet(b"\xf8\xff\xfe")
# ===========
# ...existing code below
self.stopping_time = time.perf_counter()
...
However, there'd be a background noise when the user is speaking. Therefore, my approach was to mute the bot itself in my code:
await ctx.guild.change_voice_state(channel=channel, self_mute=True)
I could neither understand the socket connection details from the documentation nor had an experience with sockets, but I assumed it was due to improper connection maintenance handling.
Best