【问题标题】:Is it possible to see if two MP3 files are the same song by analyzing the files' bytes?是否可以通过分析文件的字节来查看两个 MP3 文件是否是同一首歌曲?
【发布时间】:2011-05-27 20:13:48
【问题描述】:

这将在 C++ 或 C.... 中完成 我知道我们可以读取 MP3 的元数据,但是任何人都可以更改该信息,不是吗? 那么有没有办法分析一个文件的内容并将其与另一个文件进行比较并确定它是否实际上是同一首歌曲?

编辑 很多我没有想到的有趣的事情出现了。尝试这样做根本不是一个好主意。

【问题讨论】:

标签: c++ c mp3 byte analysis


【解决方案1】:

这是可能的,但非常困难。

即使是相同的原始录音也可能被不同的 MP3 编码器或具有不同设置的相同编码器以不同的方式编码...导致当 MP3 然后解码时产生不同的结果。你需要建立一个听觉模型来“理解”差异有多大,并做出判断。

然后是不同录音的问题。如果我唱“Once in Royal David's City”,Aled Jones 唱,那是同一首歌吗?如果一首歌有两个不同版本,其中一个版本的歌词略有修改,该怎么办?键可能不同,可能在不同的音域 - 各种各样的东西。

两首歌有多大不同但仍算作“同一首歌”?一旦你决定了,那么实施它就是一件小事;)

【讨论】:

  • +1 表示“非常困难”(这很可能是一个现存的研究问题,至少在一般情况下)
  • 我会买“小马托尼唱圣诞最爱!”
【解决方案2】:

如果我真的必须这样做,我的第一次尝试是对两首歌曲进行傅里叶变换并比较直方图。您可以使用 FFTW (http://www.fftw.org/) 进行傅里叶变换,然后通过对每个频率的差异平方求和来比较直方图。如果结果总和大于某个阈值(您必须通过实验确定),则歌曲被认为是不同的,否则它们是相同的。

【讨论】:

  • @user547703:这听起来像是一个很有希望的起点,但它无法处理一般情况——例如,如果两个录音以不同的调或不同的速度演唱会怎样?
  • +1 表示蛮力,非常简单但不那么详细:“使用傅立叶”方法 :)
  • @Stuart:我们是否可以假设@robinsonc494 的意思是iTunes 意义上的“同一首歌”,意思是相同的录音?跨度>
  • @Clifford:不清楚是什么意思,但我很高兴投票。不过,我认为一般案例问题更有趣,因为它的价值。
  • 请注意,如果源文件具有相同的采样率,您可以跳过执行任何傅里叶变换,只解码 mp3 比特流而不对其执行 IMDCT。然后你就可以免费获得频域数据了。
【解决方案3】:

没有。没那么简单。

您可以检查它们是否包含相同的编码数据,但是:

  • 可能是不同的比特率
  • 可能是同一首歌,只有 1/100 秒的延迟

在这两种情况下,字节都不匹配。

基本上,如果一个解决方案看起来太简单而令人难以置信,那通常就是这样。

【讨论】:

    【解决方案4】:

    如果您在 iTunes 的“相同录音”的意义上指的是“同一首歌”,则可以比较两个音频文件,但不能通过逐字节比较编码文件因为即使对于相同的格式,在编码时也会选择数据速率和压缩等变量。

    此外,同一录音的每个编码可能包括不同的导入/导出时序、不同的幅度和均衡,并且可能来自不同的原始来源(黑胶唱片、CD、原始母带等)。因此,您需要一种将所有这些变量都考虑在内的比较方法,即便如此,您最终也会得到匹配的“可能性”而不是确定的匹配。

    如果你真正的意思是“同一首歌”,即任何艺术家的任何录音,相同的作曲和歌词,那么在大多数情况下,你不太可能得到高度的统计相关性,因为音高、速度、音域、乐器编排会非常不同的。

    在“同一录音”的场景中,可以应用相对简单的信号处理和统计技术,在“同一首歌”的场景中,需要部署人工智能技术,即使这样我怀疑结果也会很差。

    【讨论】:

      【解决方案5】:

      如果您想比较源自相同 MP3 但元数据标记不同的 MP3 文件,只需比较实际的音频数据即可。由于它源自相同的 MP3 编码,您应该能够进行逐字节比较。您必须比较所有字节。只需采样几个就足够了,以获得在统计上几乎不可能在另一首歌曲中找到的唯一键。

      如果文件是由不同的编码器生成的,则必须从数据中提取一些“模糊”特征键并比较这些键。匆忙中我可能会构建一个这样的算法:

      • 以标准比特率将音频解码为脉冲编码调制(波)。
      • 使用一些动态定位算法找到固定数量的特征起点。例如,查找从波开始排序的前 10 个最高波峰,或者简单地均匀分布在整个波中(尽管动态固定第一个和最后一个位置是个好主意,因为不同的编码可能不会在完全相同的点开始和结束)。一种改进是在波浪中不太可能重复的位置选择特征点。
      • 从特征点中提取一组一维特征键标量。例如,对于每个特征,归一化以下 n 个样本值并计算过零次数、峰均比、平均过零距离、信号能量。目标是提取相对独特的鲁棒特征,即使在信号中添加了一些噪声和失真,仍然具有特征。这显然可以得到几乎无限的改进。
      • 使用一些准确度测量比较两个文件的提取特征键(f.eks. 10 个特征提取中的 9 个必须至少匹配 5 个提取特征键中的 4 个的 99%)。

      特征提取方法的好处是,您可以为所有 mp3 文件和单个文件建立一个特征数据库,提出以下问题:还有哪些其他媒体文件具有与此文件完全相同或几乎完全相同的特征。特征查找可以使用 R*-trees 或类似方法非常有效地实现,可用于为您提供 n 维特征集之间的快速距离测量。

      上述技术本质上是图像搜索算法(如 SIFT)中使用的一种变体,这可能是 Photosynth 和 Google Goggles 等应用程序的基础。在图像搜索中,您过滤图像以获得相对独特的特征(例如形状的角)的良好候选点,然后对该特征周围的区域进行归一化以获得归一化的颜色、强度、比例和特征方向。最后,您提取特征并搜索其他图像的特征的 n 维数据库,并验证在其他图像中找到的特征在几何上与您的搜索图像中的模式相同。搜索音频的技术是相同的,只是更简单,因为音频是一维的。

      【讨论】:

        【解决方案6】:

        使用开源 EchoPrint 库创建两个音频文件的签名,并将它们相互比较。

        该库非常易于使用,并且有关于如何创建签名的清晰示例。

        http://echoprint.me/

        您甚至可以使用签名查询他们的数据库并找到匹配的歌曲元数据(例如标题、艺术家等)。

        【讨论】:

          【解决方案7】:

          我认为jstanley 暗示的快速傅里叶变换 (FFT) 方法对于大多数用例来说都非常好;特别是,它可用于验证两者是否为同一发行版/同一艺术家的同一录音/相同比特率/音频质量。

          更明确地说,soxspek(分别通过命令行和 GUI)可以非常轻松地做到这一点。

          Spek 非常简单——只需打开软件并将其指向有问题的两个音频文件即可。

          sox 可以从命令行生成频谱图 (FFT),因此: sox "$file" -n spectrogram -o "$outfile"

          任何一个的结果都是两个图像;如果它们看起来基本相同,那么就几乎所有意图和目的而言,这两首歌将是等效的。

          比如我想测试一下这两个文件:

          1. Soundtrack to an imaginary film mixtape 2011.mp3
          2. DJRUM - Sountrack to an imaginary film mixtape 2011 (for mary-anne hobbs).mp3

          是一样的。 diff 报告了二进制文件的差异(可能是由于元数据差异或较小的编码差异),但快速浏览他们的频谱图即可解决:

          【讨论】:

            猜你喜欢
            • 2011-03-19
            • 2013-05-22
            • 1970-01-01
            • 2016-09-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-08-11
            • 2021-02-15
            相关资源
            最近更新 更多