【问题标题】:Python - How to record system audio(The output from the speaker)?Python - 如何录制系统音频(扬声器的输出)?
【发布时间】:2019-03-13 14:13:32
【问题描述】:

我从上周开始一直在寻找这个。也尝试了 pyaudio,当我使用它的另一个分叉时,系统音频与麦克风音频混合在一起。我找不到任何其他模块,因此最后问了这个问题。

编辑:

import pyaudio
import wave

CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"

p = pyaudio.PyAudio()
SPEAKERS = p.get_default_output_device_info()["hostApi"] #The modified part

stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK,
                input_host_api_specific_stream_info=SPEAKERS,
                as_loopback = True) #The part I have modified

print("* recording")

frames = []

for i in range(0, int(RATE / CHUNK * RECORD_SECONDS) + 1):
    data = stream.read(CHUNK)
    frames.append(data)

print("* done recording")

stream.stop_stream()
stream.close()
p.terminate()

wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()

此代码取自堆栈溢出。它记录扬声器输出,但输出与麦克风输入混合。 使用的 pyaudio 模块也来自 fork:https://github.com/intxcc/pyaudio_portaudio

【问题讨论】:

  • 到目前为止您已经尝试过什么。任何代码?你遇到了什么错误?
  • 我添加了代码。

标签: python audio system pyaudio


【解决方案1】:

使用https://github.com/intxcc/pyaudio_portaudio
这只会记录“device_id”指定的设备的音频

import pyaudio
import wave

chunk = 1024  # Record in chunks of 1024 samples
sample_format = pyaudio.paInt16  # 16 bits per sample
channels = 2
fs = 44100  # Record at 44100 samples per second
seconds = 3
filename = "output.wav"

p = pyaudio.PyAudio()  # Create an interface to PortAudio

#Select Device
print ( "Available devices:\n")
for i in range(0, p.get_device_count()):
    info = p.get_device_info_by_index(i)
    print ( str(info["index"]) +  ": \t %s \n \t %s \n" % (info["name"], p.get_host_api_info_by_index(info["hostApi"])["name"]))
    pass

#ToDo change to your device ID
device_id = 7
device_info = p.get_device_info_by_index(device_id)
channels = device_info["maxInputChannels"] if (device_info["maxOutputChannels"] < device_info["maxInputChannels"]) else device_info["maxOutputChannels"]
# https://people.csail.mit.edu/hubert/pyaudio/docs/#pyaudio.Stream.__init__
stream = p.open(format=sample_format,
                channels=channels,
                rate=int(device_info["defaultSampleRate"]),
                input=True,
                frames_per_buffer=chunk,
                input_device_index=device_info["index"],
                as_loopback=True
                )

frames = []  # Initialize array to store frames

print('\nRecording', device_id, '...\n')

# Store data in chunks for 3 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
p.terminate()

print('Finished recording')

# Save the recorded data as a WAV file
wf = wave.open(filename, 'wb')
wf.setnchannels(channels)
wf.setsampwidth(p.get_sample_size(sample_format))
wf.setframerate(fs)
wf.writeframes(b''.join(frames))
wf.close()

附:查看https://github.com/intxcc/pyaudio_portaudio/tree/master/example

【讨论】:

  • 提醒以后看到这个的人:1、不要使用官方的pyaudio,安装使用github.com/intxcc/pyaudio_portaudio发布的轮子,2、确保device_id正确,否则是stream部分会报错
【解决方案2】:

这可以通过声卡来完成。您必须弄清楚要用于环回的设备索引。此代码打印出您必须从中选择的代码。我通过遍历所有这些并查看扬声器播放时哪个产生非零找到了正确的。

pip install soundcard

import soundcard as sc
import time

# get a list of all speakers:
speakers = sc.all_speakers()
# get the current default speaker on your system:
default_speaker = sc.default_speaker()

# get a list of all microphones:v
mics = sc.all_microphones(include_loopback=True)
# get the current default microphone on your system:
default_mic = mics[index of your speaker loopback here]

for i in range(len(mics)):
    try:
        print(f"{i}: {mics[i].name}")
    except Exception as e:
        print(e)

with default_mic.recorder(samplerate=148000) as mic, \
            default_speaker.player(samplerate=148000) as sp:
    print("Recording...")
    data = mic.record(numframes=1000000)
    print("Done...Stop your sound so you can hear playback")
    time.sleep(5)
    sp.play(data)

【讨论】:

    【解决方案3】:

    我在mac上安装了一个virtul soundcard(blackhole)来录制系统音频,并且可以正常工作。 我只录制没有麦克风音频的系统音频,因为我不需要它

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-06
      • 1970-01-01
      相关资源
      最近更新 更多