我想使用 Python 在我的桌面应用程序中使用钩子进入 Mac OS 输出音频流。
所有现有的堆栈溢出帖子都围绕着系统输入(麦克风),或者需要像 https://github.com/ExistentialAudio/BlackHole 这样的第 3 方软件进行设置,这比我希望我的用户必须执行的步骤要多做。
我的用例:我的目标是使用 flet 构建一个跨平台的桌面应用程序,它转录用户扬声器的输出。我想听所有输出音频,而不是特定于应用程序。
AC:一个 Python 脚本,可以实时收听用户为一系列不同应用程序输出的音频(可能保存到 wav 文件以便于验证)。
备注:
要使用 Python 连接到 macOS 上的输出音频流,您可以使用 Apple 提供的 Core Audio API。此 API 允许您访问低级别的音频流并对其执行各种操作,包括捕获音频。
在 Python 中使用 Core Audio 的一种方法是使用 pyaudio 库,它为支持从默认输出设备捕获音频的 PortAudio 库提供了 Python 包装器。你可以使用 pip 安装 pyaudio:
pip install pyaudio
这是一个使用 pyaudio 从默认输出设备捕获音频的示例代码片段:
import pyaudio
import wave
chunk_size = 1024 # number of audio frames per buffer
format = pyaudio.paInt16 # audio format
channels = 2 # number of audio channels
sample_rate = 44100 # audio sample rate
audio = pyaudio.PyAudio()
# open audio stream
stream = audio.open(
format=format,
channels=channels,
rate=sample_rate,
input=True,
frames_per_buffer=chunk_size,
input_device_index=None, # use default audio device
output_device_index=None # use default audio device
)
# start capturing audio
frames = []
while True:
data = stream.read(chunk_size)
frames.append(data)
# process audio data here
...
# stop capturing audio
stream.stop_stream()
stream.close()
audio.terminate()
# save captured audio to a WAV file
wf = wave.open("output.wav", "wb")
wf.setnchannels(channels)
wf.setsampwidth(audio.get_sample_size(format))
wf.setframerate(sample_rate)
wf.writeframes(b"".join(frames))
wf.close()
此代码使用 pyaudio 打开音频流,并开始以 1024 帧的块捕获音频。捕获的音频数据附加到帧列表。您可以在捕获帧的循环中处理音频数据。
当您完成捕获音频后,您可以停止音频流并使用 wave 模块将捕获的音频保存到 WAV 文件。
frames
列表包含捕获的音频数据。
请注意,此代码从默认输出设备捕获音频,因此它将从系统上播放音频的所有应用程序捕获音频。如果您想从特定应用程序中捕获音频,则需要使用不同的方法,例如使用虚拟音频设备或在系统级别拦截音频。