Commit b0b6400f authored by Geoffrey Métais's avatar Geoffrey Métais
Browse files

Medialibrary API upgrade

parent f240566d
......@@ -4,7 +4,7 @@
# ARGUMENTS #
#############
MEDIALIBRARY_HASH=c400b97
MEDIALIBRARY_HASH=83d7198
while [ $# -gt 0 ]; do
case $1 in
......
......@@ -505,10 +505,11 @@ medialibrary::Query<medialibrary::IFolder> AndroidMediaLibrary::subFolders(int64
}
void
AndroidMediaLibrary::requestThumbnail( int64_t media_id )
AndroidMediaLibrary::requestThumbnail( int64_t media_id, medialibrary::ThumbnailSizeType sizeType, uint32_t desiredWidth,
uint32_t desiredHeight, float position )
{
medialibrary::MediaPtr media = p_ml->media(media_id);
if (media != nullptr) p_ml->requestThumbnail(media);
if (media != nullptr) media->requestThumbnail(sizeType, desiredWidth, desiredHeight, position);
}
void
......@@ -900,7 +901,7 @@ void AndroidMediaLibrary::onBackgroundTasksIdleChanged( bool isIdle )
}
}
void AndroidMediaLibrary::onMediaThumbnailReady( medialibrary::MediaPtr media, bool success )
void AndroidMediaLibrary::onMediaThumbnailReady( medialibrary::MediaPtr media, medialibrary::ThumbnailSizeType sizeType, bool success )
{
JNIEnv *env = getEnv();
if (env != NULL && weak_thiz)
......
......@@ -105,7 +105,8 @@ public:
bool playlistRemove(int64_t playlistId, unsigned int position);
bool PlaylistDelete( int64_t playlistId );
void requestThumbnail( int64_t media_id );
void requestThumbnail( int64_t media_id, medialibrary::ThumbnailSizeType sizeType, uint32_t desiredWidth,
uint32_t desiredHeight, float position );
void onMediaAdded( std::vector<medialibrary::MediaPtr> media );
void onMediaModified( std::vector<medialibrary::MediaPtr> media ) ;
......@@ -138,7 +139,8 @@ public:
void onEntryPointRemoved( const std::string& entryPoint, bool success );
void onParsingStatsUpdated( uint32_t percent);
void onBackgroundTasksIdleChanged( bool isIdle );
void onMediaThumbnailReady( medialibrary::MediaPtr media, bool success );
void onMediaThumbnailReady(medialibrary::MediaPtr media, medialibrary::ThumbnailSizeType sizeType,
bool success );
private:
void jni_detach_thread(void *data);
......
......@@ -949,10 +949,11 @@ playlistCreate(JNIEnv* env, jobject thiz, jstring name)
}
void
requestThumbnail(JNIEnv* env, jobject thiz, jlong mediaId)
requestThumbnail(JNIEnv* env, jobject thiz, jobject medialibrary, jlong mediaId, medialibrary::ThumbnailSizeType sizeType, uint32_t desiredWidth,
uint32_t desiredHeight, float position)
{
AndroidMediaLibrary *aml = MediaLibrary_getInstance(env, thiz);
aml->requestThumbnail(mediaId);
AndroidMediaLibrary *aml = MediaLibrary_getInstance(env, medialibrary);
aml->requestThumbnail(mediaId, sizeType, desiredWidth, desiredHeight, position);
}
/*
......@@ -1469,7 +1470,7 @@ setMediaThumbnail(JNIEnv* env, jobject thiz, jobject medialibrary, jlong id, jst
medialibrary::MediaPtr media = aml->media(id);
if (media == nullptr) return;
const char *char_mrl = env->GetStringUTFChars(mrl, JNI_FALSE);
media->setThumbnail(char_mrl);
media->setThumbnail(char_mrl, medialibrary::ThumbnailSizeType::Thumbnail);
env->ReleaseStringUTFChars(mrl, char_mrl);
}
......@@ -1803,7 +1804,6 @@ static JNINativeMethod methods[] = {
{"nativeSetMediaUpdatedCbFlag", "(I)V", (void*)setMediaUpdatedCbFlag },
{"nativeSetMediaAddedCbFlag", "(I)V", (void*)setMediaAddedCbFlag },
{"nativePlaylistCreate", "(Ljava/lang/String;)Lorg/videolan/medialibrary/interfaces/media/AbstractPlaylist;", (void*)playlistCreate },
{"nativeRequestThumbnail", "(J)V", (void*)requestThumbnail },
};
static JNINativeMethod media_methods[] = {
......@@ -1814,6 +1814,7 @@ static JNINativeMethod media_methods[] = {
{"nativeSetMediaThumbnail", "(Lorg/videolan/medialibrary/interfaces/AbstractMedialibrary;JLjava/lang/String;)V", (void*)setMediaThumbnail },
{"nativeSetMediaTitle", "(Lorg/videolan/medialibrary/interfaces/AbstractMedialibrary;JLjava/lang/String;)V", (void*)setMediaTitle },
{"nativeRemoveFromHistory", "(Lorg/videolan/medialibrary/interfaces/AbstractMedialibrary;J)V", (void*)removeMediaFromHistory },
{"nativeRequestThumbnail", "(Lorg/videolan/medialibrary/interfaces/AbstractMedialibrary;JIIIF)V", (void*)requestThumbnail },
};
static JNINativeMethod album_methods[] = {
......
......@@ -68,7 +68,7 @@ mediaToMediaWrapper(JNIEnv* env, fields *fields, medialibrary::MediaPtr const& m
} catch(const medialibrary::fs::DeviceRemovedException&) {
return nullptr;
}
thumbnail = mediaPtr->thumbnailMrl().empty() ? NULL : env->NewStringUTF(mediaPtr->thumbnailMrl().c_str());
thumbnail = mediaPtr->thumbnailMrl(medialibrary::ThumbnailSizeType::Thumbnail).empty() ? NULL : env->NewStringUTF(mediaPtr->thumbnailMrl(medialibrary::ThumbnailSizeType::Thumbnail).c_str());
std::vector<medialibrary::VideoTrackPtr> videoTracks = mediaPtr->videoTracks()->all();
bool hasVideoTracks = !videoTracks.empty();
unsigned int width = hasVideoTracks ? videoTracks.at(0)->width() : 0;
......@@ -85,7 +85,7 @@ mediaToMediaWrapper(JNIEnv* env, fields *fields, medialibrary::MediaPtr const& m
(jlong) mediaPtr->id(), mrl,(jlong) progress, (jlong) duration, type,
title, filename, artist, genre, album,
albumArtist, width, height, thumbnail,
audioTrack, spuTrack, trackNumber, discNumber, (jlong) files.at(0)->lastModificationDate(), seen, mediaPtr->isThumbnailGenerated());
audioTrack, spuTrack, trackNumber, discNumber, (jlong) files.at(0)->lastModificationDate(), seen, mediaPtr->isThumbnailGenerated(medialibrary::ThumbnailSizeType::Thumbnail));
if (artist != NULL)
env->DeleteLocalRef(artist);
if (genre != NULL)
......@@ -109,7 +109,7 @@ jobject
convertAlbumObject(JNIEnv* env, fields *fields, medialibrary::AlbumPtr const& albumPtr)
{
jstring title = env->NewStringUTF(albumPtr->title().c_str());
jstring thumbnailMrl = env->NewStringUTF(albumPtr->thumbnailMrl().c_str());
jstring thumbnailMrl = env->NewStringUTF(albumPtr->thumbnailMrl(medialibrary::ThumbnailSizeType::Thumbnail).c_str());
medialibrary::ArtistPtr artist = albumPtr->albumArtist();
jlong albumArtistId = artist != nullptr ? albumPtr->albumArtist()->id() : 0;
jstring artistName = artist != nullptr ? env->NewStringUTF(artist->name().c_str()) : NULL;
......@@ -125,7 +125,7 @@ jobject
convertArtistObject(JNIEnv* env, fields *fields, medialibrary::ArtistPtr const& artistPtr)
{
jstring name = env->NewStringUTF(artistPtr->name().c_str());
jstring thumbnailMrl = env->NewStringUTF(artistPtr->thumbnailMrl().c_str());
jstring thumbnailMrl = env->NewStringUTF(artistPtr->thumbnailMrl(medialibrary::ThumbnailSizeType::Thumbnail).c_str());
jstring shortBio = env->NewStringUTF(artistPtr->shortBio().c_str());
jstring musicBrainzId = env->NewStringUTF(artistPtr->musicBrainzId().c_str());
jobject item = env->NewObject(fields->Artist.clazz, fields->Artist.initID,
......
......@@ -26,6 +26,13 @@ import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.MutableLiveData;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.videolan.libvlc.LibVLC;
import org.videolan.medialibrary.interfaces.AbstractMedialibrary;
import org.videolan.medialibrary.interfaces.media.AbstractAlbum;
......@@ -38,14 +45,10 @@ import org.videolan.medialibrary.media.SearchAggregate;
import java.io.File;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
@SuppressWarnings("JniMissingFunction")
public class Medialibrary extends AbstractMedialibrary {
private static final String TAG = "VLC/JMedialibrary";
public int init(Context context) {
if (context == null) return ML_INIT_FAILED;
sContext = context;
......@@ -384,16 +387,11 @@ public class Medialibrary extends AbstractMedialibrary {
return mIsInitiated ? nativeGetFolders(type, sort, desc, nbItems, offset) : new AbstractFolder[0];
}
@NonNull
@WorkerThread
public int getFoldersCount(int type) {
return mIsInitiated ? nativeGetFoldersCount(type) : 0;
}
public void requestThumbnail(long id) {
if (mIsInitiated) nativeRequestThumbnail(id);
}
public boolean increasePlayCount(long mediaId) {
return mIsInitiated && mediaId > 0 && nativeIncreasePlayCount(mediaId);
}
......
......@@ -95,6 +95,13 @@ abstract public class AbstractMedialibrary {
return sRunning;
}
public enum ThumbnailSizeType {
/// A small sized thumbnail. Considered to be the default value before model 17
Thumbnail,
/// A banner type thumbnail. The exact size is application dependent.
Banner
}
public boolean isStarted() {
return isMedialibraryStarted;
}
......@@ -639,7 +646,6 @@ abstract public class AbstractMedialibrary {
abstract public AbstractMediaWrapper addStream(String mrl, String title);
abstract public AbstractFolder[] getFolders(int type, int sort, boolean desc, int nbItems, int offset);
abstract public int getFoldersCount(int type);
abstract public void requestThumbnail(long id);
abstract public boolean increasePlayCount(long mediaId);
abstract public SearchAggregate search(String query);
abstract public AbstractMediaWrapper[] searchMedia(String query);
......
......@@ -14,6 +14,7 @@ import org.videolan.libvlc.util.Extensions;
import org.videolan.libvlc.util.VLCUtil;
import org.videolan.medialibrary.MLServiceLocator;
import org.videolan.medialibrary.Tools;
import org.videolan.medialibrary.interfaces.AbstractMedialibrary;
import org.videolan.medialibrary.media.MediaLibraryItem;
import java.util.Locale;
......@@ -108,6 +109,8 @@ public abstract class AbstractMediaWrapper extends MediaLibraryItem implements P
public abstract boolean setLongMeta(int metaDataType, long metaDataValue);
public abstract boolean setStringMeta(int metaDataType, String metaDataValue);
public abstract void setThumbnail(String mrl);
public abstract void requestThumbnail(int width, float position);
public abstract void requestBanner(int width, float position);
/**
* Create a new AbstractMediaWrapper
......
......@@ -235,23 +235,38 @@ public class MediaWrapper extends AbstractMediaWrapper {
}
public boolean setStringMeta(int metaDataType, String metadataValue) {
if (mId == 0L) return false;
AbstractMedialibrary ml = AbstractMedialibrary.getInstance();
if (mId != 0 && ml.isInitiated())
nativeSetMediaStringMetadata(ml, mId, metaDataType, metadataValue);
return mId != 0;
return true;
}
public void setThumbnail(String mrl) {
if (mId == 0L) return;
mArtworkURL = mrl;
final AbstractMedialibrary ml = AbstractMedialibrary.getInstance();
if (mId != 0 && ml.isInitiated()) nativeSetMediaThumbnail(ml, mId, Tools.encodeVLCMrl(mrl));
}
public void requestThumbnail(int width, float position) {
if (mId == 0L) return;
final AbstractMedialibrary ml = AbstractMedialibrary.getInstance();
if (ml.isInitiated()) nativeRequestThumbnail(ml, mId, AbstractMedialibrary.ThumbnailSizeType.Thumbnail.ordinal(), width, 0, position);
}
public void requestBanner(int width, float position) {
if (mId == 0L) return;
final AbstractMedialibrary ml = AbstractMedialibrary.getInstance();
if (ml.isInitiated()) nativeRequestThumbnail(ml, mId, AbstractMedialibrary.ThumbnailSizeType.Banner.ordinal(), width, 0, position);
}
private native long nativeGetMediaLongMetadata(AbstractMedialibrary ml, long id, int metaDataType);
private native String nativeGetMediaStringMetadata(AbstractMedialibrary ml, long id, int metaDataType);
private native void nativeSetMediaStringMetadata(AbstractMedialibrary ml, long id, int metaDataType, String metadataValue);
private native void nativeSetMediaLongMetadata(AbstractMedialibrary ml, long id, int metaDataType, long metadataValue);
private native void nativeSetMediaThumbnail(AbstractMedialibrary ml, long id, String mrl);
private native void nativeSetMediaTitle(AbstractMedialibrary ml, long id, String name);
private native void nativeRemoveFromHistory(AbstractMedialibrary ml, long id);
private native void nativeSetMediaThumbnail(AbstractMedialibrary ml, long id, String mrl);
private native void nativeRequestThumbnail(AbstractMedialibrary ml, long mediaId, int type, int width, int height, float position);
}
......@@ -56,8 +56,14 @@ public class StubMediaWrapper extends AbstractMediaWrapper {
return true;
}
public void setThumbnail(String mrl) {
//TODO
public void setThumbnail(String mrl) {}
@Override
public void requestThumbnail(int width, float position) {}
@Override
public void requestBanner(int width, float position) {
}
}
......@@ -132,10 +132,10 @@ class MediaParsingService : Service(), DevicesDiscoveryCb, CoroutineScope {
ACTION_CHECK_STORAGES -> if (settings.getInt(KEY_MEDIALIBRARY_SCAN, -1) != ML_SCAN_OFF) actions.offer(UpdateStorages) else exitCommand()
else -> {
exitCommand()
return Service.START_NOT_STICKY
return START_NOT_STICKY
}
}
return Service.START_NOT_STICKY
return START_NOT_STICKY
}
@TargetApi(Build.VERSION_CODES.O)
......@@ -330,6 +330,7 @@ class MediaParsingService : Service(), DevicesDiscoveryCb, CoroutineScope {
override fun onReloadCompleted(entryPoint: String) {
if (BuildConfig.DEBUG) Log.v(TAG, "onReloadCompleted $entryPoint")
if (TextUtils.isEmpty(entryPoint)) --reload
if (reload <= 0) exitCommand()
}
private fun exitCommand() = launch {
......
......@@ -85,19 +85,15 @@ object ThumbnailsProvider {
media.artworkURL = thumbPath
}
} else if (media.id != 0L) {
AbstractMedialibrary.getInstance().requestThumbnail(media.id)
media.requestThumbnail(width, 0.4f)
}
return bitmap
}
suspend fun getPlaylistImage(key: String, mediaList: List<AbstractMediaWrapper>, width: Int): Bitmap? {
var composedImage = BitmapCache.getBitmapFromMemCache(key)
if (composedImage == null) {
composedImage = composePlaylistImage(mediaList, width)
if (composedImage != null) BitmapCache.addBitmapToMemCache(key, composedImage)
}
return composedImage
}
suspend fun getPlaylistImage(key: String, mediaList: List<AbstractMediaWrapper>, width: Int) =
(BitmapCache.getBitmapFromMemCache(key) ?: composePlaylistImage(mediaList, width))?.also {
BitmapCache.addBitmapToMemCache(key, it)
}
/**
* Compose 1 image from tracks of a Playlist
......@@ -105,9 +101,7 @@ object ThumbnailsProvider {
* @return a Bitmap object
*/
private suspend fun composePlaylistImage(mediaList: List<AbstractMediaWrapper>, width: Int): Bitmap? {
if (mediaList.isEmpty()) {
return null
}
if (mediaList.isEmpty()) return null
val url = mediaList[0].artworkURL
val isAllSameImage = !mediaList.any { it.artworkURL != url }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment