如何以编程方式比较MP3文件

5

我想要能够以程序方式比较mp3文件。但问题是我不知道用什么方式比较,是用头部信息?直方图?声道信息?有没有人在这个领域有经验?


我猜你的意思是“比较”,对吗? - schnaader
下面的答案中提到的用于比较音频的程序似乎已经多年没有更新了。还有什么是现在仍在维护的吗? 我也遇到了这个问题,我需要一个程序来比较两个mp3文件并生成差异报告。 - Adrian Ber
@AdrianBer,也许可以看一下https://acoustid.org/chromaprint?请看我的回答。 - Alexis Wilke
9个回答

19
我写了我的硕士论文关于音频指纹识别。这篇论文列举了一些开源解决方案来比较音乐的声音,并提供它们之间的性能比较。可能有点过头了,但是有一些非常不错的应用程序可用。
如果您只想通过标记数据进行比较,则要查看的标准是ID3。基本上有两个版本,第一个非常简单(ID3v1),由一个128字节块组成,位于MP3的末尾。ID3v2在MP3的开头放置了一个更大,可变大小的块。

1
Vegard Larsen的论文链接现在已经失效,但我在这里找到了它:http://daim.idi.ntnu.no/masteroppgaver/IME/IDI/2008/4014/masteroppgave.pdf - mivk
@VegardLarsen,您的硕士论文链接已经失效,请更新一下链接,谢谢! - Hooray Im Helping
1
@HoorayImHelping 帖子中的URL已更新。有人更改了URL结构:http://daim.idi.ntnu.no/masteroppgaver/004/4014/masteroppgave.pdf - Vegard Larsen

6
我希望能够以编程方式比较mp3文件。我曾经有同样的问题,我发现iTunes改变了我的Amazon MP3下载文件的时间/日期戳、文件大小和MD5签名,导致我的备份中出现了许多近似重复的文件。当我使用VIM进行比较时,我发现这些更改只是文件的非常小的部分。在Audacity中,即使放大查看,两个文件看起来也完全相同。我的解决方案是创建一个没有头信息的WAV转储文件,然后比较每个WAV的MD5签名。FFMPEG可以很容易地完成这种转换。
ffmpeg -y -i $mp3 $mp3.wav;
md5sum $mp3.wav

我使用MD5作为键创建了哈希,指向原始的MP3文件规范。将WAV文件放在SSD上以提高速度。
虽然有些暴力,但它能够运行。

1
创建的wav文件可能仍然具有一些元数据。使用以下命令来去除它:avconv -i wav.wav -map 0 -map_metadata 0:s:0 -c copy nometa.wav - Tamas

4
我猜你可以采用以下几种方法之一来解决这个问题:

1. 比较标签

你可以比较mp3标签中保存的数据。标签以ID3格式保存。有很多库可以帮助你访问标签,tagLib是一个流行的选择(对于.net应用程序,TagLib Sharp也是如此)。

2. 声纹识别

这是目前最可靠的方法,允许您找到匹配项,而不管压缩甚至格式如何。从文件的实际音频创建唯一的指纹,允许识别歌曲echoprint是一个开源的例子。

3. 从文件创建哈希值

这是一种更快的方法,允许您查找内容完全匹配的文件。


更多阅读:

  • 这里有一篇有趣的MSDN文章,介绍如何管理mp3收藏(包括读取标签):链接文本(它是用Visual Basic编写的,但仍然可能有用。)

  • 这里有一个文件格式的简要说明:链接文本


3

有没有任何库/程序可以做到这一点? - Adrian Ber

2
为了更好地回答您的问题,我认为我们需要知道您想要做什么。
如果您想比较实际的歌曲,musicDNS有一个库可以创建音频指纹。这个名为libOFA的库可以在这里找到:这里。这种指纹系统被用于将数字音频文件与其数据库匹配,例如musicbrainz。理论上,您可以使用它来比较两个不同的数字文件。
如果您想比较标签数据(id3v1/id3v2),有很多库可以为您完成此操作,其中提到了taglib,libmpg123也有自己的函数来提取标签数据。 libOFA方法的好处是,您可以将不同格式的文件进行比较,因为指纹是在音频本身上完成的。

1
看起来Chromaprint可以做你想要的事情。它可以将PCM数据转换成音频指纹,然后用于比较。
他们有一个C API库(实际上是用C++编写的),一个Python前端,还有一些工具可以将结果转换成JSON格式,这意味着你可以使用另一种语言来操作数据。但我不认为他们提供比较功能本身。
此外,如果你使用的是Linux系统,很可能会找到相应的软件包。

0

如果你只是想根据标签比较mp3文件,我建议使用taglib


0

我编写了一个PHP程序,只是比较音频--忽略所有的头文件、图形和其他信息。 基本上从文件列表foreach as $src: /usr/bin/ffmpeg -hide_banner -y -i "$src" -f s16le -acodec pcm_s16le output.raw 2> /dev/null

您可以对output.raw文件进行md5哈希(必须记录该文件),并将其与其他原始文件进行比较。

转换后的文件是原始输出音频,仅用于创建哈希。我预见到脚本的唯一问题是在转换/哈希后保留低质量的文件,或者保留较少的ID3标签的文件...尽管我移动文件而不是删除它们,所以仍然有旧文件。


-1

我经常在Linux上使用fdupes来查找重复文件。fdupes使用md5校验和。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接