diff --git a/speech_recognition/__init__.py b/speech_recognition/__init__.py index 253ab0fe..f9515174 100644 --- a/speech_recognition/__init__.py +++ b/speech_recognition/__init__.py @@ -105,23 +105,6 @@ def get_pyaudio(): raise AttributeError("Could not find PyAudio; check installation") return pyaudio - @staticmethod - def list_microphone_names(): - """ - Returns a list of the names of all available microphones. For microphones where the name can't be retrieved, the list entry contains ``None`` instead. - - The index of each microphone's name in the returned list is the same as its device index when creating a ``Microphone`` instance - if you want to use the microphone at index 3 in the returned list, use ``Microphone(device_index=3)``. - """ - audio = Microphone.get_pyaudio().PyAudio() - try: - result = [] - for i in range(audio.get_device_count()): - device_info = audio.get_device_info_by_index(i) - result.append(device_info.get("name")) - finally: - audio.terminate() - return result - @staticmethod def list_working_microphones(): """ diff --git a/speech_recognition/microphone.py b/speech_recognition/microphone.py new file mode 100644 index 00000000..0e6079b4 --- /dev/null +++ b/speech_recognition/microphone.py @@ -0,0 +1,39 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + import pyaudio + + +class PyAudioWrapper: + @staticmethod + def get_pyaudio() -> pyaudio.PyAudio: + """Returns pyaudio.PyAudio instance. + + Checks pyaudio's installation, throws exceptions if pyaudio can't be found + """ + try: + import pyaudio + except ImportError: + raise AttributeError( + "Could not find PyAudio; Run `pip install SpeechRecognition[audio]`" + ) + return pyaudio.PyAudio() + + @staticmethod + def list_microphone_names(): + """ + Returns a list of the names of all available microphones. For microphones where the name can't be retrieved, the list entry contains ``None`` instead. + + The index of each microphone's name in the returned list is the same as its device index when creating a ``Microphone`` instance - if you want to use the microphone at index 3 in the returned list, use ``Microphone(device_index=3)``. + """ + audio = PyAudioWrapper.get_pyaudio() + try: + result = [] + for i in range(audio.get_device_count()): + device_info = audio.get_device_info_by_index(i) + result.append(device_info.get("name")) + finally: + audio.terminate() + return result diff --git a/tests/test_microphone.py b/tests/test_microphone.py new file mode 100644 index 00000000..b9e3d394 --- /dev/null +++ b/tests/test_microphone.py @@ -0,0 +1,14 @@ +import sys +from unittest.mock import patch + +import pytest + +from speech_recognition.microphone import PyAudioWrapper + + +@pytest.mark.skipif(sys.platform.startswith("win"), reason="skip on Windows") +class TestPyAudioWrapper: + @patch("pyaudio.PyAudio") + def test_get_pyaudio(self, PyAudio): + assert PyAudioWrapper.get_pyaudio() == PyAudio.return_value + PyAudio.assert_called_once_with()