如何在没有标签信息的情况下计算mp3文件的哈希值?

5
我们需要计算mp3文件的哈希值以唯一标识它。问题是,Traktor软件会修改文件的标签,并且没有改变它的机会。
我们使用id3lib库,所以我想也许有一些方法可以获取各个版本标签的前缀和后缀大小,并只读取它们之间的媒体内容以计算哈希值。我在id3lib文档中搜索了一下,唯一找到的是ID3_Tag::GetPrependedBytes()ID3_Tag::GetAppendedBytes(),就像这样:
const std::size_t prepend = tagOpener.GetPrependedBytes();
const std::size_t append = tagOpener.GetAppendedBytes();
const std::size_t overall = tagOpener.Size();

但它们只会返回0。

如果有帮助的话,我们正在使用C++和Qt进行开发,所以也许有一些东西可以帮助解决问题。


为什么不在ID3v1标签的注释字段中放置您自己的唯一ID? - huysentruitw
@WouterH 如果没有其他解决方案可以不触及文件,我们应该这样做。我们不想破坏用户输入的标签。 - Roman Kruglov
2个回答

1
我已经用以下代码解决了这个问题。也许它会帮助到其他人。
/** Return QString hash for the given path */
inline QString GetHash( const QString& filePath )
{
   /// Determine positions of ID3 tags
   ID3_Tag tagOpener( filePath.toLocal8Bit() );
   const std::size_t prepend = tagOpener.GetPrependedBytes();
   const std::size_t append = tagOpener.GetAppendedBytes();

   /// Calculate a hash
   QString hashValueString;
   QFile file( filePath );
   QCryptographicHash hash( QCryptographicHash::Md5 );
   if( file.open(QIODevice::ReadOnly) )
   {
      /// Read only useful media data and skip tags
      const bool seekRes = file.seek( prepend ); // skip prepend tags info
      const qint64 mediaDataSize = file.size() - append - prepend;
      hash.addData( file.read(mediaDataSize) );

      /// Set hash md5 for current file
      hashValueString =  hash.result().toHex().data();
      file.close();
   }

   tagOpener.Clear();
   return hashValueString;
}

这是一个使用Qt和ID3Lib的解决方案。您可以仅使用由hash.result()代码返回的值来获得数字表示。


0

另一种解决方案可能是使用音频负载的哈希值来识别一个mp3文件。你可以使用一个解析mpeg音频文件的库,而不是id3lib吗?


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