6

我有关于使用 Python 进行音频数据分析的作业。我想知道有没有什么好的模块可以用来从 mp3 文件中提取原始数据。我的意思是原始数据,而不是元数据,id3 标签。

我知道如何使用该wave模块来处理.wav文件。我可以readframes得到原始数据。但我不知道如何处理mp3。我在 google 和 stackoverflow 上搜索了很多并找到eyeD3. 但不幸的是,文档相当令人沮丧,现在版本是 0.7.1,与我在 Internet 上找到的大多数示例不同。

有没有什么好的模块可以从 mp3 中提取原始数据?如果有任何好的文档eyeD3,那也很好。

4

4 回答 4

20

如果我理解您的问题,您可以尝试使用pydub(我编写的一个库)来获取音频数据,如下所示:

from pydub import AudioSegment

sound = AudioSegment.from_mp3("test.mp3")

# sound._data is a bytestring
raw_data = sound._data
于 2013-09-16T14:24:26.750 回答
4

stackoverflow 周围有一些类似的问题。有不同的用例。

  1. 用户想要将 .mp3 文件转换为 PCM 文件,例如 .wav 文件。

  2. 用户想要访问 .mp3 文件中的原始数据(也就是说,不将其视为压缩的 PCM)。这里的用例是了解 MP3 和 AAC 等压缩方案的工作原理。

尽管我没有可共享或指向的工作代码,但此答案针对的是其中的第二个。

MP3 等压缩方案通常在频域工作。作为一个简化的示例,您可以一次获取 1024 个样本的 .wav 文件,使用 FFT 转换每个 1024 个样本块,然后将其存储。粗略地说,有损压缩会丢弃频域中的信息,以便进行更小的编码。

如果您只想将.mp3 转换为.wav,那么纯python 实现是非常不切实际的。但是,如果您想探索 .mp3 和相关方案是如何工作的,那么即使代码运行速度比 ffmpeg 使用的慢 1000 倍,您也可以轻松修改一些东西,这实际上是有用的,特别是如果以允许的方式编写阅读源代码以了解 .mp3 压缩是如何工作的。例如,请参阅http://bugra.github.io/work/notes/2014-07-12/discre-fourier-cosine-transform-dft-dct-image-compression/了解 IPython 工作簿,了解如何进行频域转换用于JPEG等图像压缩方案。类似于 MP3 压缩和类似的东西对于学习压缩的人很有用。

.mp3 文件基本上是一系列 MP3 帧,每个帧都有一个标题和数据组件。然后第一个任务是编写一个 Python 类(或多个类)来表示这些,并从 .mp3 文件中读取它们。首先以二进制模式读取文件(即 f = open(filename,"rb") 然后 data = f.read() - 在现代机器上,假设 .mp3 中典型的 5 分钟歌曲约为 5MB,您不妨一口气读完整本书)。

沿着这些思路编写一个更简单(而且效率低得多)的编码方案也可能值得探索它的工作原理,逐渐添加 MP3 和 AAC 等技巧方案。例如,将一个 PCM 输入文件拆分为 1024 个样本块,使用 FFT 或 DCT 之类的,然后再返回,看看如何取回原始数据。然后探索如何将数据从频率转换的版本中丢弃,看看它在转换回 PCM 数据时会产生什么影响。那么最终的结果会很差,起初,但是通过看到问题,看看 MP3 和 AAC 做了什么,你可以了解为什么这些压缩方案会以它们的方式做事。

简而言之,如果您的用例是“完成工作”,您可能不想使用 Python。另一方面,如果您的用例是“学习如何完成工作”,那就不同了。(作为一个粗略的经验法则,你可以在 90 年代的 Pentium 100 上优化组装,你可以在现代 Core i5 上使用 Python 以大致相同的性能 - 类似这样 - 有一个因素100 左右的原始性能,以及使用 Python 的类似减速)。

于 2016-01-31T14:59:49.537 回答
3

您是否尝试过以读取二进制模式打开文件?

f = open("test.mp3", "rb")
first16bytes = f.read(16)
etc...
于 2013-07-11T04:55:58.600 回答
1

我使用 Jiaaro 的回答中的 pydub,但我想为这个问题添加一些代码,这些代码实际上可以从 MP3 文件中提取 PCM 数据。

这是一个带注释的完整程序,用于读取 MP3 文件,将 PCM 数据提取到有符号整数列表中,然后使用 matplotlib 对其进行绘图。显然 pydub 和 matplotlib 需要安装。

from pydub import AudioSegment
from matplotlib import pyplot as plt

# This will open and read the audio file with pydub.  Replace the file path with
# your own file.
audio_file = AudioSegment.from_file("./2021-02-23-22:00:11-edited.mp3")

# Set up a list for us to dump PCM samples into, and create a 'data' variable
# so we don't need to type audio_file._data again
data = audio_file._data
pcm16_signed_integers = []

# This loop decodes the bytestring into PCM samples.
# The bytestring is a stream of little-endian encoded signed integers.
# This basically just cuts each two-byte sample out of the bytestring, converts
# it to an integer, and appends it to the list of samples.
for sample_index in range(len(data)//2):
    sample = int.from_bytes(data[sample_index*2:sample_index*2+2], 'little', signed=True)
    pcm16_signed_integers.append(sample)

# Now plot the samples!
plt.plot(pcm16_signed_integers)
plt.show()

这是我的情节的样子(我放大了一个很好的部分):

使用 Matplotlib 绘制的音频数据

是的,这个图表是从上面的代码生成的:D

于 2021-02-24T07:05:39.750 回答