* improved music data mappings for acoustid response
This commit is contained in:
parent
0a73d7d98d
commit
42d5175b54
|
@ -1,6 +1,5 @@
|
|||
package net.filebot.web;
|
||||
|
||||
import static java.util.Arrays.*;
|
||||
import static net.filebot.web.WebRequest.*;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -11,7 +10,6 @@ import java.net.URL;
|
|||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
|
@ -21,6 +19,7 @@ import java.util.Scanner;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
|
@ -107,11 +106,13 @@ public class AcoustIDClient implements MusicIdentificationService {
|
|||
}
|
||||
|
||||
private static Object[] array(Object node, String key) {
|
||||
return ((JsonObject<?, ?>) ((Map<?, ?>) node).get(key)).getArray();
|
||||
Object value = ((Map<?, ?>) node).get(key);
|
||||
return value == null ? null : ((JsonObject<?, ?>) value).getArray();
|
||||
}
|
||||
|
||||
private static Map<?, ?> firstMap(Object node, String key) {
|
||||
return (Map<?, ?>) array(node, key)[0];
|
||||
Object[] values = array(node, key);
|
||||
return values == null || values.length == 0 ? null : (Map<?, ?>) values[0];
|
||||
}
|
||||
|
||||
private static Integer integer(Object node, String key) {
|
||||
|
@ -119,86 +120,92 @@ public class AcoustIDClient implements MusicIdentificationService {
|
|||
return value == null ? null : new Integer(value.toString());
|
||||
}
|
||||
|
||||
private static String string(Object node, String key) {
|
||||
Object value = ((Map<?, ?>) node).get(key);
|
||||
return value == null ? null : value.toString();
|
||||
}
|
||||
|
||||
public AudioTrack parseResult(String json, final int targetDuration) throws IOException {
|
||||
Map<?, ?> data = (Map<?, ?>) JsonReader.jsonToMaps(json);
|
||||
|
||||
if (!data.get("status").equals("ok")) {
|
||||
throw new IOException("acoustid responded with error: " + data.get("status"));
|
||||
}
|
||||
|
||||
try {
|
||||
for (Object result : array(data, "results")) {
|
||||
try {
|
||||
// pick most likely matching recording
|
||||
Object[] recordings = array(result, "recordings");
|
||||
sort(recordings, new Comparator<Object>() {
|
||||
return Stream.of(array(result, "recordings")).sorted((Object o1, Object o2) -> {
|
||||
Integer i1 = integer(o1, "duration");
|
||||
Integer i2 = integer(o2, "duration");
|
||||
return Double.compare(i1 == null ? Double.NaN : Math.abs(i1 - targetDuration), i2 == null ? Double.NaN : Math.abs(i2 - targetDuration));
|
||||
}).map((Object o) -> {
|
||||
Map<?, ?> recording = (Map<?, ?>) o;
|
||||
try {
|
||||
Map<?, ?> releaseGroup = firstMap(recording, "releasegroups");
|
||||
if (releaseGroup == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(Object o1, Object o2) {
|
||||
Integer i1 = integer(o1, "duration");
|
||||
Integer i2 = integer(o2, "duration");
|
||||
return Double.compare(i1 == null ? Double.NaN : Math.abs(i1 - targetDuration), i2 == null ? Double.NaN : Math.abs(i2 - targetDuration));
|
||||
}
|
||||
});
|
||||
String artist = (String) firstMap(recording, "artists").get("name");
|
||||
String title = (String) recording.get("title");
|
||||
|
||||
Map<?, ?> recording = (Map<?, ?>) recordings[0];
|
||||
String artist = (String) firstMap(recording, "artists").get("name");
|
||||
String title = (String) recording.get("title");
|
||||
AudioTrack audioTrack = new AudioTrack(artist, title, null);
|
||||
audioTrack.mbid = string(result, "id");
|
||||
|
||||
String type = string(releaseGroup, "type");
|
||||
Object[] secondaryTypes = array(releaseGroup, "secondarytypes");
|
||||
Object[] releases = array(releaseGroup, "releases");
|
||||
|
||||
if (releases == null || secondaryTypes != null || (secondaryTypes != null && secondaryTypes.length > 0) || (type == null || !type.equals("Album"))) {
|
||||
return null; // ignore music that doesn't belong to a proper album
|
||||
}
|
||||
|
||||
AudioTrack audioTrack = new AudioTrack(artist, title, null);
|
||||
try {
|
||||
Map<?, ?> releaseGroup = firstMap(recording, "releasegroups");
|
||||
Object[] releases = array(releaseGroup, "releases");
|
||||
if (releases != null) {
|
||||
for (Object it : releases) {
|
||||
AudioTrack thisRelease = audioTrack.clone();
|
||||
Map<?, ?> release = (Map<?, ?>) it;
|
||||
Map<?, ?> date = (Map<?, ?>) release.get("date");
|
||||
try {
|
||||
AudioTrack thisRelease = new AudioTrack(artist, title, null);
|
||||
Map<?, ?> release = (Map<?, ?>) it;
|
||||
Map<?, ?> date = (Map<?, ?>) release.get("date");
|
||||
try {
|
||||
thisRelease.albumReleaseDate = new SimpleDate(integer(date, "year"), integer(date, "month"), integer(date, "day"));
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
if (thisRelease.albumReleaseDate == null || thisRelease.albumReleaseDate.getTimeStamp() >= (audioTrack.albumReleaseDate == null ? Long.MAX_VALUE : audioTrack.albumReleaseDate.getTimeStamp())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Map<?, ?> medium = firstMap(release, "mediums");
|
||||
thisRelease.mediumIndex = integer(medium, "position");
|
||||
thisRelease.mediumCount = integer(release, "medium_count");
|
||||
|
||||
Map<?, ?> track = firstMap(medium, "tracks");
|
||||
thisRelease.trackIndex = integer(track, "position");
|
||||
thisRelease.trackCount = integer(medium, "track_count");
|
||||
|
||||
try {
|
||||
thisRelease.album = release.get("title").toString();
|
||||
} catch (Exception e) {
|
||||
thisRelease.album = (String) releaseGroup.get("title");
|
||||
}
|
||||
try {
|
||||
thisRelease.albumArtist = (String) firstMap(releaseGroup, "artists").get("name");
|
||||
} catch (Exception e) {
|
||||
thisRelease.albumArtist = null;
|
||||
}
|
||||
thisRelease.trackTitle = (String) track.get("title");
|
||||
|
||||
if (!"Various Artists".equalsIgnoreCase(thisRelease.albumArtist) && (thisRelease.album == null || !thisRelease.album.contains("Greatest Hits"))) {
|
||||
// full info audio track
|
||||
return thisRelease;
|
||||
}
|
||||
thisRelease.albumReleaseDate = new SimpleDate(integer(date, "year"), integer(date, "month"), integer(date, "day"));
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(AcoustIDClient.class.getName()).log(Level.WARNING, e.toString(), e);
|
||||
thisRelease.albumReleaseDate = null;
|
||||
}
|
||||
|
||||
if (thisRelease.albumReleaseDate == null || thisRelease.albumReleaseDate.getTimeStamp() >= (audioTrack.albumReleaseDate == null ? Long.MAX_VALUE : audioTrack.albumReleaseDate.getTimeStamp())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Map<?, ?> medium = firstMap(release, "mediums");
|
||||
thisRelease.mediumIndex = integer(medium, "position");
|
||||
thisRelease.mediumCount = integer(release, "medium_count");
|
||||
|
||||
Map<?, ?> track = firstMap(medium, "tracks");
|
||||
thisRelease.trackIndex = integer(track, "position");
|
||||
thisRelease.trackCount = integer(medium, "track_count");
|
||||
|
||||
try {
|
||||
thisRelease.album = release.get("title").toString();
|
||||
} catch (Exception e) {
|
||||
thisRelease.album = (String) releaseGroup.get("title");
|
||||
}
|
||||
try {
|
||||
thisRelease.albumArtist = (String) firstMap(releaseGroup, "artists").get("name");
|
||||
} catch (Exception e) {
|
||||
thisRelease.albumArtist = null;
|
||||
}
|
||||
thisRelease.trackTitle = (String) track.get("title");
|
||||
|
||||
if (!"Various Artists".equalsIgnoreCase(thisRelease.albumArtist) && (thisRelease.album == null || !thisRelease.album.contains("Greatest Hits"))) {
|
||||
// full info audio track
|
||||
return thisRelease;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(AcoustIDClient.class.getName()).log(Level.WARNING, e.toString(), e);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(AcoustIDClient.class.getName()).log(Level.WARNING, e.toString(), e);
|
||||
}
|
||||
|
||||
// basic info audio track
|
||||
return audioTrack;
|
||||
return null;
|
||||
}).filter(o -> o != null).findFirst().get();
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
|
||||
package net.filebot.web;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
public class AudioTrack implements Serializable {
|
||||
|
||||
|
||||
protected String artist;
|
||||
protected String title;
|
||||
protected String album;
|
||||
|
||||
|
||||
protected String albumArtist;
|
||||
protected String trackTitle;
|
||||
protected SimpleDate albumReleaseDate;
|
||||
|
@ -18,12 +15,12 @@ public class AudioTrack implements Serializable {
|
|||
protected Integer mediumCount;
|
||||
protected Integer trackIndex;
|
||||
protected Integer trackCount;
|
||||
|
||||
|
||||
|
||||
protected String mbid; // MusicBrainz Identifier
|
||||
|
||||
protected AudioTrack() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public AudioTrack(AudioTrack other) {
|
||||
this.artist = other.artist;
|
||||
this.title = other.title;
|
||||
|
@ -35,17 +32,16 @@ public class AudioTrack implements Serializable {
|
|||
this.mediumCount = other.mediumCount;
|
||||
this.trackIndex = other.trackIndex;
|
||||
this.trackCount = other.trackCount;
|
||||
this.mbid = other.mbid;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public AudioTrack(String artist, String title, String album) {
|
||||
this.artist = artist;
|
||||
this.title = title;
|
||||
this.album = album;
|
||||
}
|
||||
|
||||
|
||||
public AudioTrack(String artist, String title, String album, String albumArtist, String trackTitle, SimpleDate albumReleaseDate, Integer mediumIndex, Integer mediumCount, Integer trackIndex, Integer trackCount) {
|
||||
|
||||
public AudioTrack(String artist, String title, String album, String albumArtist, String trackTitle, SimpleDate albumReleaseDate, Integer mediumIndex, Integer mediumCount, Integer trackIndex, Integer trackCount, String mbid) {
|
||||
this.artist = artist;
|
||||
this.title = title;
|
||||
this.album = album;
|
||||
|
@ -56,68 +52,61 @@ public class AudioTrack implements Serializable {
|
|||
this.mediumCount = mediumCount;
|
||||
this.trackIndex = trackIndex;
|
||||
this.trackCount = trackCount;
|
||||
this.mbid = mbid;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getArtist() {
|
||||
return artist;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getAlbum() {
|
||||
return album;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getAlbumArtist() {
|
||||
return albumArtist;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getTrackTitle() {
|
||||
return trackTitle;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public SimpleDate getAlbumReleaseDate() {
|
||||
return albumReleaseDate;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Integer getMedium() {
|
||||
return mediumIndex;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Integer getMediumCount() {
|
||||
return mediumCount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Integer getTrack() {
|
||||
return trackIndex;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Integer getTrackCount() {
|
||||
return trackCount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getMBID() {
|
||||
return mbid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AudioTrack clone() {
|
||||
return new AudioTrack(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s - %s", getArtist(), getTitle());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ public class ID3Lookup implements MusicIdentificationService {
|
|||
}
|
||||
|
||||
if (artist.length() > 0 && title.length() > 0 && album.length() > 0) {
|
||||
info.put(f, new AudioTrack(artist, title, album, albumArtist, trackTitle, albumReleaseDate, mediumIndex, mediumCount, trackIndex, trackCount));
|
||||
info.put(f, new AudioTrack(artist, title, album, albumArtist, trackTitle, albumReleaseDate, mediumIndex, mediumCount, trackIndex, trackCount, null));
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
Logger.getLogger(ID3Lookup.class.getName()).log(Level.WARNING, e.getMessage(), e);
|
||||
|
|
Loading…
Reference in New Issue