5 votes

Java compare deux fichiers audio avec l'empreinte digitale

Je veux savoir si deux fichiers audio sont identiques ou si l'un contient l'autre.

Pour ce faire, j'utilise l'empreinte digitale de 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());

pour convertir l'audio en tableau d'octets, j'utilise l'API sonore

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;
}

mais lorsque je l'ai exécutée, je me suis sentie à l'aise. fingerprint.getFingerprintsSimilarity() un 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)

Comment comparer 2 fichiers mp3 avec l'empreinte digitale en Java ?

2voto

kriegaex Points 6365

Je n'ai jamais fait de choses audio en Java auparavant, mais j'ai regardé votre code brièvement. Je pense que musicg ne fonctionne que pour les fichiers WAV, pas pour les MP3. Vous devez donc d'abord convertir les fichiers. Une recherche sur le web révèle qu'il est possible d'utiliser par exemple JLayer à cette fin. Le code correspondant se présente comme suit :

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());
  }
}

Bien sûr, vous devez vous assurer que vous ne convertissez pas chaque fichier à nouveau lorsque le programme démarre, c'est-à-dire que vous devez vérifier si les fichiers WAV existent déjà. J'ai sauté cette étape et réduit l'exemple de code à une version minimale fonctionnelle.

0voto

user1878676 Points 1

Pour FingerprintSimilarityComputer(input1, input2), il est supposé prendre en compte l'empreinte digitale des données audio chargées et non les données audio chargées elles-mêmes.

Dans votre cas, cela devrait être le cas :

// Convert your audio to wav using FFMpeg

Wave w1 = new Wave("first.wav");
Wave w2 = new Wave("second.wav");

FingerprintSimilarityComputer fingerprint = 
        new FingerprintSimilarityComputer(w1.getFingerprint(), w2.getFingerprint());

// print fingerprint.getFingerprintSimilarity()

0voto

Torge Points 1239

Peut-être ai-je oublié un point, mais si j'ai bien compris, cela devrait suffire :

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

byte[] smaller = firstAudio.length <= secondAudio.lenght ? firstAudio : secondAudio;
byte[] bigger = firstAudio.length > secondAudio.length ? firstAudio : secondAudio;

int ixS = 0;
int ixB = 0;

boolean contians = false;

for (; ixB<bigger.length; ixB++) {

    if (smaller[ixS] == bigger[ixB]) {
        ixS++;
        if (ixS == smaller.lenght) {
            contains = true;
            break;
        }
    }
    else {
        ixS = 0;
    }
}

if (contains) {
    if (smaller.length == bigger.length) {
        System.out.println("Both tracks are equal");
    }
    else {
        System.out.println("The bigger track, fully contains the smaller track starting at byte: "+(ixB-smaller.lenght));
    }
}
else {
    System.out.println("No track completely contains the other track");
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X