【问题标题】:Convert PyAudio microphone input stream to mp3将 PyAudio 麦克风输入流转换为 mp3
【发布时间】:2020-09-05 20:08:34
【问题描述】:

我正在寻找直接从麦克风编码 mp3 文件而不保存到中间 wav 文件的方法。有大量用于保存到 wav 文件的示例以及大量用于将 wav 文件转换为 mp3 的示例。但是我没有找到直接从麦克风保存 mp3 的方法。例如,我正在使用网上找到的以下示例录制到 wav 文件。

我希望获得有关如何将frames 列表(pyaudio 流读取)直接转换为 mp3 的建议。或者,通过 ffmpeg 将 pyaudio 麦克风输入直接流式传输到 mp3,而不用读取数据填充列表/数组。非常感谢!

import pyaudio
import wave

# the file name output you want to record into
filename = "recorded.wav"
# set the chunk size of 1024 samples
chunk = 1024
# sample format
FORMAT = pyaudio.paInt16
# mono, change to 2 if you want stereo
channels = 1
# 44100 samples per second
sample_rate = 44100
record_seconds = 5
# initialize PyAudio object
p = pyaudio.PyAudio()
# open stream object as input & output
stream = p.open(format=FORMAT,
                channels=channels,
                rate=sample_rate,
                input=True,
                output=True,
                frames_per_buffer=chunk)
frames = []
print("Recording...")
for i in range(int(44100 / chunk * record_seconds)):
    data = stream.read(chunk)
    frames.append(data)
print("Finished recording.")
# stop and close stream
stream.stop_stream()
stream.close()
# terminate pyaudio object
p.terminate()
# save audio file
# open the file in 'write bytes' mode
wf = wave.open(filename, "wb")
# set the channels
wf.setnchannels(channels)
# set the sample format
wf.setsampwidth(p.get_sample_size(FORMAT))
# set the sample rate
wf.setframerate(sample_rate)
# write the frames as bytes
wf.writeframes(b"".join(frames))
# close the file
wf.close()

【问题讨论】:

  • 我应该说我在 python 3.8.1 和 windows10 上

标签: python ffmpeg mp3 pyaudio lame


【解决方案1】:

我能够找到一种方法将 pyaudio pcm 流转换为 mp3,而无需使用来自稀有软件的蹩脚 3.1 二进制文件保存到中间 wav 文件。我确信它也可以用 ffmpeg 完成,但由于 ffmpeg 使用 lame 编码为 mp3,我想我会专注于 lame。

为了将原始 pcm 数组直接转换为 mp3,请删除所有波形文件操作并替换为以下内容。这样一来,数据就变成了蹩脚的数据。

raw_pcm = b''.join(frames)
l = subprocess.Popen("lame - -r -m m recorded.mp3", stdin=subprocess.PIPE)
l.communicate(input=raw_pcm)

为了在读取时将 pcm 数据传输到 lame,我使用了以下内容。如果您愿意,我相信您可以在流回调中执行此操作。

l = subprocess.Popen("lame - -r -m m recorded.mp3", stdin=subprocess.PIPE)
for i in range(int(44100 / chunk * record_seconds)):
    l.stdin.write(stream.read(chunk))

我应该注意,无论哪种方式,lame 直到数据完成管道输入后才开始编码。当在每个读取的流上管道输入数据时,我认为编码会立即开始,但事实并非如此.

此外,如果没有读取标准输出和标准错误缓冲区,使用 .stdin.write 可能会导致一些问题。我需要进一步研究。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-27
    相关资源
    最近更新 更多