1
0
mirror of https://github.com/mitb-archive/filebot synced 2024-08-13 17:03:45 -04:00

Call fpcalc for each individual file to work around all kinds of issues (Windows arg limits, fpcalc/ffmpeg issues, etc)

This commit is contained in:
Reinhard Pointner 2016-06-03 01:30:45 +08:00
parent 69a58b8185
commit 9d84ef7663

View File

@ -12,13 +12,11 @@ import java.io.InputStreamReader;
import java.lang.ProcessBuilder.Redirect; import java.lang.ProcessBuilder.Redirect;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.net.URL; import java.net.URL;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Comparator; import java.util.Comparator;
import java.util.EnumMap;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Scanner; import java.util.Scanner;
@ -59,20 +57,25 @@ public class AcoustIDClient implements MusicIdentificationService {
public Map<File, AudioTrack> lookup(Collection<File> files) throws Exception { public Map<File, AudioTrack> lookup(Collection<File> files) throws Exception {
Map<File, AudioTrack> results = new LinkedHashMap<File, AudioTrack>(); Map<File, AudioTrack> results = new LinkedHashMap<File, AudioTrack>();
if (files.size() > 0) { for (File file : files) {
for (Map<String, String> fp : fpcalc(files)) { Map<ChromaprintField, String> fp = fpcalc(file);
File file = new File(fp.get("FILE"));
int duration = Integer.parseInt(fp.get("DURATION")); // sanity check
String fingerprint = fp.get("FINGERPRINT"); if (!fp.containsKey(ChromaprintField.DURATION) || !fp.containsKey(ChromaprintField.FINGERPRINT))
continue;
int duration = Integer.parseInt(fp.get(ChromaprintField.DURATION));
String fingerprint = fp.get(ChromaprintField.FINGERPRINT);
// sanity check
if (duration < 10)
continue;
if (duration > 10 && fingerprint != null) {
String response = lookup(duration, fingerprint); String response = lookup(duration, fingerprint);
if (response != null && response.length() > 0) { if (response != null && response.length() > 0) {
results.put(file, parseResult(lookup(duration, fingerprint), duration)); results.put(file, parseResult(lookup(duration, fingerprint), duration));
} }
} }
}
}
return results; return results;
} }
@ -181,48 +184,35 @@ public class AcoustIDClient implements MusicIdentificationService {
return null; return null;
} }
public enum ChromaprintField {
FILE, FINGERPRINT, DURATION;
}
public String getChromaprintCommand() { public String getChromaprintCommand() {
// use fpcalc executable path as specified by the cmdline or default to "fpcalc" and let the shell figure it out // use fpcalc executable path as specified by the cmdline or default to "fpcalc" and let the shell figure it out
return System.getProperty("net.filebot.AcoustID.fpcalc", "fpcalc"); return System.getProperty("net.filebot.AcoustID.fpcalc", "fpcalc");
} }
public List<Map<String, String>> fpcalc(Collection<File> files) throws IOException, InterruptedException { public Map<ChromaprintField, String> fpcalc(File file) throws IOException, InterruptedException {
List<String> command = new ArrayList<String>(); Map<ChromaprintField, String> output = new EnumMap<ChromaprintField, String>(ChromaprintField.class);
command.add(getChromaprintCommand());
for (File f : files) {
command.add(f.getPath());
}
Process process = null; ProcessBuilder command = new ProcessBuilder(getChromaprintCommand(), file.getCanonicalPath());
try { Process process = command.redirectError(Redirect.INHERIT).start();
process = new ProcessBuilder(command).redirectError(Redirect.INHERIT).start();
} catch (Exception e) {
throw new IOException("Failed to exec fpcalc: " + e.getMessage());
}
Scanner scanner = new Scanner(new InputStreamReader(process.getInputStream(), UTF_8)); try (Scanner scanner = new Scanner(new InputStreamReader(process.getInputStream(), UTF_8))) {
LinkedList<Map<String, String>> results = new LinkedList<Map<String, String>>();
try {
while (scanner.hasNextLine()) { while (scanner.hasNextLine()) {
String[] value = EQUALS.split(scanner.nextLine(), 2); String[] value = EQUALS.split(scanner.nextLine(), 2);
if (value.length != 2) if (value.length == 2) {
continue; try {
output.put(ChromaprintField.valueOf(value[0]), value[1]);
if (results.isEmpty() || results.getLast().containsKey(value[0])) { } catch (Exception e) {
results.addLast(new HashMap<String, String>(3)); debug.warning(e::toString);
}
} }
results.getLast().put(value[0], value[1]);
} }
} finally {
scanner.close();
} }
if (process.waitFor() != 0) { return output;
throw new IOException("Failed to exec fpcalc: Exit code " + process.exitValue());
}
return results;
} }
private static class MostFieldsNotNull implements Comparator<Object> { private static class MostFieldsNotNull implements Comparator<Object> {