【问题标题】:how do we check similarity between hash values of two audio files in python?我们如何在 python 中检查两个音频文件的哈希值之间的相似性?
【发布时间】:2020-11-07 05:32:56
【问题描述】:

关于数据: 我们有 2 个相同的视频文件,这些文件的音频也相同,但质量不同。 也就是分别是 128kbps 和 320kbps。

我们使用 ffmpeg 从视频中提取音频,并使用以下代码为两个音频文件生成哈希值:ffmpeg -loglevel error -i 320kbps.wav -map 0 -f hash - 输出为:SHA256=4c77a4a73f9fa99ee219f0019e99a367c4ab72242623f10d1dc35d12f3be726c 同样,我们对另一个我们必须比较的音频文件做了它, C:\FFMPEG>ffmpeg -loglevel 错误 -i 128kbps.wav -map 0 -f hash - SHA256=f8ca7622da40473d375765e1d4337bdf035441bbd01187b69e4d059514b2d69a

现在我们知道这些音频文件和哈希值是不同的,但我们想知道它们实际上有多少不同/相似,例如:比如 a-b 中的某个距离是 3

有人可以帮忙吗?

【问题讨论】:

    标签: python audio ffmpeg computer-vision similarity


    【解决方案1】:

    不能使用 SHA-256 等加密哈希值来比较两个音频文件之间的距离。加密哈希被刻意设计为不可预测的,并且理想情况下不会泄露有关已哈希输入的任何信息。

    但是,有许多合适的acoustic fingerprinting 算法可以接受一段音频并返回一个指纹向量。然后,您可以通过查看两个音频片段对应的指纹向量的接近程度来衡量两个音频片段的相似度。

    选择声学指纹算法

    Chromaprint 是一种流行的开源声学指纹算法,在许多流行语言中都有bindings and reimplementationsAcoustID 项目使用 Chromaprint,该项目正在构建一个开源数据库来收集流行音乐的指纹和元数据。

    研究员 Joren Six 还编写并开源了声学指纹库 PanakoOlaf。但是,它们目前都以 AGPLv3 的形式获得许可,并且可能侵犯仍然有效的美国专利。

    一些公司——例如Pex——销售用于检查任意音频文件是否包含受版权保护的材料的 API。如果您注册 Pex,他们会给您their closed-source SDK,用于根据他们的算法生成声学指纹。

    生成和比较指纹

    在这里,我假设您选择了 Chromaprint。您必须安装 libchromaprint 和 FFT 库。

    我假设您选择了 Chromaprint,并且您想使用 Python 比较指纹,尽管一般原则适用于其他指纹库。

    1. 安装libchromaprint or the fpcalc command line tool
    2. 从 PyPI 安装 pyacoustid Python 库。它将查找您现有的 libchromaprint 或 fpcalc 安装。
    3. 标准化您的音频文件以消除可能混淆 Chromaprint 的差异,例如音频文件开头的静音。还要记住,Chromaprin
    4. 虽然我通常使用measure the distance between vectors using NumPy,但许多 Chromaprint 用户通过计算指纹之间的xor 函数并计算1 位的数量来比较两个音频文件。

    这里有一些用于比较两个指纹之间距离的简单粗暴的 Python 代码。虽然如果我正在构建生产服务,我会在 C++ 或 Rust 中实现比较。

    from operator import xor
    from typing import List
    
    # These imports should be in your Python module path
    # after installing the `pyacoustid` package from PyPI.
    import acoustid
    import chromaprint
    
    
    def get_fingerprint(filename: str) -> List[int]:
        """
        Reads an audio file from the filesystem and returns a
        fingerprint.
    
        Args:
            filename: The filename of an audio file on the local
                filesystem to read.
    
        Returns:
            Returns a list of 32-bit integers. Two fingerprints can
            be roughly compared by counting the number of
            corresponding bits that are different from each other.
        """
        _, encoded = acoustid.fingerprint_file(filename)
        fingerprint, _ = chromaprint.decode_fingerprint(
            encoded
        )
        return fingerprint
    
    
    def fingerprint_distance(
        f1: List[int],
        f2: List[int],
        fingerprint_len: int,
    ) -> float:
        """
        Returns a normalized distance between two fingerprints.
    
        Args:
            f1: The first fingerprint.
    
            f2: The second fingerprint.
    
            fingerprint_len: Only compare the first `fingerprint_len`
                integers in each fingerprint. This is useful
                when comparing audio samples of a different length.
    
        Returns:
            Returns a number between 0.0 and 1.0 representing
            the distance between two fingerprints. This value
            represents distance as like a percentage.
        """
        max_hamming_weight = 32 * fingerprint_len
        hamming_weight = sum(
            sum(
                c == "1"
                for c in bin(xor(f1[i], f2[i]))
            )
            for i in range(fingerprint_len)
        )
        return hamming_weight / max_hamming_weight
    

    上面的函数可以让你比较两个指纹如下:

    >>> f1 = get_fingerprint("1.mp3")
    >>> f2 = get_fingerprint("2.mp3")
    >>> f_len = min(len(f1), len(f2))
    >>> fingerprint_distance(f1, f2, f_len)
    0.35 # for example
    

    您可以阅读有关如何使用 Chromaprint 计算不同音频文件之间距离的更多信息。 This mailing list thread 描述了如何比较 Chromaprint 指纹的理论。 This GitHub Gist 提供了另一种实现方式。

    【讨论】:

    • 由于问题使用了ffmpeg标签,值得一提的是ffmpeg有一个chromaprint muxer。
    【解决方案2】:

    您不能为此使用 SHA256 哈希。这是故意的。如果可以的话,它会削弱哈希的安全性。您的建议类似于差分密码分析。 SHA256 是一种现代加密哈希,旨在防止此类攻击。

    【讨论】:

    • 这个答案没有回答问题,可能更适合作为评论。
    猜你喜欢
    • 2022-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-31
    • 2017-09-23
    • 1970-01-01
    • 2011-04-15
    相关资源
    最近更新 更多