如何读取python和ffmpeg或类似的实时麦克风音量

Rya*_*tin 9 python linux audio ffmpeg numpy

我试图用近乎实时的方式读取Python中USB麦克风音频的音量.

我有件,但无法弄清楚如何把它放在一起.

如果我已经有一个.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
Run Code Online (Sandbox Code Playgroud)

这很好用,但我想实时处理来自麦克风的音频,而不是文件.

所以我的想法是使用像ffmpeg这样的东西将实时输出PIPE到WaveReader,但我的Byte知识有点缺乏.

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
Run Code Online (Sandbox Code Playgroud)

这看起来很漂亮,但它没有做太多.它失败并显示[NULL @ 0x7ff640016600]无法为'pipe:'错误找到合适的输出格式.

我认为这是一个相当简单的事情,因为我只需要检查音量的音量.

有人知道如何完成这个吗?FFMPEG不是必需的,但它确实需要在OSX和Linux上运行.

Rya*_*tin 13

感谢@Matthias建议使用sounddevice模块.这正是我需要的.

对于后代,这是一个打印实时音频级别到shell的工作示例:

# Print out realtime audio volume as ascii bars

import sounddevice as sd
import numpy as np

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)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


pba*_*ski 7

Python 3 用户在这里
我几乎没有问题可以完成这项工作,所以我使用了:https : //python-sounddevice.readthedocs.io/en/0.3.3/examples.html#plot-microphone-signal-s-in-real-时间
我需要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)
Run Code Online (Sandbox Code Playgroud)

是的,它有效:)