繁体   English   中英

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

[英]How to extract the raw data from a mp3 file using python?

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

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

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

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

from pydub import AudioSegment

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

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

有一些类似的问题围绕着 stackoverflow 浮动。 有不同的用例。

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

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

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

MP3 等压缩方案一般工作在频域。 作为一个简化示例,您可以一次获取 .wav 文件 1024 个样本,使用 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 的放缓)。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM