Как читать громкость звука микрофона в реальном времени в python и ffmpeg или аналогичном

Я пытаюсь читать, в практически в реальном времени, громкость, поступающая от звука USB-микрофона в Python.

у меня есть кусочки, но я не могу понять, как их собрать.

Если у меня уже есть .wav-файл, я могу просто прочитать его с помощью wavefile:

from wavefile import WaveReader

with WaveReader("/Users/rmartin/audio.wav") as r:
    for data in r.read_iter(size=512):
        left_channel = data[0]
        volume = np.linalg.norm(left_channel)
        print volume

это отлично работает, но я хочу обрабатывать звук с микрофона в режиме реального времени, а не из файла.

Так что моя мысль была использовать что-то вроде ffmpeg для передачи вывода в реальном времени в WaveReader, но мои байтовые знания несколько отсутствуют.

import subprocess
import numpy as np

command = ["/usr/local/bin/ffmpeg",
            '-f', 'avfoundation',
            '-i', ':2',
            '-t', '5',
            '-ar', '11025',
            '-ac', '1',
            '-acodec','aac', '-']

pipe = subprocess.Popen(command, stdout=subprocess.PIPE, bufsize=10**8)
stdout_data = pipe.stdout.read()
audio_array = np.fromstring(stdout_data, dtype="int16")

print audio_array

это выглядит красиво, но это не делает много. Он выдает [NULL @ 0x7ff640016600] не удалось найти подходящий формат вывода для ' pipe:' ошибка.

Я предполагаю, что это довольно простая вещь, учитывая, что мне нужно только проверить уровень громкости звука.

кто-нибудь знает, как это сделать просто? Попробуйте не требование, но он должен работать на OSX и Linux.

2 ответов


спасибо @Matthias за предложение использовать модуль sounddevice. Это именно то, что мне нужно.

для потомков вот рабочий пример, который печатает уровни звука в реальном времени в оболочке:

# Print out realtime audio volume as ascii bars

import sounddevice as sd

duration = 10  # seconds

def print_sound(indata, outdata, frames, time, status):
    volume_norm = np.linalg.norm(indata)*10
    print "|" * int(volume_norm)

with sd.Stream(callback=print_sound):
    sd.sleep(duration * 1000)

enter image description here


пользователь Python 3 здесь
У меня было мало проблем, чтобы сделать эту работу, поэтому я использовал: https://python-sounddevice.readthedocs.io/en/0.3.3/examples.html#plot-microphone-signal-s-in-real-time
И мне нужно установить sudo apt-get install python3-tk для python 3.6 look модуль Tkinter не найден на Ubuntu
Затем я изменил скрипт:

#!/usr/bin/env python3
import numpy as np
import sounddevice as sd

duration = 10 #in seconds

def audio_callback(indata, frames, time, status):
   volume_norm = np.linalg.norm(indata) * 10
   print("|" * int(volume_norm))


stream = sd.InputStream(callback=audio_callback)
with stream:
   sd.sleep(duration * 1000)

и да, это работает :)