亲测可用。
录音电平有点低, 不妨自己修改。
$ cat myaudrec.py
import pyaudio
import wave
chunk = 16384 # Record in chunks of ????? samples
sample_format = pyaudio.paInt16 # 16bit sampling
channels = 1
fs = 44100 # 44100 sampling rate
seconds = 30 # Duration of clip
filename = "micXout.wav"
port = pyaudio.PyAudio() # Create an interface of PortAudio
print('Recording')
stream = port.open(format=sample_format,
channels=channels,
rate=fs,
frames_per_buffer=chunk,
input=True)
frames = [] # Initialize an array to buffer frames
# Keep data in chunks for 30 seconds
for i in range(0, int(fs / chunk * seconds)):
data = stream.read(chunk)
frames.append(data)
# Stop and close the stream
stream.stop_stream()
stream.close()
# Terminate the PortAudio interface
port.terminate()
print('Recording Done.')
# Save the recorded data as a WAV file
wf = wave.open(filename, 'wb')
wf.setnchannels(channels)
wf.setsampwidth(port.get_sample_size(sample_format))
wf.setframerate(fs)
wf.writeframes(b''.join(frames))
wf.close()
pyaudio 也许不是默认安装的, 因此您可能需要预先装上。
# dnf -y install python3-pyaudio
Last metadata expiration check: 0:04:52 ago on Sun 02 Aug 2020 11:24:27 PM PDT.
Dependencies resolved.
==================================================================================================================================================
Package Architecture Version Repository Size
==================================================================================================================================================
Installing:
python3-pyaudio x86_64 0.2.11-4.fc31 fedora 38 k
Transaction Summary
==================================================================================================================================================
Install 1 Package
Total download size: 38 k
Installed size: 119 k
Downloading Packages:
python3-pyaudio-0.2.11-4.fc31.x86_64.rpm 124 kB/s | 38 kB 00:00
--------------------------------------------------------------------------------------------------------------------------------------------------
Total 52 kB/s | 38 kB 00:00
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : python3-pyaudio-0.2.11-4.fc31.x86_64 1/1
Running scriptlet: python3-pyaudio-0.2.11-4.fc31.x86_64 1/1
Verifying : python3-pyaudio-0.2.11-4.fc31.x86_64 1/1
Installed:
python3-pyaudio-0.2.11-4.fc31.x86_64
Complete!
另外, 用 python sounddevice 也可以录音。
感觉稍微繁复, 代码也冗长很多。
网上的例子亲测可用, 同样有录音电平比较低的问题。
https://python-sounddevice.readthedocs.io/en/0.4.0/examples.html#recording-with-arbitrary-duration
$ cat ./sdrectest00.py
#!/usr/bin/env python3
"""Create a recording with arbitrary duration.
The soundfile module (https://PySoundFile.readthedocs.io/) has to be installed!
"""
import argparse
import tempfile
import queue
import sys
import sounddevice as sd
import soundfile as sf
import numpy # Make sure NumPy is loaded before it is used in the callback
assert numpy # avoid "imported but unused" message (W0611)
def int_or_str(text):
"""Helper function for argument parsing."""
try:
return int(text)
except ValueError:
return text
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument(
'-l', '--list-devices', action='store_true',
help='show list of audio devices and exit')
args, remaining = parser.parse_known_args()
if args.list_devices:
print(sd.query_devices())
parser.exit(0)
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter,
parents=[parser])
parser.add_argument(
'filename', nargs='?', metavar='FILENAME',
help='audio file to store recording to')
parser.add_argument(
'-d', '--device', type=int_or_str,
help='input device (numeric ID or substring)')
parser.add_argument(
'-r', '--samplerate', type=int, help='sampling rate')
parser.add_argument(
'-c', '--channels', type=int, default=1, help='number of input channels')
parser.add_argument(
'-t', '--subtype', type=str, help='sound file subtype (e.g. "PCM_24")')
args = parser.parse_args(remaining)
q = queue.Queue()
def callback(indata, frames, time, status):
"""This is called (from a separate thread) for each audio block."""
if status:
print(status, file=sys.stderr)
q.put(indata.copy())
try:
if args.samplerate is None:
device_info = sd.query_devices(args.device, 'input')
# soundfile expects an int, sounddevice provides a float:
args.samplerate = int(device_info['default_samplerate'])
if args.filename is None:
args.filename = tempfile.mktemp(prefix='delme_rec_unlimited_',
suffix='.wav', dir='')
# Make sure the file is opened before recording anything:
with sf.SoundFile(args.filename, mode='x', samplerate=args.samplerate,
channels=args.channels, subtype=args.subtype) as file:
with sd.InputStream(samplerate=args.samplerate, device=args.device,
channels=args.channels, callback=callback):
print('#' * 80)
print('press Ctrl+C to stop the recording')
print('#' * 80)
while True:
file.write(q.get())
except KeyboardInterrupt:
print('nRecording finished: ' + repr(args.filename))
parser.exit(0)
except Exception as e:
parser.exit(type(e).__name__ + ': ' + str(e))
用 sounddevice 录音,要事先安装 sounddevice 和 soundfile
,不然就出错。
## pip install --upgrade pip
# pip install sounddevice
Requirement already satisfied: sounddevice in /usr/local/lib/python3.7/site-packages (0.4.0)
Requirement already satisfied: CFFI>=1.0 in /usr/lib64/python3.7/site-packages (from sounddevice) (1.12.3)
Requirement already satisfied: pycparser in /usr/lib/python3.7/site-packages (from CFFI>=1.0->sounddevice) (2.14)
sudo pip install soundfile
Collecting soundfile
Downloading SoundFile-0.10.3.post1-py2.py3-none-any.whl (21 kB)
Requirement already satisfied: cffi>=1.0 in /usr/lib64/python3.7/site-packages (from soundfile) (1.12.3)
Requirement already satisfied: pycparser in /usr/lib/python3.7/site-packages (from cffi>=1.0->soundfile) (2.14)
Installing collected packages: soundfile
Successfully installed soundfile-0.10.3.post1
参考:
PortAudio v19 Python Bindings
PyAudio Documentation - PyAudio 0.2.11 documentation
https://stackoverflow.com/questions/892199/detect-record-audio-in-python