2016-11-01 13 views
3

Я хочу узнать, если два аудиофайла одинаковы или один содержит другой.Java сравнить два аудиофайла с отпечатком пальца

Для этого я использую отпечатком 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()); 

конвертировать аудио в байтовый массив Я использую звук 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; 
} 

, но когда я исполню его, я стал на 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) 

Как сравнить 2 mp3-файла с отпечатками пальцев на Java?

ответ

0

Я никогда не делал каких-либо аудио материал в 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()); 
    } 
} 

Конечно, вы должны убедиться, что вы не конвертировать каждый файл заново при каждом запуске программы, то вы должны проверить, если уже существуют файлы WAV. Я пропустил этот шаг и уменьшил образец кода до минимальной рабочей версии.

+0

Сделав программу для сравнения более 1000 mp3 песни, это было бы плохим решением. – anatoli

+0

Пожалуйста, подберите свой комментарий, так оно и есть просто субъективно, но не очень полезно. «Плохое решение» почему? Из-за пространства для хранения? Использование процессора? Время, необходимое для конверсии? Кстати, не очень хороший стиль представляет код для одной пары файлов, не говоря уже о необходимости пакетной обработки вообще. Цитата: «Как я могу сравнить 2 mp3-файлов с отпечатками пальцев в Java?» Я правильно ответил на ваш вопрос. Если вы считаете, что это решение «плохо», возможно, вам нужно выбрать лучшую библиотеку, которая будет делать то, что вы представляете себе за один шаг. У меня нет волшебной палочки для вас. – kriegaex

+0

yay, моя вина. Я просто подумал, что есть более простое решение для сравнения mp3-файлов, так как есть довольно быстрые программы для сравнения по многим файлам. благодаря – anatoli

0

Для FingerprintSimilarityComputer (input1, input2) предполагается использовать отпечаток загруженных аудиоданных, а не самих загруженных аудиоданных.

В вашем случае, это должно быть:

// 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() 
+0

это не может использоваться для mp3-файлов, что мне нужно – anatoli

0

Может быть, мне не хватает точки, но если я прав вас понял, то это должно сделать:

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"); 
} 
+0

Является ли interessant idea (у меня в настоящее время есть аналогичное решение, чтобы сравнивать файлы), но тем не менее я хочу использовать отпечаток пальца – anatoli