【发布时间】:2010-02-08 12:04:46
【问题描述】:
我想存储多个 mp3 文件并通过给出歌曲的某些部分来搜索它们,以检测它是哪首歌。
我正在考虑将所有二进制内容存储在 mysql 中,当我想按内容搜索特定歌曲时,我将取歌曲的中间部分并将其与 MySQL 中的二进制数据实际匹配。
我的问题是:
- 这是按内容查找歌曲的合理方式吗?
- 将歌曲内容存储在数据库中是否正确,还是应该使用文件系统?
【问题讨论】:
我想存储多个 mp3 文件并通过给出歌曲的某些部分来搜索它们,以检测它是哪首歌。
我正在考虑将所有二进制内容存储在 mysql 中,当我想按内容搜索特定歌曲时,我将取歌曲的中间部分并将其与 MySQL 中的二进制数据实际匹配。
我的问题是:
【问题讨论】:
这是行不通的。 MP3 是一种“有损”格式。这意味着它在编码时不断地改变音乐的细微差别,从而在几乎每个编码上产生完全不同的字节数据同一首歌。
此外,即使是像 WAV 这样的未压缩格式,不同卷的两条相同记录也会产生不同的字节数据。因此,无法通过比较文件内容的字节值来比较音乐。
二进制比较仅适用于 同一个 MP3 文件的两个完全相同的副本。当您使用相同的设置重新编码相同的 MP3 文件时,它甚至不再起作用了。
比较音乐不是一件小事,有几种方法存在,但据我所知,没有一种方法可以在 PHP 中使用。
如果幸运的话,有一个允许某种匹配的网络服务。不过,预计它会以某种方式商业化——我怀疑我们是否处于可以免费使用这种东西的阶段。
【讨论】:
按歌曲内容查找歌曲是否正确。
只有当您可以确定您作为搜索标准获得的部分实际上是该特定 MP3 文件的摘录时……这是非常非常不可能的。如果该部分可以来自不同的来源(即同一首歌的不同录音,或者只是不同压缩的 MP3),您将不得不使用复杂得多的audio fingerprinting。
将歌曲内容存储在数据库或文件存储中是否正常?
如果您进行简单的二进制匹配,则使用数据库毫无意义。如果您有更复杂的索引技术(例如音频指纹),那么使用数据库是有意义的。
【讨论】:
正如其他人所指出的 - 通过查看文件的二进制内容来比较 MP3 是行不通的。
我在大学的最后一年的项目中用 Java 写过类似的东西。我很乐意将源代码发送给您。它处理的是相对相似性——“与歌曲 Z 相比,歌曲 X 与歌曲 Y 更相似”,而不是匹配,但这可能是朝着正确方向迈出的一步。
请不要尝试在 PHP 中执行此操作。我使用的算法需要我为它分析的每个 MP3 计算(如果我没记错的话——我大约在 3 年前研究过)30 个 30x30 矩阵。在我笨重的旧机器上,每首歌大约需要 30 秒才能处理成一组矩阵(我相信我的新电脑可以更快地完成工作)。一旦我得到了 n 首歌曲的矩阵,第二步计算每对歌曲之间的差异,第三步将这些差异减少到 m 维空间。这 3 个步骤中的每一个都需要相当多的精力,PHP 绝对不是这项工作的合适人选。
PHP 可能适用于前端 - 我最终得到了一个用 Ruby on Rails 编写的可查询网络应用程序,其中我有一个简单的后端,它将每首歌曲的坐标存储在 m 维空间中(我碰巧选择 m = 6) - 给定一首特定的歌曲或片段 X,然后您可以在 X 的某个“距离”内计算歌曲。
注意。我可能应该指出,我编写的所有代码基本上只是其他人编写的库的包装——这些库是由奥地利一所大学的一些聪明人编写的——这些库取了两首歌曲并生成了矩阵——我所做的只是计算距离并将大量歌曲的距离映射到 m 维空间。希望我也足够聪明,也能做到这一点!
【讨论】:
我不完全理解您要做什么,但如果您要为 MP3 集合编制索引,存储散列(足够长)而不是实际文件可能是一个更好的主意。
问题是字节不能让您深入了解文件的内容,即其中的音乐。即使您从字节中删除元数据进行比较(以消除元数据的拼写/大写变化等噪音),您也只了解唯一文件本身。因此,您可以比较两个相同文件(即完全重复的文件)的相等性,但您无法比较任何两个随机文件的相似性。
【讨论】:
要搜索歌曲,您可能希望为他们的tags 编制索引,并专注于一个漂亮、易于使用的用户界面,以便用户可以灵活地查找它们。
如上所述,同一首歌曲会根据编码显示不同的内容字节。
但是,指向您的方向的一个想法,我不确定是否可行,将索引一些可能唯一识别它的歌曲模式。例如。所有 Johnny Cash 的歌曲有什么共同点?音量,音调,它们的组合?当你得到一部分内容时,你可以从中提取相同的模式并进行匹配。这将是一个有趣的概念。
【讨论】: