@ -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
DEALINGS IN THE SOFTWARE .
"""
from __future__ import annotations
import threading
@ -717,6 +718,8 @@ class AudioPlayer(threading.Thread):
self . _current_error : Optional [ Exception ] = None
self . _lock : threading . Lock = threading . Lock ( )
self . _end_async : asyncio . Event = asyncio . Event ( loop = client . loop )
if after is not None and not callable ( after ) :
raise TypeError ( ' Expected a callable for the " after " parameter. ' )
@ -774,7 +777,8 @@ class AudioPlayer(threading.Thread):
self . stop ( )
finally :
self . _call_after ( )
self . source . cleanup ( )
self . _cleanup ( )
self . client . loop . call_soon_threadsafe ( self . _end_async . set )
def _call_after ( self ) - > None :
error = self . _current_error
@ -788,6 +792,12 @@ class AudioPlayer(threading.Thread):
elif 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 :
self . _end . set ( )
self . _resumed . set ( )
@ -817,6 +827,10 @@ class AudioPlayer(threading.Thread):
self . source = source
self . resume ( update_speaking = False )
async def wait_async ( self ) - > Optional [ Exception ] :
await self . _end_async . wait ( )
return self . _current_error
def _speak ( self , speaking : SpeakingState ) - > None :
try :
asyncio . run_coroutine_threadsafe ( self . client . ws . speak ( speaking ) , self . client . client . loop )