Made some progress with glide.

This commit is contained in:
Karim Abou Zeid 2016-01-02 01:19:36 +01:00
commit 3393136f2e
20 changed files with 361 additions and 186 deletions

View file

@ -1,34 +0,0 @@
package com.kabouzeid.gramophone.glide;
import android.graphics.drawable.Drawable;
import android.widget.ImageView;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.glide.palette.BitmapPaletteImageViewTarget;
import com.kabouzeid.gramophone.glide.palette.BitmapPaletteWrapper;
import com.kabouzeid.gramophone.util.ColorUtil;
public abstract class PhonographColoredImageViewTarget extends BitmapPaletteImageViewTarget {
public PhonographColoredImageViewTarget(ImageView view) {
super(view);
}
@Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
super.onLoadFailed(e, errorDrawable);
onColorReady(getDefaultBarColor());
}
@Override
public void onResourceReady(BitmapPaletteWrapper resource, GlideAnimation<? super BitmapPaletteWrapper> glideAnimation) {
super.onResourceReady(resource, glideAnimation);
onColorReady(ColorUtil.getColor(resource.getPalette(), getDefaultBarColor()));
}
private int getDefaultBarColor() {
return ColorUtil.resolveColor(getView().getContext(), R.attr.default_bar_color);
}
public abstract void onColorReady(int color);
}

View file

@ -1,32 +1,17 @@
package com.kabouzeid.gramophone.glide;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.widget.ImageView;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.glide.palette.BitmapPaletteTarget;
import com.kabouzeid.gramophone.glide.palette.BitmapPaletteWrapper;
import com.kabouzeid.gramophone.util.ColorUtil;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public abstract class PhonographColoredTarget extends SimpleTarget<BitmapPaletteWrapper> {
private Context context;
public PhonographColoredTarget(Context context) {
super();
init(context);
}
public PhonographColoredTarget(Context context, int width, int height) {
super(width, height);
init(context);
}
private void init(Context context) {
this.context = context;
public abstract class PhonographColoredTarget extends BitmapPaletteTarget {
public PhonographColoredTarget(ImageView view) {
super(view);
}
@Override
@ -37,11 +22,12 @@ public abstract class PhonographColoredTarget extends SimpleTarget<BitmapPalette
@Override
public void onResourceReady(BitmapPaletteWrapper resource, GlideAnimation<? super BitmapPaletteWrapper> glideAnimation) {
super.onResourceReady(resource, glideAnimation);
onColorReady(ColorUtil.getColor(resource.getPalette(), getDefaultBarColor()));
}
private int getDefaultBarColor() {
return ColorUtil.resolveColor(context, R.attr.default_bar_color);
return ColorUtil.resolveColor(getView().getContext(), R.attr.default_bar_color);
}
public abstract void onColorReady(int color);

View file

@ -5,6 +5,12 @@ import android.content.Context;
import com.bumptech.glide.Glide;
import com.bumptech.glide.GlideBuilder;
import com.bumptech.glide.module.GlideModule;
import com.kabouzeid.gramophone.glide.artistimage.ArtistImageLoader;
import com.kabouzeid.gramophone.glide.artistimage.ArtistImageRequest;
import com.kabouzeid.gramophone.glide.audiocover.SongCoverLoader;
import com.kabouzeid.gramophone.model.Song;
import java.io.InputStream;
/**
* @author Karim Abou Zeid (kabouzeid)
@ -17,6 +23,7 @@ public class PhonographGlideModule implements GlideModule {
@Override
public void registerComponents(Context context, Glide glide) {
glide.register(Song.class, InputStream.class, new SongCoverLoader.Factory());
glide.register(ArtistImageRequest.class, InputStream.class, new ArtistImageLoader.Factory(context));
}
}

View file

@ -0,0 +1,59 @@
package com.kabouzeid.gramophone.glide.artistimage;
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.data.HttpUrlFetcher;
import com.bumptech.glide.load.model.GlideUrl;
import com.kabouzeid.gramophone.lastfm.rest.LastFMRestClient;
import com.kabouzeid.gramophone.lastfm.rest.model.LastFmArtist;
import com.kabouzeid.gramophone.util.LastFMUtil;
import com.kabouzeid.gramophone.util.MusicUtil;
import java.io.InputStream;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class ArtistImageFetcher implements DataFetcher<InputStream> {
private final LastFMRestClient lastFMRestClient;
private final ArtistImageRequest model;
private HttpUrlFetcher urlFetcher;
private volatile boolean isCancelled;
public ArtistImageFetcher(LastFMRestClient lastFMRestClient, ArtistImageRequest model) {
this.lastFMRestClient = lastFMRestClient;
this.model = model;
}
@Override
public String getId() {
return model.artistName;
}
@Override
public InputStream loadData(Priority priority) throws Exception {
if (MusicUtil.isArtistNameUnknown(model.artistName)) return null;
LastFmArtist lastFmArtist = lastFMRestClient.getApiService().getArtistInfo(model.artistName, model.forceDownload ? "no-cache" : null).execute().body();
if (isCancelled) return null;
urlFetcher = new HttpUrlFetcher(new GlideUrl(LastFMUtil.getLargestArtistImageUrl(lastFmArtist.getArtist().getImage())));
return urlFetcher.loadData(priority);
}
@Override
public void cleanup() {
if (urlFetcher != null) {
urlFetcher.cleanup();
}
}
@Override
public void cancel() {
isCancelled = true;
if (urlFetcher != null) {
urlFetcher.cancel();
}
}
}

View file

@ -0,0 +1,62 @@
package com.kabouzeid.gramophone.glide.artistimage;
import android.content.Context;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.model.GenericLoaderFactory;
import com.bumptech.glide.load.model.ModelLoader;
import com.bumptech.glide.load.model.ModelLoaderFactory;
import com.bumptech.glide.load.model.stream.StreamModelLoader;
import com.kabouzeid.gramophone.lastfm.rest.LastFMRestClient;
import java.io.InputStream;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class ArtistImageLoader implements StreamModelLoader<ArtistImageRequest> {
private LastFMRestClient lastFMRestClient;
public ArtistImageLoader(LastFMRestClient lastFMRestClient) {
this.lastFMRestClient = lastFMRestClient;
}
@Override
public DataFetcher<InputStream> getResourceFetcher(ArtistImageRequest model, int width, int height) {
return new ArtistImageFetcher(lastFMRestClient, model);
}
public static class Factory implements ModelLoaderFactory<ArtistImageRequest, InputStream> {
private static volatile LastFMRestClient internalClient;
private LastFMRestClient client;
private static LastFMRestClient getInternalClient(Context context) {
if (internalClient == null) {
synchronized (Factory.class) {
if (internalClient == null) {
internalClient = new LastFMRestClient(context);
}
}
}
return internalClient;
}
/**
* Constructor for a new Factory that runs requests using a static singleton client.
*/
public Factory(Context context) {
client = getInternalClient(context);
}
@Override
public ModelLoader<ArtistImageRequest, InputStream> build(Context context, GenericLoaderFactory factories) {
return new ArtistImageLoader(client);
}
@Override
public void teardown() {
}
}
}

View file

@ -0,0 +1,14 @@
package com.kabouzeid.gramophone.glide.artistimage;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class ArtistImageRequest {
public final String artistName;
public final boolean forceDownload;
public ArtistImageRequest(String artistName, boolean forceDownload) {
this.artistName = artistName;
this.forceDownload = forceDownload;
}
}

View file

@ -0,0 +1,82 @@
package com.kabouzeid.gramophone.glide.audiocover;
import android.content.Context;
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.data.DataFetcher;
import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.util.MusicUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class AudioFileCoverFetcher implements DataFetcher<InputStream> {
private final Song model;
private FileInputStream stream;
private Context context;
public AudioFileCoverFetcher(Context context, Song model) {
this.context = context;
this.model = model;
}
@Override
public String getId() {
return model.data;
}
@Override
public InputStream loadData(Priority priority) throws Exception {
// MediaMetadataRetriever retriever = new MediaMetadataRetriever();
// try {
// retriever.setDataSource(model.data);
// byte[] picture = retriever.getEmbeddedPicture();
// if (picture != null) {
// return new ByteArrayInputStream(picture);
// } else {
// return fallback(model.data);
// }
// } finally {
// retriever.release();
// }
return context.getContentResolver().openInputStream(MusicUtil.getAlbumArtUri(model.albumId));
}
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
}
}

View file

@ -0,0 +1,41 @@
package com.kabouzeid.gramophone.glide.audiocover;
import android.content.Context;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.model.GenericLoaderFactory;
import com.bumptech.glide.load.model.ModelLoader;
import com.bumptech.glide.load.model.ModelLoaderFactory;
import com.bumptech.glide.load.model.stream.StreamModelLoader;
import com.kabouzeid.gramophone.model.Song;
import java.io.InputStream;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class SongCoverLoader implements StreamModelLoader<Song> {
private Context context;
public SongCoverLoader(Context context) {
this.context = context;
}
@Override
public DataFetcher<InputStream> getResourceFetcher(Song model, int width, int height) {
return new AudioFileCoverFetcher(context, model);
}
public static class Factory implements ModelLoaderFactory<Song, InputStream> {
@Override
public ModelLoader<Song, InputStream> build(Context context, GenericLoaderFactory factories) {
return new SongCoverLoader(context);
}
@Override
public void teardown() {
}
}
}

View file

@ -4,8 +4,8 @@ import android.widget.ImageView;
import com.bumptech.glide.request.target.ImageViewTarget;
public class BitmapPaletteImageViewTarget extends ImageViewTarget<BitmapPaletteWrapper> {
public BitmapPaletteImageViewTarget(ImageView view) {
public class BitmapPaletteTarget extends ImageViewTarget<BitmapPaletteWrapper> {
public BitmapPaletteTarget(ImageView view) {
super(view);
}