Refactored and improved album art detection and extraction.
This commit is contained in:
parent
1d860760d6
commit
005e116505
@ -32,6 +32,9 @@ public class PlayerGUI {
|
|||||||
public PlayerGUI() {
|
public PlayerGUI() {
|
||||||
DatabaseManager.init();
|
DatabaseManager.init();
|
||||||
populateLibrary(new TreeMap<>(Gateway.listAllSongsGroupedByAlbum().get()));
|
populateLibrary(new TreeMap<>(Gateway.listAllSongsGroupedByAlbum().get()));
|
||||||
|
libraryView.setRootVisible(false);
|
||||||
|
libraryView.setToggleClickCount(1);
|
||||||
|
libraryView.setCellRenderer(new LibraryTreeCellRenderer());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetTree() {
|
private void resetTree() {
|
||||||
@ -39,9 +42,6 @@ public class PlayerGUI {
|
|||||||
DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();
|
DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();
|
||||||
DefaultTreeModel treeModel = new DefaultTreeModel(rootNode);
|
DefaultTreeModel treeModel = new DefaultTreeModel(rootNode);
|
||||||
libraryView.setModel(treeModel);
|
libraryView.setModel(treeModel);
|
||||||
libraryView.setRootVisible(false);
|
|
||||||
libraryView.setToggleClickCount(1);
|
|
||||||
libraryView.setCellRenderer(new LibraryTreeCellRenderer());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void populateLibrary(Map<Album, List<Song>> libraryData) {
|
private void populateLibrary(Map<Album, List<Song>> libraryData) {
|
||||||
|
@ -73,7 +73,7 @@ public class Gateway {
|
|||||||
session.beginTransaction();
|
session.beginTransaction();
|
||||||
Optional<Album> albumObj = getOneAlbum(metadata.album);
|
Optional<Album> albumObj = getOneAlbum(metadata.album);
|
||||||
if (!albumObj.isPresent()) {
|
if (!albumObj.isPresent()) {
|
||||||
Album album = new Album(metadata.album);
|
Album album = new Album(metadata.album, metadata.artwork);
|
||||||
albumObj = Optional.of(album);
|
albumObj = Optional.of(album);
|
||||||
session.save(album);
|
session.save(album);
|
||||||
}
|
}
|
||||||
@ -87,16 +87,4 @@ public class Gateway {
|
|||||||
session.getTransaction().commit();
|
session.getTransaction().commit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void updateAllAlbumArt() {
|
|
||||||
try (Session session = DatabaseManager.getInstance().getSession()) {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
List<Album> albums = session.createCriteria(Album.class).list();
|
|
||||||
session.beginTransaction();
|
|
||||||
albums.forEach(Album::refreshAlbumArt);
|
|
||||||
session.getTransaction().commit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,7 @@ package musicplayer.model;
|
|||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -25,14 +23,18 @@ public class Album implements Comparable<Album> {
|
|||||||
@Lob
|
@Lob
|
||||||
@Column(name = "art", nullable = true, length = 10000)
|
@Column(name = "art", nullable = true, length = 10000)
|
||||||
private byte[] art;
|
private byte[] art;
|
||||||
@Transient
|
|
||||||
private static int imageScaleToSize = 50;
|
|
||||||
|
|
||||||
protected Album() {
|
protected Album() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Album(String name){
|
public Album(String name){
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.art = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Album(String name, byte[] art) {
|
||||||
|
this.name = name;
|
||||||
|
this.art = art;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
@ -52,20 +54,6 @@ public class Album implements Comparable<Album> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transient
|
|
||||||
public void refreshAlbumArt() {
|
|
||||||
Optional<BufferedImage> artGet = songs.iterator().next().getAlbumArt();
|
|
||||||
if (artGet.isPresent()) {
|
|
||||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
|
||||||
ImageIO.write(convertToBufferedImage(artGet.get().getScaledInstance(imageScaleToSize, imageScaleToSize, Image.SCALE_SMOOTH)), "jpg", baos);
|
|
||||||
baos.flush();
|
|
||||||
art = baos.toByteArray();
|
|
||||||
} catch (IOException e) {
|
|
||||||
art = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("MethodWithMultipleReturnPoints")
|
@SuppressWarnings("MethodWithMultipleReturnPoints")
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
@ -85,17 +73,6 @@ public class Album implements Comparable<Album> {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transient
|
|
||||||
public static BufferedImage convertToBufferedImage(Image image) {
|
|
||||||
BufferedImage newImage = new BufferedImage(
|
|
||||||
image.getWidth(null), image.getHeight(null),
|
|
||||||
BufferedImage.TYPE_INT_ARGB);
|
|
||||||
Graphics2D g = newImage.createGraphics();
|
|
||||||
g.drawImage(image, 0, 0, null);
|
|
||||||
g.dispose();
|
|
||||||
return newImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,13 @@ package musicplayer.model;
|
|||||||
import org.jaudiotagger.tag.FieldKey;
|
import org.jaudiotagger.tag.FieldKey;
|
||||||
import org.jaudiotagger.tag.Tag;
|
import org.jaudiotagger.tag.Tag;
|
||||||
|
|
||||||
import java.io.File;
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal class representing metadata extracted from a music file.
|
* Internal class representing metadata extracted from a music file.
|
||||||
@ -15,6 +21,9 @@ public class ExtractedMetadata {
|
|||||||
public final String genre;
|
public final String genre;
|
||||||
public final String songFile;
|
public final String songFile;
|
||||||
public final String trackNumber;
|
public final String trackNumber;
|
||||||
|
public final byte[] artwork;
|
||||||
|
|
||||||
|
static final String albumArtRegex = ".*(Cover|Folder|cover|folder)\\.(jpg|png)";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param audioTags jaudiotagger tag data.
|
* @param audioTags jaudiotagger tag data.
|
||||||
@ -27,5 +36,41 @@ public class ExtractedMetadata {
|
|||||||
this.artist = audioTags.getFirst(FieldKey.ARTIST);
|
this.artist = audioTags.getFirst(FieldKey.ARTIST);
|
||||||
this.genre = audioTags.getFirst(FieldKey.GENRE);
|
this.genre = audioTags.getFirst(FieldKey.GENRE);
|
||||||
this.songFile = songFile.getAbsolutePath();
|
this.songFile = songFile.getAbsolutePath();
|
||||||
|
byte[] tmpArt = null;
|
||||||
|
try {
|
||||||
|
tmpArt = audioTags.getFirstArtwork().getBinaryData();
|
||||||
|
BufferedImage image = ImageIO.read(new ByteArrayInputStream(tmpArt));
|
||||||
|
tmpArt = convertImageToBytes(image);
|
||||||
|
} catch (IOException | NullPointerException e) {
|
||||||
|
try {
|
||||||
|
Path dir = songFile.toPath().getParent();
|
||||||
|
Optional<Path> imageFile = Files.walk(dir).filter(x -> x.toString().matches(albumArtRegex)).findFirst();
|
||||||
|
if (imageFile.isPresent()) {
|
||||||
|
Image actualImage = ImageIO.read(imageFile.get().toFile());
|
||||||
|
tmpArt = convertImageToBytes(actualImage);
|
||||||
|
}
|
||||||
|
} catch (IOException ignored) {}
|
||||||
|
}
|
||||||
|
artwork = tmpArt;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] convertImageToBytes(Image image){
|
||||||
|
int imageScaleToSize = 50;
|
||||||
|
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()){
|
||||||
|
ImageIO.write(convertToBufferedImage(image.getScaledInstance(imageScaleToSize, imageScaleToSize, Image.SCALE_SMOOTH)), "jpg", baos);
|
||||||
|
baos.flush();
|
||||||
|
return baos.toByteArray();
|
||||||
|
} catch (IOException ignored) {}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BufferedImage convertToBufferedImage(Image image) {
|
||||||
|
BufferedImage newImage = new BufferedImage(
|
||||||
|
image.getWidth(null), image.getHeight(null),
|
||||||
|
BufferedImage.TYPE_INT_ARGB);
|
||||||
|
Graphics2D g = newImage.createGraphics();
|
||||||
|
g.drawImage(image, 0, 0, null);
|
||||||
|
g.dispose();
|
||||||
|
return newImage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user