From fedf26bf3e91e12a403144e8282300a785c204d4 Mon Sep 17 00:00:00 2001 From: Imayhaveborkedit Date: Sat, 22 Jun 2019 02:33:53 -0400 Subject: Add FFmpegOpusAudio and other voice improvements Rework FFmpeg player and add FFmpegOpusAudio I have extracted some of the base FFmpeg source code into its own base class and reimplemented the PCM and the new Opus variants. Support avconv probing Also fix a few things Update `__all__` Fix the bugs Rework probe functions and add factory function Probing involves subprocess so it has been reworked into an async factory function. Add docs + a few tweaks * Removed unnecessary read() and is_opus() functions from FFmpegAudio * Clear self._stdout in cleanup() * Add 20 second process communication timeout to probe functions * Capped probe function bitrate values at 512 Change AudioPlayer to use more accurate, monotonic time.perf_counter() Add lazy opus loading The library now no longer loads libopus on import, only on opus.Encoder creation or manually. Fix review nits --- discord/opus.py | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) (limited to 'discord/opus.py') diff --git a/discord/opus.py b/discord/opus.py index 9ad6b11c..f958cb3e 100644 --- a/discord/opus.py +++ b/discord/opus.py @@ -38,6 +38,8 @@ c_int_ptr = ctypes.POINTER(ctypes.c_int) c_int16_ptr = ctypes.POINTER(ctypes.c_int16) c_float_ptr = ctypes.POINTER(ctypes.c_float) +_lib = None + class EncoderStruct(ctypes.Structure): pass @@ -100,25 +102,29 @@ def libopus_loader(name): return lib -try: - if sys.platform == 'win32': - _basedir = os.path.dirname(os.path.abspath(__file__)) - _bitness = 'x64' if sys.maxsize > 2**32 else 'x86' - _filename = os.path.join(_basedir, 'bin', 'libopus-0.{}.dll'.format(_bitness)) - _lib = libopus_loader(_filename) - else: - _lib = libopus_loader(ctypes.util.find_library('opus')) -except Exception: - _lib = None +def _load_default(): + global _lib + try: + if sys.platform == 'win32': + _basedir = os.path.dirname(os.path.abspath(__file__)) + _bitness = 'x64' if sys.maxsize > 2**32 else 'x86' + _filename = os.path.join(_basedir, 'bin', 'libopus-0.{}.dll'.format(_bitness)) + _lib = libopus_loader(_filename) + else: + _lib = libopus_loader(ctypes.util.find_library('opus')) + except Exception: + _lib = None + + return _lib is not None def load_opus(name): """Loads the libopus shared library for use with voice. If this function is not called then the library uses the function - :func:`ctypes.util.find_library` and then loads that one - if available. + :func:`ctypes.util.find_library` and then loads that one if available. - Not loading a library leads to voice not working. + Not loading a library and attempting to use PCM based AudioSources will + lead to voice not working. This function propagates the exceptions thrown. @@ -221,7 +227,8 @@ class Encoder: self.application = application if not is_loaded(): - raise OpusNotLoaded() + if not _load_default(): + raise OpusNotLoaded() self._state = self._create_state() self.set_bitrate(128) -- cgit v1.2.3