如何使用python从mp3文件中提取原始数据?

时间:2013-05-19 11:22:24

标签: python audio mp3 eyed3

我有使用Python进行音频数据分析的作业。我想知道是否有任何好的模块可供我从mp3文件中提取原始数据。我的意思是原始数据,而不是元数据,id3标签。

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

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

4 个答案:

答案 0 :(得分:15)

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

from pydub import AudioSegment

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

# sound._data is a bytestring
raw_data = sound._data

答案 1 :(得分:4)

在stackoverflow上有一些类似的问题。有不同的用例。

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

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

  3. 这个答案针对其中的第二个,尽管我没有工作代码可以分享或指向。

    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(文件名,“rb”),然后在现代机器上读取数据= f.read() - 假设.mp3中典型的5分钟歌曲大约为5MB,你也可以一次性阅读整篇文章。)

    在这些方面编写一个更简单(效率更低)的编码方案也值得探讨它的工作原理,逐步添加MP3和AAC等技巧方案。例如,将PCM输入文件拆分为1024个样本块,使用FFT或DCT等,然后再返回,并查看如何获取原始数据。然后探索如何将数据从频率转换版本中抛出,并看看它在转换回PCM数据时有什么影响。然后最终结果将是非常差的,但是通过看到问题,并看到例如MP3和AAC可以,你可以学习为什么这些压缩方案按照他们的方式做事。

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

答案 2 :(得分:3)

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

f = open("test.mp3", "rb")
first16bytes = f.read(16)
etc...

答案 3 :(得分:0)

我使用了 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()

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

Audio data plotted with Matplotlib

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