Mac OS El Capitan записывает звук с помощью Python
Я пытаюсь записать звук с микрофона. Сначала использовался PyAudio, затем звуковое устройство, но оба не удалось.
Вот код для PyAudio:
import pyaudio
def _recording_loop(samples_queue, running, stream, chunk_size):
stream.start_stream()
while running.is_set():
samples_queue.put(stream.read(chunk_size))
stream.stop_stream()
class Recoder:
def __init__(self, frame_rate, period):
self.proc = None
self.running = Event()
self.samples_queue = Queue()
self.frame_rate = frame_rate
self.chunk_size = (frame_rate*period) / 1000
self.channels = 1
self._pa = pyaudio.PyAudio()
self._stream = None
def start(self):
if self.proc is None:
self._stream = self._pa.open(format=pyaudio.paInt8,
channels=self.channels,
rate=self.frame_rate,
input=True,
frames_per_buffer=self.chunk_size)
self.running.set()
self.proc = Process(target=_recording_loop, args=[self.samples_queue, self.running, self._stream,
self.chunk_size])
self.proc.start()
def stop(self):
if self.proc is not None:
self.running.clear()
self.proc.join()
self._stream.close()
self._pa.terminate()
def empty(self):
return self.samples_queue.empty()
def read(self):
res = []
while not self.samples_queue.empty():
res.append(self.samples_queue.get())
return res
Это дает мне предупреждение:Python[21648:645093] 13:42:01.242 WARNING: 140: This application, or a library it uses, is using the deprecated Carbon Component Manager for hosting Audio Units. Support for this will be removed in a future release. Also, this makes the host incompatible with version 3 audio units. Please transition to the API's in AudioComponent.h.
и ничего никогда не записывается.
Как я понимаю, это что-то с El Capitan и еще не решено. А может я не прав?
Поэтому я решил переключить библиотеку на звуковое устройство:
from multiprocessing import Process, Queue, Event
import sounddevice as sd
def _recording_loop(samples_queue, running, frame_rate, chunk_size):
while running.is_set():
samples_queue.put(sd.rec(chunk_size, samplerate=frame_rate, channels=1,
dtype='int8', blocking=True))
class Recoder:
def __init__(self, frame_rate, period):
self.proc = None
self.running = Event()
self.samples_queue = Queue()
self.frame_rate = frame_rate
self.period = period
self.chunk_size = (frame_rate * period) / 1000
def start(self):
if self.proc is None:
self.running.set()
self.proc = Process(target=_recording_loop, args=[self.samples_queue, self.running, self.frame_rate,
self.chunk_size])
self.proc.start()
def stop(self):
if self.proc is not None:
self.running.clear()
self.proc.join()
def empty(self):
return self.samples_queue.empty()
def read(self):
res = []
while not self.samples_queue.empty():
res.append(self.samples_queue.get())
return res
И это говорит:
||PaMacCore (AUHAL)|| Warning on line 530: err=''who?'', msg=Audio Hardware: Unknown Property
||PaMacCore (AUHAL)|| Warning on line 534: err=''who?'', msg=Audio Hardware: Unknown Property
||PaMacCore (AUHAL)|| Warning on line 445: err=''who?'', msg=Audio Hardware: Unknown Property
И опять ничего не записывается. Что я делаю не так?
2 ответа
sounddevice.rec() не предназначен для такого использования. Вы просто называете это с количеством кадров, которое хотите записать, и все (см. Пример из документации):
import sounddevice as sd
fs = 44100
duration = 10 # seconds
myrecording = sd.rec(duration * fs, samplerate=fs, channels=2,
blocking=True)
Вот и все. Вам не нужно полстраницы кода только для записи звука.
Кстати, вы можете пока проигнорировать предупреждение, см. https://github.com/spatialaudio/python-sounddevice/issues/10.
Вчера я столкнулся с подобной проблемой. Кажется, это вызвано использованием многопроцессорной обработки со звуковым устройством. Когда я делаю import sounddevice
в верхней части модуля я получаю ||PaMacCore (AUHAL)|| Warning on line 530: err=''who?'', msg=Audio Hardware: Unknown Property
а затем приложение просто зависает при создании sounddevice.RawInputStream
, Когда я импортирую звуковое устройство в моем run()
метод (я создаю новый класс на основе multiprocessing.Process
) все отлично работает. Мне кажется, что sounddevice делает что-то для инициализации сразу после импорта, и это должно происходить в том же процессе, в котором он будет использоваться.Изменить: вместо Multiprocessing
использование Threading
,