簡體   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