Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
854 views
in Technique[技术] by (71.8m points)

linux - How to read realtime microphone audio volume in python and ffmpeg or similar

I'm trying to read, in near-realtime, the volume coming from the audio of a USB microphone in Python.

I have the pieces, but can't figure out how to put it together.

If I already have a .wav file, I can pretty simply read it using 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

This works great, but I want to process the audio from the microphone in real-time, not from a file.

So my thought was to use something like ffmpeg to PIPE the real-time output into WaveReader, but my Byte knowledge is somewhat lacking.

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

That looks pretty, but it doesn't do much. It fails with a [NULL @ 0x7ff640016600] Unable to find a suitable output format for 'pipe:' error.

I assume this is a fairly simple thing to do given that I only need to check the audio for volume levels.

Anyone know how to accomplish this simply? FFMPEG isn't a requirement, but it does need to work on OSX & Linux.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Thanks to @Matthias for the suggestion to use the sounddevice module. It's exactly what I need.

For posterity, here is a working example that prints real-time audio levels to the shell:

# Print out realtime audio volume as ascii bars

import sounddevice as sd
import numpy as np

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(10000)

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...