Browse Source

Merge 6f74fb7213 into 26855160f8

pull/9842/merge
Imayhaveborkedit 1 month ago
committed by GitHub
parent
commit
bbc4ac33e5
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 15
      discord/player.py
  2. 21
      discord/voice_client.py

15
discord/player.py

@ -21,6 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
""" """
from __future__ import annotations from __future__ import annotations
import threading import threading
@ -721,6 +722,8 @@ class AudioPlayer(threading.Thread):
self._current_error: Optional[Exception] = None self._current_error: Optional[Exception] = None
self._lock: threading.Lock = threading.Lock() self._lock: threading.Lock = threading.Lock()
self._end_future = client.loop.create_future()
if after is not None and not callable(after): if after is not None and not callable(after):
raise TypeError('Expected a callable for the "after" parameter.') raise TypeError('Expected a callable for the "after" parameter.')
@ -778,7 +781,8 @@ class AudioPlayer(threading.Thread):
self.stop() self.stop()
finally: finally:
self._call_after() self._call_after()
self.source.cleanup() self._cleanup()
self.client.loop.call_soon_threadsafe(self._end_future.set_result, self._current_error)
def _call_after(self) -> None: def _call_after(self) -> None:
error = self._current_error error = self._current_error
@ -792,6 +796,12 @@ class AudioPlayer(threading.Thread):
elif error: elif error:
_log.exception('Exception in voice thread %s', self.name, exc_info=error) _log.exception('Exception in voice thread %s', self.name, exc_info=error)
def _cleanup(self) -> None:
try:
self.source.cleanup()
except Exception:
_log.exception("Error cleaning up audio source %s", self.source)
def stop(self) -> None: def stop(self) -> None:
self._end.set() self._end.set()
self._resumed.set() self._resumed.set()
@ -821,6 +831,9 @@ class AudioPlayer(threading.Thread):
self.source = source self.source = source
self.resume(update_speaking=False) self.resume(update_speaking=False)
async def wait_async(self) -> Optional[Exception]:
return await self._end_future
def _speak(self, speaking: SpeakingState) -> None: def _speak(self, speaking: SpeakingState) -> None:
try: try:
asyncio.run_coroutine_threadsafe(self.client.ws.speak(speaking), self.client.client.loop) asyncio.run_coroutine_threadsafe(self.client.ws.speak(speaking), self.client.client.loop)

21
discord/voice_client.py

@ -557,6 +557,27 @@ class VoiceClient(VoiceProtocol):
self._player.set_source(value) self._player.set_source(value)
async def wait_until_done(self) -> Optional[Exception]:
"""|coro|
Waits for the audio player to finish playback and returns any encountered error.
.. versionadded:: 2.4
Returns
--------
Optional[:class:`Exception`]
The exception the player encountered during playback, or ``None``.
"""
if not self.is_connected():
raise ClientException('Not connected to voice.')
if self._player is None:
raise ValueError('Not playing anything.')
return await self._player.wait_async()
def send_audio_packet(self, data: bytes, *, encode: bool = True) -> None: def send_audio_packet(self, data: bytes, *, encode: bool = True) -> None:
"""Sends an audio packet composed of the data. """Sends an audio packet composed of the data.

Loading…
Cancel
Save