Hi, i want to load album art from audio file for my music app can any one help to do it. i was able get file path but when i parse through the Uri.parse(filePath) method its not loading
What's in the filePath variable (log it)? What's the error you're getting (add .listener())? Please share some code too.
The best way to attack this is probably a custom model loader for audio files (class AudioCover { String path }), use a MediaMetadataRetreiver to get the cover art as byte[] and return a ByteArrayInputStream so Glide can do the rest. See ByteArrayFetcher as an example.
i understand little bit, but can you help me, how to get album art from using MediaStore and load using glide in listview
File music = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
// Tested with music from Windows 7's c:\Users\Public\Music\Sample Music
String filePath = new File(music, "Maid with the Flaxen Hair.mp3").getAbsolutePath();
Glide
.with(context)
.load(new AudioCover(filePath))
.placeholder(R.drawable.loading_cover)
.error(R.drawable.missing_cover)
.into(imageView)
;
public class AudioCover {
final String path;
public AudioCover(String path) {
this.path = path;
}
}
// TODO https://github.com/bumptech/glide/wiki/Configuration#lazy-configuration
public class AudioCoverModule implements GlideModule {
@Override public void applyOptions(Context context, GlideBuilder builder) {
}
@Override public void registerComponents(Context context, Glide glide) {
glide.register(AudioCover.class, InputStream.class, new AudioCoverLoader.Factory());
}
}
class AudioCoverLoader implements StreamModelLoader<AudioCover> {
@Override public DataFetcher<InputStream> getResourceFetcher(AudioCover model, int width, int height) {
return new AudioCoverFetcher(model);
}
static class Factory implements ModelLoaderFactory<AudioCover, InputStream> {
@Override public ModelLoader<AudioCover, InputStream> build(Context context, GenericLoaderFactory factories) {
return new AudioCoverLoader();
}
@Override public void teardown() {
}
}
}
class AudioCoverFetcher implements DataFetcher<InputStream> {
private final AudioCover model;
private FileInputStream stream;
public AudioCoverFetcher(AudioCover model) {
this.model = model;
}
@Override public String getId() {
return model.path;
}
@Override public InputStream loadData(Priority priority) throws Exception {
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
try {
retriever.setDataSource(model.path);
byte[] picture = retriever.getEmbeddedPicture();
if (picture != null) {
return new ByteArrayInputStream(picture);
} else {
return fallback(model.path);
}
} finally {
retriever.release();
}
}
private static final String[] FALLBACKS = {"cover.jpg", "album.jpg", "folder.jpg"};
private InputStream fallback(String path) throws FileNotFoundException {
File parent = new File(path).getParentFile();
for (String fallback : FALLBACKS) {
// TODO make it smarter by enumerating folder contents and filtering for files
// example algorithm for that: http://askubuntu.com/questions/123612/how-do-i-set-album-artwork
File cover = new File(parent, fallback);
if (cover.exists()) {
return stream = new FileInputStream(cover);
}
}
return null;
}
@Override public void cleanup() {
// already cleaned up in loadData and ByteArrayInputStream will be GC'd
if (stream != null) {
try {
stream.close();
} catch (IOException ignore) {
// can't do much about it
}
}
}
@Override public void cancel() {
// cannot cancel
}
}
Thanks you very much for code
@TWiStErRob just wondering, how would you implement a signature in this case?
@kabouzeid same as any local File, use the last modification date of the file. Hopefully the tag editor will change the date. If you want to be really sure you can also mix in the file size.
The problematic part I guess is the fallbacks, after some quick thoughts I would go something like this:
// create a list of AudioCover objects and use those in the adapter,
// so signature can be cached at least while scrolling the list
AudioCover model = new AudioCover(filePath); // this involves I/O
Then at binding:
AudioCover model = list.get(position);
Glide
.with(context)
.load(model)
.signature(model.signature)
class AudioCover {
final String path;
final AudioCoverSignature signature;
public AudioCover(String path) {
this.path = path;
this.signature = new AudioCoverSignature(path);
// this list creation should already be in the background (Loader?),
// so it's fine to call blocking I/O there
signature.refresh();
}
}
class AudioCoverSignature implements Key {
private static final int AUDIO_SIZE = 2 * Long.SIZE / 8;
private static final int FALLBACK_SIZE = 2 * Long.SIZE / 8;
private final File file;
private final ByteBuffer signature =
ByteBuffer.allocate(AUDIO_SIZE + AudioCoverFetcher.FALLBACKS.length * FALLBACK_SIZE);
public AudioCoverSignature(String path) {
this.file = new File(path);
}
public void refresh() {
File parent = file.getParentFile();
signature.putLong(parent.lastModified());
signature.putLong(parent.length());
for (String fallback : AudioCoverFetcher.FALLBACKS) {
File cover = new File(parent, fallback);
// no need for File.exists() or File.isFile() checks, both fall back to 0 if invalid
signature.putLong(cover.lastModified());
signature.putLong(cover.length());
}
}
@Override public void updateDiskCacheKey(MessageDigest messageDigest) throws UnsupportedEncodingException {
messageDigest.update(signature);
}
}
This way you are in control when to pick up any changes: again, preferably in the background.
@TWiStErRob wow, thanks for the detailed answer sir! This helped a lot.
Hello, I follow glide-support/src/glide3/java/com/bumptech/glide/supportapp/github/_699_mp3_cover/ ,but no success ,can you help me.
@lougw need a little bit more than "it doesn't work".
First step is always https://github.com/bumptech/glide/wiki/Debugging-and-Error-Handling, also debug your code to see which path is taken in your custom classes.
@TWiStErRob I'm sorry, it's my problem,my path is wrong ,Thanks you very much !!
@TWiStErRob is glide capable of loading network video tumbnail..?? if yes guide me how to do it.
thanks
@yogarajsubu https://github.com/bumptech/glide/issues/1582
@h4h13 i want to Load Video Thumbnail from url.
I tried above code but not getting results.
can you post your code of loading video thumbnail from URL.
Thanks in advance
@jayappmobi there are numerous issues stating that video loading is not possible / highly discouraged: e.g. https://github.com/bumptech/glide/issues/862
The above code was designed for local Files.
Thanks
@TWiStErRob
i will try some other thing.
@TWiStErRob Tried your answer you commented above but it is giving this error
java.lang.IllegalArgumentException: Unknown type class com.package.app.Classes.AudioCover.
You must provide a Model of a type for which there is a registered ModelLoader,
if you are using a custom model, you must first call Glide#register with a ModelLoaderFactory for your custom model class
at com.bumptech.glide.RequestManager.loadGeneric(RequestManager.java:629)
at com.bumptech.glide.RequestManager.load(RequestManager.java:598)
Can You please help
@rk8339811 Updated my answer to call out (TODO) that you need to register the module.
private static final int AUDIO_SIZE = Long.SIZE / 8; // mistake here private static final int FALLBACK_SIZE = 2 * Long.SIZE / 8; private final File file; private final ByteBuffer signature = ByteBuffer.allocate(AUDIO_SIZE + AudioCoverFetcher.FALLBACKS.length * FALLBACK_SIZE);
int AUDIO_SIZE = 2 * Long.SIZE / 8
because
signature.putLong(parent.lastModified());
signature.putLong(parent.length());
Thanks @TWiStErRob . This is really helpful.
This way you are in control when to pick up any changes: again, preferably in the background.
Anyone have Glide 4.x updated code for for album art?
Up: solved using this code: https://stackoverflow.com/questions/57831679/glide-load-audio-cover-art-using-custom-medialoader-and-metadataretriever
Anyone have Glide 4.x updated code for for album art?
Up: solved using this code: https://stackoverflow.com/questions/57831679/glide-load-audio-cover-art-using-custom-medialoader-and-metadataretriever
Hey, Can you help me how you managed to fix this code because it is not working with v4 in mine and throwing a model error

Edit: Nvm, I found the problem and answered the question as well
@erva just noticed, thanks for flagging, updated original.
Wait, Glide can load images from music files (album art) ? How? Where can I read about it? Is there a sample?
Does it work even with a file-path? And it fetches the HQ one, and not just the thumbnail ?
Most helpful comment