如何在内置输出上调用python声音设备包

时间:2018-12-12 03:16:29

标签: python python-3.x audio

我试图在Mac OS X 10.14.1上使用python3和sounddevice记录计算机的音频输出(不是输入到麦克风,而是输入到扬声器-在离开设备之前)。

从下面的追溯中可以看到,我尝试了所有合理的输入通道数和默认的输入通道数,但是没有运气。我也查看了源代码,但无法确定我的问题。

是否可以在系统上录制音频输出流?

Python 3.6.2 (v3.6.2:5fd33b5926, Jul 16 2017, 20:11:06) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sounddevice as sd
>>> sd.query_devices()
> 0 Built-in Microphone, Core Audio (2 in, 0 out)
< 1 Built-in Output, Core Audio (0 in, 2 out)
>>> sd.default.device = 1
>>> print("Channels should be 0 (number of input channels) or 2 (number of output channels)")
Channels should be 0 (number of input channels) or 2 (number of output channels)
>>> duration = 10
>>> fs = 44100
>>> x = sd.rec(int(duration * fs), samplerate=fs, channels=2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sounddevice.py", line 224, in rec
    ctx.input_dtype, callback, blocking, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sounddevice.py", line 2417, in start_stream
    **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sounddevice.py", line 1301, in __init__
    **_remove_self(locals()))
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sounddevice.py", line 780, in __init__
    'Error opening {0}'.format(self.__class__.__name__))
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sounddevice.py", line 2572, in _check
    raise PortAudioError(errormsg, err)
sounddevice.PortAudioError: Error opening InputStream: Invalid number of channels [PaErrorCode -9998]
>>> x = sd.rec(int(duration * fs), samplerate=fs, channels=0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sounddevice.py", line 224, in rec
    ctx.input_dtype, callback, blocking, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sounddevice.py", line 2417, in start_stream
    **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sounddevice.py", line 1301, in __init__
    **_remove_self(locals()))
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sounddevice.py", line 780, in __init__
    'Error opening {0}'.format(self.__class__.__name__))
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sounddevice.py", line 2572, in _check
    raise PortAudioError(errormsg, err)
sounddevice.PortAudioError: Error opening InputStream: Invalid number of channels [PaErrorCode -9998]
>>> x = sd.rec(int(duration * fs), samplerate=fs)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sounddevice.py", line 215, in rec
    ctx.frames = ctx.check_out(out, frames, channels, dtype, mapping)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sounddevice.py", line 2351, in check_out
    'Unable to determine number of input channels')
TypeError: Unable to determine number of input channels

2 个答案:

答案 0 :(得分:2)

您似乎正在告诉它进行记录:

sd.rec(...

并且您正在录制的设备没有输入,这是真的。

以下是播放声音的一个很好的例子:

https://python-sounddevice.readthedocs.io/en/0.3.12/examples.html#play-a-sound-file

或使用下面的马克提供的非常简洁的示例。

就将输出返回到输入而言,这需要进行一些高级工作,例如在驱动程序级别进行操作。我注意到有一个名为SoundFlower的OSX虚拟设备可以执行此操作。参见:

https://apple.stackexchange.com/questions/221980/os-x-route-audio-output-to-audio-input

可在此处找到来源:

https://github.com/mattingalls/Soundflower

选择利用此现有工具,或者尝试尝试理解和提取所需行为的子集的更陡峭的路径(胆量在SoundflowerEngine :: createAudioStreams中)。

答案 1 :(得分:1)

我编写了下面的脚本,该脚本可以在Python 2.x和3.x中运行。

  

以下代码可在Windows中完美运行,但尚未在MAC OS X中进行测试。希望这可能对您有用。

最重要的是,不要忘记安装sounddevice,soundfile,numpy

import sounddevice
import soundfile

rec_rate = 40000  # Hertz
rec_duration = 10  # seconds
rec_name = 'names.wav'  # Name for file
rec_data = sounddevice.rec(int(rec_rate * rec_duration), samplerate=rec_rate, channels=1, blocking=True)  # Recording ...
soundfile.write(rec_name, rec_data, rec_rate)  # Writing recorded sound in a file
相关问题