Browse Source

Mediagroups

merge-requests/382/head
Geoffrey Métais 7 years ago
parent
commit
dceeb8961b
  1. 4
      compile.sh
  2. 57
      medialibrary/jni/AndroidMediaLibrary.cpp
  3. 14
      medialibrary/jni/AndroidMediaLibrary.h
  4. 39
      medialibrary/jni/medialibrary.cpp
  5. 4
      medialibrary/jni/utils.cpp
  6. 8
      medialibrary/jni/utils.h
  7. 1
      medialibrary/src/org/videolan/medialibrary/Medialibrary.java
  8. 73
      medialibrary/src/org/videolan/medialibrary/interfaces/AbstractMedialibrary.java
  9. 26
      vlc-android/src/org/videolan/vlc/viewmodels/CallBackDelegate.kt

4
compile.sh

@ -122,8 +122,8 @@ if [ -z "$ANDROID_NDK" -o -z "$ANDROID_SDK" ]; then
fi
if [ -z "$ANDROID_ABI" ]; then
diagnostic "*** No ANDROID_ABI defined architecture: using ARMv7"
ANDROID_ABI="armeabi-v7a"
diagnostic "*** No ANDROID_ABI defined architecture: using arm64-v8a"
ANDROID_ABI="arm64-v8a"
fi
if [ "$ANDROID_ABI" = "armeabi-v7a" -o "$ANDROID_ABI" = "arm" ]; then

57
medialibrary/jni/AndroidMediaLibrary.cpp

@ -513,30 +513,24 @@ medialibrary::Query<medialibrary::IFolder> AndroidMediaLibrary::subFolders(int64
return folder != nullptr ? folder->subfolders(params) : nullptr;
}
medialibrary::Query<medialibrary::IVideoGroup>
medialibrary::Query<medialibrary::IMediaGroup>
AndroidMediaLibrary::videoGroups( const medialibrary::QueryParameters* params )
{
return p_ml->videoGroups(params);
}
void
AndroidMediaLibrary::setVideoGroupsPrefixLength( uint32_t prefixLength )
{
p_ml->setVideoGroupsPrefixLength(prefixLength);
return p_ml->mediaGroups(params);
}
medialibrary::Query<medialibrary::IMedia>
AndroidMediaLibrary::mediaFromVideoGroup(const std::string& name, const medialibrary::QueryParameters* params )
AndroidMediaLibrary::mediaFromMediaGroup(const std::string& name, const medialibrary::QueryParameters* params )
{
medialibrary::VideoGroupPtr group = p_ml->videoGroup(name);
return group != nullptr ? group->media(params) : nullptr;
medialibrary::MediaGroupPtr group = p_ml->mediaGroup(name);
return group != nullptr ? group->media(medialibrary::IMedia::Type::Video, params) : nullptr;
}
medialibrary::Query<medialibrary::IMedia>
AndroidMediaLibrary::searchFromVideoGroup( const std::string& name, const std::string& query, const medialibrary::QueryParameters* params )
AndroidMediaLibrary::searchFromMediaGroup( const std::string& name, const std::string& query, const medialibrary::QueryParameters* params )
{
auto group = p_ml->videoGroup(name);
return group == nullptr ? nullptr : group->searchMedia(query, params);
auto group = p_ml->mediaGroup(name);
return group == nullptr ? nullptr : group->searchMedia(query, medialibrary::IMedia::Type::Video, params);
}
void
@ -896,8 +890,41 @@ void AndroidMediaLibrary::onParsingStatsUpdated( uint32_t percent)
}
}
void AndroidMediaLibrary::onHistoryChanged( medialibrary::HistoryType )
void AndroidMediaLibrary::onHistoryChanged( medialibrary::HistoryType type)
{
JNIEnv *env = getEnv();
if (env != nullptr && weak_thiz)
{
env->CallVoidMethod(weak_thiz, p_fields->MediaLibrary.onHistoryChangedId, type);
}
}
void AndroidMediaLibrary::onMediaGroupAdded( std::vector<medialibrary::MediaGroupPtr> mediaGroups )
{
JNIEnv *env = getEnv();
if (env != nullptr && weak_thiz)
{
env->CallVoidMethod(weak_thiz, p_fields->MediaLibrary.onMediaGroupAddedId);
}
}
void AndroidMediaLibrary::onMediaGroupModified( std::vector<int64_t> mediaGroupsIds )
{
JNIEnv *env = getEnv();
if (env != nullptr && weak_thiz)
{
env->CallVoidMethod(weak_thiz, p_fields->MediaLibrary.onMediaGroupModifiedId);
}
}
void AndroidMediaLibrary::onMediaGroupDeleted( std::vector<int64_t> mediaGroupsIds )
{
JNIEnv *env = getEnv();
if (env != nullptr && weak_thiz)
{
env->CallVoidMethod(weak_thiz, p_fields->MediaLibrary.onMediaGroupDeletedId);
}
}
void AndroidMediaLibrary::onRescanStarted()

14
medialibrary/jni/AndroidMediaLibrary.h

@ -16,7 +16,7 @@
#include <medialibrary/IGenre.h>
#include <medialibrary/IPlaylist.h>
#include <medialibrary/IFolder.h>
#include <medialibrary/IVideoGroup.h>
#include <medialibrary/IMediaGroup.h>
#include <medialibrary/Types.h>
#include <medialibrary/IDeviceLister.h>
#include <medialibrary/IMedia.h>
@ -79,7 +79,7 @@ public:
medialibrary::MediaPtr addStream(const std::string& mrl, const std::string& title);
medialibrary::Query<medialibrary::IMedia> videoFiles( const medialibrary::QueryParameters* params = nullptr );
medialibrary::Query<medialibrary::IMedia> audioFiles( const medialibrary::QueryParameters* params = nullptr );
medialibrary::Query<medialibrary::IVideoGroup> videoGroups( const medialibrary::QueryParameters* params );
medialibrary::Query<medialibrary::IMediaGroup> videoGroups( const medialibrary::QueryParameters* params );
medialibrary::Query<medialibrary::IAlbum> albums(const medialibrary::QueryParameters* params);
medialibrary::AlbumPtr album(int64_t albumId);
medialibrary::Query<medialibrary::IArtist> artists(bool includeAll, const medialibrary::QueryParameters* params);
@ -101,10 +101,12 @@ public:
medialibrary::Query<medialibrary::IFolder> folders(const medialibrary::QueryParameters* params = nullptr, medialibrary::IMedia::Type type = medialibrary::IMedia::Type::Unknown );
medialibrary::Query<medialibrary::IFolder> subFolders(int64_t folderId, const medialibrary::QueryParameters* params = nullptr );
// VideoGroups
void setVideoGroupsPrefixLength( uint32_t prefixLength );
medialibrary::Query<medialibrary::IMedia> mediaFromVideoGroup(const std::string& name, const medialibrary::QueryParameters* params );
medialibrary::Query<medialibrary::IMedia> searchFromVideoGroup( const std::string& name, const std::string& query, const medialibrary::QueryParameters* params );
//PLaylists
medialibrary::Query<medialibrary::IMedia> mediaFromMediaGroup(const std::string& name, const medialibrary::QueryParameters* params );
medialibrary::Query<medialibrary::IMedia> searchFromMediaGroup( const std::string& name, const std::string& query, const medialibrary::QueryParameters* params );
void onMediaGroupAdded( std::vector<medialibrary::MediaGroupPtr> mediaGroups );
void onMediaGroupModified( std::vector<int64_t> mediaGroupsIds );
void onMediaGroupDeleted( std::vector<int64_t> mediaGroupsIds );
//Playlists
bool playlistAppend(int64_t playlistId, int64_t mediaId);
bool playlistAdd(int64_t playlistId, int64_t mediaId, unsigned int position);
bool playlistMove(int64_t playlistId, unsigned int oldPosition, unsigned int newPosition);

39
medialibrary/jni/medialibrary.cpp

@ -301,8 +301,7 @@ jobjectArray
getSortedVideos(JNIEnv* env, jobject thiz, jint sortingCriteria, jboolean desc)
{
medialibrary::QueryParameters params {
static_cast<medialibrary::SortingCriteria>(sortingCriteria),
static_cast<bool>( desc )
static_cast<medialibrary::SortingCriteria>(sortingCriteria), static_cast<bool>( desc )
};
return getInternalVideos(env, thiz, &params );
}
@ -1768,13 +1767,6 @@ foldersCount(JNIEnv* env, jobject thiz, jint type) {
* Video groups
*/
void
setVideoGroupsPrefixLength( JNIEnv* env, jobject thiz, jint prefixLength )
{
AndroidMediaLibrary *aml = MediaLibrary_getInstance(env, thiz);
aml->setVideoGroupsPrefixLength(static_cast<uint32_t>(prefixLength));
}
jobjectArray
videoGroups(JNIEnv* env, jobject thiz, jint sortingCriteria, jboolean desc, jint nbItems, jint offset ) {
AndroidMediaLibrary *aml = MediaLibrary_getInstance(env, thiz);
@ -1784,10 +1776,10 @@ videoGroups(JNIEnv* env, jobject thiz, jint sortingCriteria, jboolean desc, jint
};
const auto query = aml->videoGroups(&params);
if (query == nullptr) return (jobjectArray) env->NewObjectArray(0, ml_fields.VideoGroup.clazz, NULL);
std::vector<medialibrary::VideoGroupPtr> groupsList = nbItems != 0 ? query->items(nbItems, offset) : query->all();
std::vector<medialibrary::MediaGroupPtr> groupsList = nbItems != 0 ? query->items(nbItems, offset) : query->all();
jobjectArray groupsRefs = (jobjectArray) env->NewObjectArray(groupsList.size(), ml_fields.VideoGroup.clazz, NULL);
int index = -1;
for(medialibrary::VideoGroupPtr const& group : groupsList) {
for(medialibrary::MediaGroupPtr const& group : groupsList) {
try
{
jobject item = convertVideoGroupObject(env, &ml_fields, group);
@ -1817,7 +1809,7 @@ getPagedMediaFromvideoGroup(JNIEnv* env, jobject thiz, jobject medialibrary, jst
static_cast<bool>( desc )
};
const char *char_name = env->GetStringUTFChars(name, JNI_FALSE);
const auto query = aml->mediaFromVideoGroup(char_name, &params);
const auto query = aml->mediaFromMediaGroup(char_name, &params);
if (query == nullptr)
{
env->ReleaseStringUTFChars(name, char_name);
@ -1838,7 +1830,7 @@ getPagedMediaFromvideoGroup(JNIEnv* env, jobject thiz, jobject medialibrary, jst
jint
getvideoGroupMediaCount(JNIEnv* env, jobject thiz, jobject medialibrary, jstring name) {
const char *char_name = env->GetStringUTFChars(name, JNI_FALSE);
const auto query = MediaLibrary_getInstance(env, medialibrary)->mediaFromVideoGroup(char_name, nullptr);
const auto query = MediaLibrary_getInstance(env, medialibrary)->mediaFromMediaGroup(char_name, nullptr);
env->ReleaseStringUTFChars(name, char_name);
return static_cast<jint> (query != nullptr ? query->count() : 0);
}
@ -1853,7 +1845,7 @@ searchFromvideoGroup(JNIEnv* env, jobject thiz, jobject medialibrary, jstring na
};
const char *char_name = env->GetStringUTFChars(name, JNI_FALSE);
const char *queryChar = env->GetStringUTFChars(filterQuery, JNI_FALSE);
const auto query = aml->searchFromVideoGroup(char_name, queryChar, &params);
const auto query = aml->searchFromMediaGroup(char_name, queryChar, &params);
if (query == nullptr)
{
env->ReleaseStringUTFChars(filterQuery, queryChar);
@ -1877,7 +1869,7 @@ jint
getSearchFromvideoGroupCount(JNIEnv* env, jobject thiz, jobject medialibrary, jstring name, jstring filterQuery) {
const char *queryChar = env->GetStringUTFChars(filterQuery, JNI_FALSE);
const char *char_name = env->GetStringUTFChars(name, JNI_FALSE);
const auto query = MediaLibrary_getInstance(env, medialibrary)->searchFromVideoGroup(char_name, queryChar, nullptr);
const auto query = MediaLibrary_getInstance(env, medialibrary)->searchFromMediaGroup(char_name, queryChar, nullptr);
env->ReleaseStringUTFChars(filterQuery, queryChar);
env->ReleaseStringUTFChars(name, char_name);
return static_cast<jint> (query != nullptr ? query->count() : 0);
@ -1902,7 +1894,6 @@ static JNINativeMethod methods[] = {
{"nativeLastStreamsPlayed", "()[Lorg/videolan/medialibrary/interfaces/media/AbstractMediaWrapper;", (void*)lastStreamsPlayed },
{"nativeAddToHistory", "(Ljava/lang/String;Ljava/lang/String;)Z", (void*)addToHistory },
{"nativeClearHistory", "()Z", (void*)clearHistory },
{"nativeSetVideoGroupsPrefixLength", "(I)V", (void*)setVideoGroupsPrefixLength },
{"nativeGetVideos", "()[Lorg/videolan/medialibrary/interfaces/media/AbstractMediaWrapper;", (void*)getVideos },
{"nativeGetSortedVideos", "(IZ)[Lorg/videolan/medialibrary/interfaces/media/AbstractMediaWrapper;", (void*)getSortedVideos },
{"nativeGetSortedPagedVideos", "(IZII)[Lorg/videolan/medialibrary/interfaces/media/AbstractMediaWrapper;", (void*)getPagedVideos },
@ -2264,6 +2255,22 @@ jint JNI_OnLoad(JavaVM *vm, void *reserved)
ml_fields.MediaLibrary.onGenresModifiedId,
ml_fields.MediaLibrary.clazz,
"onGenresModified", "()V");
GET_ID(GetMethodID,
ml_fields.MediaLibrary.onHistoryChangedId,
ml_fields.MediaLibrary.clazz,
"onHistoryChanged", "(I)V");
GET_ID(GetMethodID,
ml_fields.MediaLibrary.onMediaGroupAddedId,
ml_fields.MediaLibrary.clazz,
"onMediaGroupAdded", "()V");
GET_ID(GetMethodID,
ml_fields.MediaLibrary.onMediaGroupModifiedId,
ml_fields.MediaLibrary.clazz,
"onMediaGroupModified", "()V");
GET_ID(GetMethodID,
ml_fields.MediaLibrary.onMediaGroupDeletedId,
ml_fields.MediaLibrary.clazz,
"onMediaGroupDeleted", "()V");
GET_ID(GetMethodID,
ml_fields.MediaLibrary.onPlaylistsModifiedId,
ml_fields.MediaLibrary.clazz,

4
medialibrary/jni/utils.cpp

@ -160,11 +160,11 @@ convertFolderObject(JNIEnv* env, fields *fields, medialibrary::FolderPtr const&
}
jobject
convertVideoGroupObject(JNIEnv* env, fields *fields, medialibrary::VideoGroupPtr const& videogroupPtr)
convertVideoGroupObject(JNIEnv* env, fields *fields, medialibrary::MediaGroupPtr const& videogroupPtr)
{
jstring name = env->NewStringUTF(videogroupPtr->name().c_str());
jobject item = env->NewObject(fields->VideoGroup.clazz, fields->VideoGroup.initID,
name, (jint)videogroupPtr->count());
name, (jint)videogroupPtr->nbVideo());
env->DeleteLocalRef(name);
return item;
}

8
medialibrary/jni/utils.h

@ -35,7 +35,7 @@
#include <medialibrary/IMediaLibrary.h>
#include <medialibrary/IMetadata.h>
#include<medialibrary/filesystem/IDevice.h>
#include <medialibrary/IVideoGroup.h>
#include <medialibrary/IMediaGroup.h>
#include <medialibrary/filesystem/Errors.h>
#define VLC_JNI_VERSION JNI_VERSION_1_2
@ -68,6 +68,10 @@ struct fields {
jmethodID onPlaylistsAddedId;
jmethodID onPlaylistsModifiedId;
jmethodID onPlaylistsDeletedId;
jmethodID onMediaGroupAddedId;
jmethodID onMediaGroupModifiedId;
jmethodID onMediaGroupDeletedId;
jmethodID onHistoryChangedId;
jmethodID onDiscoveryStartedId;
jmethodID onDiscoveryProgressId;
jmethodID onDiscoveryCompletedId;
@ -126,7 +130,7 @@ jobject convertArtistObject(JNIEnv* env, fields *fields, medialibrary::ArtistPtr
jobject convertGenreObject(JNIEnv* env, fields *fields, medialibrary::GenrePtr const& genrePtr);
jobject convertPlaylistObject(JNIEnv* env, fields *fields, medialibrary::PlaylistPtr const& genrePtr);
jobject convertFolderObject(JNIEnv* env, fields *fields, medialibrary::FolderPtr const& folderPtr);
jobject convertVideoGroupObject(JNIEnv* env, fields *fields, medialibrary::VideoGroupPtr const& videogroupPtr);
jobject convertVideoGroupObject(JNIEnv* env, fields *fields, medialibrary::MediaGroupPtr const& videogroupPtr);
jobject convertSearchAggregateObject(JNIEnv* env, fields *fields, medialibrary::SearchAggregate const& searchAggregatePtr);
jobjectArray filteredArray(JNIEnv* env, jobjectArray array, jclass clazz, int removalCount = -1);

1
medialibrary/src/org/videolan/medialibrary/Medialibrary.java

@ -46,7 +46,6 @@ import java.io.File;
public class Medialibrary extends AbstractMedialibrary {
private static final String TAG = "VLC/JMedialibrary";
public int init(Context context) {
if (context == null) return ML_INIT_FAILED;
if (mIsInitiated) return ML_INIT_ALREADY_INITIALIZED;

73
medialibrary/src/org/videolan/medialibrary/interfaces/AbstractMedialibrary.java

@ -44,6 +44,11 @@ abstract public class AbstractMedialibrary {
public final static int SORT_PLAYCOUNT = 8;
public final static int SORT_ALBUM = 9;
public final static int SORT_FILENAME = 10;
public final static int TrackNumber = 11;
public final static int TrackId = 12;
public final static int NbVideo = 13;
public final static int NbAudio = 14;
public final static int NbMedia = 15;
protected long mInstanceID;
public static final int FLAG_MEDIA_UPDATED_AUDIO = 1 << 0;
@ -75,6 +80,8 @@ abstract public class AbstractMedialibrary {
protected final List<MediaCb> mMediaCbs = new ArrayList<>();
protected final List<GenresCb> mGenreCbs = new ArrayList<>();
protected final List<PlaylistsCb> mPlaylistCbs = new ArrayList<>();
protected final List<HistoryCb> mHistoryCbs = new ArrayList<>();
protected final List<MediaGroupCb> mMediaGroupCbs = new ArrayList<>();
protected final List<OnMedialibraryReadyListener> onMedialibraryReadyListeners = new ArrayList<>();
protected final List<OnDeviceChangeListener> onDeviceChangeListeners = new ArrayList<>();
protected volatile boolean isMedialibraryStarted = false;
@ -197,6 +204,16 @@ abstract public class AbstractMedialibrary {
void onPlaylistsDeleted();
}
public interface HistoryCb {
void onHistoryModified();
}
public interface MediaGroupCb {
void onMediaGroupsAdded();
void onMediaGroupsModified();
void onMediaGroupsDeleted();
}
public interface OnMedialibraryReadyListener {
void onMedialibraryReady();
void onMedialibraryIdle();
@ -345,6 +362,34 @@ abstract public class AbstractMedialibrary {
}
}
@SuppressWarnings("unused")
public void onHistoryChanged(int type) {
synchronized (mHistoryCbs) {
for (HistoryCb cb : mHistoryCbs) cb.onHistoryModified();
}
}
@SuppressWarnings("unused")
public void onMediaGroupAdded() {
synchronized (mMediaGroupCbs) {
for (MediaGroupCb cb : mMediaGroupCbs) cb.onMediaGroupsAdded();
}
}
@SuppressWarnings("unused")
public void onMediaGroupModified() {
synchronized (mMediaGroupCbs) {
for (MediaGroupCb cb : mMediaGroupCbs) cb.onMediaGroupsModified();
}
}
@SuppressWarnings("unused")
public void onMediaGroupDeleted() {
synchronized (mMediaGroupCbs) {
for (MediaGroupCb cb : mMediaGroupCbs) cb.onMediaGroupsDeleted();
}
}
public void onDiscoveryStarted(String entryPoint) {
synchronized (devicesDiscoveryCbList) {
if (!devicesDiscoveryCbList.isEmpty())
@ -546,6 +591,34 @@ abstract public class AbstractMedialibrary {
}
}
public void addHistoryCb(HistoryCb historyCb) {
if (!mIsInitiated) return;
synchronized (mHistoryCbs) {
this.mHistoryCbs.add(historyCb);
}
}
public void removeHistoryCb(HistoryCb historyCb) {
if (!mIsInitiated) return;
synchronized (mHistoryCbs) {
this.mHistoryCbs.remove(historyCb);
}
}
public void addMediaGroupCb(MediaGroupCb mediaGroupCb) {
if (!mIsInitiated) return;
synchronized (mMediaGroupCbs) {
this.mMediaGroupCbs.add(mediaGroupCb);
}
}
public void removeMediaGroupCb(MediaGroupCb mediaGroupCb) {
if (!mIsInitiated) return;
synchronized (mMediaGroupCbs) {
this.mMediaGroupCbs.remove(mediaGroupCb);
}
}
public void addDeviceDiscoveryCb(DevicesDiscoveryCb cb) {
synchronized (devicesDiscoveryCbList) {
if (!devicesDiscoveryCbList.contains(cb))

26
vlc-android/src/org/videolan/vlc/viewmodels/CallBackDelegate.kt

@ -36,6 +36,8 @@ interface ICallBackHandler {
fun watchAlbums()
fun watchGenres()
fun watchPlaylists()
fun watchHistory()
fun watchMediaGroups()
}
class CallBackDelegate : ICallBackHandler,
@ -45,7 +47,7 @@ class CallBackDelegate : ICallBackHandler,
AbstractMedialibrary.ArtistsCb,
AbstractMedialibrary.AlbumsCb,
AbstractMedialibrary.GenresCb,
AbstractMedialibrary.PlaylistsCb{
AbstractMedialibrary.PlaylistsCb, AbstractMedialibrary.HistoryCb, AbstractMedialibrary.MediaGroupCb {
override val medialibrary = AbstractMedialibrary.getInstance()
private lateinit var refreshActor: SendChannel<Unit>
@ -55,6 +57,8 @@ class CallBackDelegate : ICallBackHandler,
private var albumsCb = false
private var genresCb = false
private var playlistsCb = false
private var historyCb = false
private var mediaGroupsCb = false
override fun CoroutineScope.registerCallBacks(refresh: () -> Unit) {
refreshActor = conflatedActor { refresh() }
@ -87,6 +91,16 @@ class CallBackDelegate : ICallBackHandler,
playlistsCb = true
}
override fun watchHistory() {
medialibrary.addHistoryCb(this)
historyCb = true
}
override fun watchMediaGroups() {
medialibrary.addMediaGroupCb(this)
mediaGroupsCb = true
}
override fun releaseCallbacks() {
medialibrary.removeOnMedialibraryReadyListener(this)
medialibrary.removeOnDeviceChangeListener(this)
@ -95,6 +109,8 @@ class CallBackDelegate : ICallBackHandler,
if (albumsCb) medialibrary.removeAlbumsCb(this)
if (genresCb) medialibrary.removeGenreCb(this)
if (playlistsCb) medialibrary.removePlaylistCb(this)
if (historyCb) medialibrary.removeHistoryCb(this)
if (mediaGroupsCb) medialibrary.removeMediaGroupCb(this)
refreshActor.close()
}
@ -133,4 +149,12 @@ class CallBackDelegate : ICallBackHandler,
override fun onPlaylistsModified() { refreshActor.offer(Unit) }
override fun onPlaylistsDeleted() { refreshActor.offer(Unit) }
override fun onHistoryModified() { refreshActor.offer(Unit) }
override fun onMediaGroupsAdded() { refreshActor.offer(Unit) }
override fun onMediaGroupsModified() { refreshActor.offer(Unit) }
override fun onMediaGroupsDeleted() { refreshActor.offer(Unit) }
}

Loading…
Cancel
Save