Java通过指纹比较两个音频文件

ana*_*oli 5 java fingerprint musicg

我想知道两个音频文件是否相同或者一个包含另一个。

为此,我使用音乐指纹

byte[] firstAudio = readAudioFileData("first.mp3");
byte[] secondAudio = readAudioFileData("second.mp3");

FingerprintSimilarityComputer fingerprint = 
            new FingerprintSimilarityComputer(firstAudio, secondAudio);

FingerprintSimilarity fingerprintSimilarity = fingerprint.getFingerprintsSimilarity();

System.out.println("clip is found at " + fingerprintSimilarity.getScore());
Run Code Online (Sandbox Code Playgroud)

要将音频转换为字节数组,我使用声音 API

public static byte[] readAudioFileData(final String filePath) {
    byte[] data = null;
    try {
        final ByteArrayOutputStream baout = new ByteArrayOutputStream();
        final File file = new File(filePath);
        final AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(file);

        byte[] buffer = new byte[4096];
        int c;
        while ((c = audioInputStream.read(buffer, 0, buffer.length)) != -1) {
            baout.write(buffer, 0, c);
        }
        audioInputStream.close();
        baout.close();
        data = baout.toByteArray();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return data;
}
Run Code Online (Sandbox Code Playgroud)

但是当我执行它时,我变成fingerprint.getFingerprintsSimilarity()Exception.

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 15999
at com.musicg.fingerprint.PairManager.getPairPositionList(PairManager.java:133)
at com.musicg.fingerprint.PairManager.getPair_PositionList_Table(PairManager.java:80)
at com.musicg.fingerprint.FingerprintSimilarityComputer.getFingerprintsSimilarity(FingerprintSimilarityComputer.java:71)
at Main.main(Main.java:42)
Run Code Online (Sandbox Code Playgroud)

如何在Java中比较2个mp3文件与指纹?

kri*_*aex 2

我以前从未用 Java 做过任何音频工作,但我简单地研究了你的代码。我认为musicg仅适用于WAV文件,不适用于MP3。因此,您需要先转换文件。网络搜索表明您可以使用JLayer来实现此目的。相应的代码如下所示:

package de.scrum_master.so;

import com.musicg.fingerprint.FingerprintManager;
import com.musicg.fingerprint.FingerprintSimilarity;
import com.musicg.fingerprint.FingerprintSimilarityComputer;
import com.musicg.wave.Wave;
import javazoom.jl.converter.Converter;
import javazoom.jl.decoder.JavaLayerException;

public class Application {
  public static void main(String[] args) throws JavaLayerException {
    // MP3 to WAV
    new Converter().convert("White Wedding.mp3", "White Wedding.wav");
    new Converter().convert("Poison.mp3", "Poison.wav");
    // Fingerprint from WAV
    byte[] firstFingerPrint = new FingerprintManager().extractFingerprint(new Wave("White Wedding.wav"));
    byte[] secondFingerPrint = new FingerprintManager().extractFingerprint(new Wave("Poison.wav"));
    // Compare fingerprints
    FingerprintSimilarity fingerprintSimilarity = new FingerprintSimilarityComputer(firstFingerPrint, secondFingerPrint).getFingerprintsSimilarity();
    System.out.println("Similarity score = " + fingerprintSimilarity.getScore());
  }
}
Run Code Online (Sandbox Code Playgroud)

当然,您应该确保在程序启动时不会再次转换每个文件,即您应该检查 WAV 文件是否已经存在。我跳过了这一步,并将示例代码缩减为最小工作版本。

  • 请限定您的评论,它只是判断性的,但不是很有用。“糟糕的解决方案”为什么?因为存储空间?CPU使用率?转换需要时间?顺便说一句,为一对文件提供代码并不是很好的风格,根本没有提到批处理的需要。Quote: “如何在 Java 中比较 2 个 mp3 文件和指纹?” 我已经正确回答了你的问题。如果您认为这个解决方案“不好”,也许您想要选择一个更好的库,一步就能完成您想象的事情。我没有魔杖给你。 (2认同)