[Android] [PATCH 4/4] libvlc: Add MediaDiscoverer
Thomas Guillem
thomas at gllm.fr
Fri Dec 5 14:43:43 CET 2014
---
libvlc/jni/Android.mk | 1 +
libvlc/jni/libvlcjni-mediadiscoverer.c | 141 +++++++++++++++++++++
libvlc/jni/libvlcjni.c | 21 ++-
libvlc/src/org/videolan/libvlc/EventHandler.java | 7 +-
libvlc/src/org/videolan/libvlc/LibVLC.java | 6 +
.../src/org/videolan/libvlc/MediaDiscoverer.java | 87 +++++++++++++
6 files changed, 258 insertions(+), 5 deletions(-)
create mode 100644 libvlc/jni/libvlcjni-mediadiscoverer.c
create mode 100644 libvlc/src/org/videolan/libvlc/MediaDiscoverer.java
diff --git a/libvlc/jni/Android.mk b/libvlc/jni/Android.mk
index 1e2ce54..58aee81 100644
--- a/libvlc/jni/Android.mk
+++ b/libvlc/jni/Android.mk
@@ -5,6 +5,7 @@ LOCAL_MODULE := libvlcjni
LOCAL_SRC_FILES := libvlcjni.c libvlcjni-util.c libvlcjni-track.c
LOCAL_SRC_FILES += libvlcjni-medialist.c libvlcjni-equalizer.c
+LOCAL_SRC_FILES += libvlcjni-mediadiscoverer.c
LOCAL_SRC_FILES += aout.c vout.c native_crash_handler.c thumbnailer.c
ifneq ($(ANDROID_API),android-21)
# compat functions not needed after android-21
diff --git a/libvlc/jni/libvlcjni-mediadiscoverer.c b/libvlc/jni/libvlcjni-mediadiscoverer.c
new file mode 100644
index 0000000..caff0c5
--- /dev/null
+++ b/libvlc/jni/libvlcjni-mediadiscoverer.c
@@ -0,0 +1,141 @@
+/*****************************************************************************
+ * libvlcjni-mediadiscoverer.c
+ *****************************************************************************
+ * Copyright © 2014 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#include <jni.h>
+#include <vlc/vlc.h>
+#include <vlc/libvlc_media_discoverer.h>
+
+#include "utils.h"
+#define LOG_TAG "VLC/JNI/MediaDiscoverer"
+#include "log.h"
+
+void vlc_event_callback(const libvlc_event_t *ev, void *data);
+
+static libvlc_media_discoverer_t *
+getMediaDiscoverer(JNIEnv *env, jobject thiz)
+{
+ return (libvlc_media_discoverer_t*)(intptr_t)getLong(env, thiz, "mInternalMediaDiscovererInstance");
+}
+
+static libvlc_media_discoverer_t *
+setMediaDiscoverer(JNIEnv *env, jobject thiz, libvlc_media_discoverer_t *p_md)
+{
+ setLong(env, thiz, "mInternalMediaDiscovererInstance", (jlong)(intptr_t)p_md);
+}
+
+static void throw(JNIEnv *env, const char *p_error)
+{
+ jclass exc = (*env)->FindClass(env, "org/videolan/libvlc/LibVlcException");
+ (*env)->ThrowNew(env, exc, p_error);
+}
+
+void
+Java_org_videolan_libvlc_LibVLC_mediaDiscoverCreate(JNIEnv *env, jobject thiz,
+ jstring jname)
+{
+ libvlc_instance_t *p_instance = getLibVlcInstance(env, thiz);
+ libvlc_media_discoverer_t *p_discoverer = getMediaDiscoverer(env, thiz);
+ libvlc_event_manager_t *ev;
+
+ const char* p_name;
+ if (p_discoverer)
+ {
+ throw(env, "media discoverer instance already exist");
+ return;
+ }
+
+ if (!jname || !(p_name = (*env)->GetStringUTFChars(env, jname, 0)))
+ {
+ throw(env, "arguments invalid");
+ return;
+ }
+
+ p_discoverer = libvlc_media_discoverer_new(p_instance, p_name);
+
+ (*env)->ReleaseStringUTFChars(env, jname, p_name);
+
+ if (!p_discoverer)
+ {
+ throw(env, "can't create media discoverer instance");
+ return;
+ }
+
+ ev = libvlc_media_discoverer_event_manager(p_discoverer);
+ static const libvlc_event_type_t mp_events[] = {
+ libvlc_MediaDiscovererStarted,
+ libvlc_MediaDiscovererEnded,
+ libvlc_MediaDiscovererItemAdded,
+ libvlc_MediaDiscovererItemRemoved,
+ libvlc_MediaDiscovererItemRemoveAll
+ };
+ for(int i = 0; i < (sizeof(mp_events) / sizeof(*mp_events)); i++)
+ libvlc_event_attach(ev, mp_events[i], vlc_event_callback, NULL);
+
+ if (libvlc_media_discoverer_start(p_discoverer) == -1)
+ {
+ libvlc_media_discoverer_release(p_discoverer);
+ throw(env, "can't start media discoverer");
+ return;
+ }
+ setMediaDiscoverer(env, thiz, p_discoverer);
+}
+
+void
+Java_org_videolan_libvlc_LibVLC_mediaDiscoverRelease(JNIEnv *env, jobject thiz)
+{
+ libvlc_media_discoverer_t *p_discoverer = getMediaDiscoverer(env, thiz);
+ if (p_discoverer)
+ {
+ libvlc_media_discoverer_release(p_discoverer);
+ setMediaDiscoverer(env, thiz, NULL);
+ }
+}
+
+bool
+Java_org_videolan_libvlc_LibVLC_mediaDiscoverBrowse(JNIEnv *env, jobject thiz,
+ jstring jpath)
+{
+ libvlc_media_discoverer_t *p_discoverer = getMediaDiscoverer(env, thiz);
+ const char* p_path;
+ int i_ret;
+
+ if (!p_discoverer)
+ {
+ throw(env, "discoverer instance does not exist");
+ return false;
+ }
+
+ if (jpath)
+ {
+ p_path = (*env)->GetStringUTFChars(env, jpath, 0);
+ if (!p_path)
+ {
+ throw(env, "can't get path");
+ return false;
+ }
+ } else
+ p_path = NULL;
+
+ i_ret = libvlc_media_discoverer_browse(p_discoverer, p_path);
+
+ if (jpath)
+ (*env)->ReleaseStringUTFChars(env, jpath, p_path);
+
+ return i_ret == 0 ? true : false;
+}
diff --git a/libvlc/jni/libvlcjni.c b/libvlc/jni/libvlcjni.c
index 94b216c..7c3ceab 100644
--- a/libvlc/jni/libvlcjni.c
+++ b/libvlc/jni/libvlcjni.c
@@ -126,7 +126,7 @@ static JavaVM *myVm;
static jobject eventHandlerInstance = NULL;
-static void vlc_event_callback(const libvlc_event_t *ev, void *data)
+void vlc_event_callback(const libvlc_event_t *ev, void *data)
{
JNIEnv *env;
@@ -191,6 +191,21 @@ static void vlc_event_callback(const libvlc_event_t *ev, void *data)
(*env)->DeleteLocalRef(env, item_uri_value);
(*env)->DeleteLocalRef(env, item_index);
free(mrl);
+ } else if(ev->type == libvlc_MediaDiscovererItemAdded ||
+ ev->type == libvlc_MediaDiscovererItemRemoved ) {
+ jstring item_uri = (*env)->NewStringUTF(env, "item_uri");
+ char* mrl = libvlc_media_get_mrl(
+ ev->type == libvlc_MediaListItemAdded ?
+ ev->u.media_discoverer_item_added.item :
+ ev->u.media_discoverer_item_removed.item
+ );
+ jstring item_uri_value = (*env)->NewStringUTF(env, mrl);
+
+ (*env)->CallVoidMethod(env, bundle, putString, item_uri, item_uri_value);
+
+ (*env)->DeleteLocalRef(env, item_uri);
+ (*env)->DeleteLocalRef(env, item_uri_value);
+ free(mrl);
}
/* Get the object class */
@@ -442,7 +457,7 @@ void Java_org_videolan_libvlc_LibVLC_playMRL(JNIEnv *env, jobject thiz,
libvlc_MediaPlayerEncounteredError
};
for(int i = 0; i < (sizeof(mp_events) / sizeof(*mp_events)); i++)
- libvlc_event_attach(ev, mp_events[i], vlc_event_callback, myVm);
+ libvlc_event_attach(ev, mp_events[i], vlc_event_callback, NULL);
/* Keep a pointer to this media player */
setLong(env, thiz, "mInternalMediaPlayerInstance", (jlong)(intptr_t)mp);
@@ -467,7 +482,7 @@ void Java_org_videolan_libvlc_LibVLC_playMRL(JNIEnv *env, jobject thiz,
libvlc_MediaMetaChanged,
};
for(int i = 0; i < (sizeof(mp_media_events) / sizeof(*mp_media_events)); i++)
- libvlc_event_attach(ev_media, mp_media_events[i], vlc_event_callback, myVm);
+ libvlc_event_attach(ev_media, mp_media_events[i], vlc_event_callback, NULL);
libvlc_media_player_set_media(mp, p_md);
libvlc_media_player_play(mp);
diff --git a/libvlc/src/org/videolan/libvlc/EventHandler.java b/libvlc/src/org/videolan/libvlc/EventHandler.java
index 4ec0861..3f441b4 100644
--- a/libvlc/src/org/videolan/libvlc/EventHandler.java
+++ b/libvlc/src/org/videolan/libvlc/EventHandler.java
@@ -73,8 +73,11 @@ public class EventHandler {
//public static final int MediaListPlayerNextItemSet = 0x401;
//public static final int MediaListPlayerStopped = 0x402;
- //public static final int MediaDiscovererStarted = 0x500;
- //public static final int MediaDiscovererEnded = 0x501;
+ public static final int MediaDiscovererStarted = 0x500;
+ public static final int MediaDiscovererEnded = 0x501;
+ public static final int MediaDiscovererItemAdded = 0x502;
+ public static final int MediaDiscovererItemRemoved = 0x503;
+ public static final int MediaDiscovererItemRemoveAll = 0x504;
//public static final int VlmMediaAdded = 0x600;
//public static final int VlmMediaRemoved = 0x601;
diff --git a/libvlc/src/org/videolan/libvlc/LibVLC.java b/libvlc/src/org/videolan/libvlc/LibVLC.java
index 8bac400..e9d632e 100644
--- a/libvlc/src/org/videolan/libvlc/LibVLC.java
+++ b/libvlc/src/org/videolan/libvlc/LibVLC.java
@@ -66,6 +66,7 @@ public class LibVLC {
/** libvlc_media_player pointer and index */
private int mInternalMediaPlayerIndex = 0; // Read-only, reserved for JNI
private long mInternalMediaPlayerInstance = 0; // Read-only, reserved for JNI
+ private long mInternalMediaDiscovererInstance = 0; // Read-only, reserved for JNI
private MediaList mMediaList; // Pointer to media list being followed
private MediaList mPrimaryList; // Primary/default media list; see getPrimaryMediaList()
@@ -872,4 +873,9 @@ public class LibVLC {
/* MediaList */
protected native void loadPlaylist(String mrl, ArrayList<String> items);
protected native int expandMedia(int position, ArrayList<String> children);
+
+ /* MediaDiscoverer */
+ protected native void mediaDiscoverCreate(String name) throws LibVlcException;
+ protected native void mediaDiscoverRelease();
+ protected native void mediaDiscoverBrowse(String path) throws LibVlcException;
}
diff --git a/libvlc/src/org/videolan/libvlc/MediaDiscoverer.java b/libvlc/src/org/videolan/libvlc/MediaDiscoverer.java
new file mode 100644
index 0000000..7eb194b
--- /dev/null
+++ b/libvlc/src/org/videolan/libvlc/MediaDiscoverer.java
@@ -0,0 +1,87 @@
+package org.videolan.libvlc;
+
+
+import org.videolan.libvlc.util.WeakHandler;
+
+import android.os.Handler;
+import android.os.Message;
+
+public class MediaDiscoverer {
+
+ public static class Item {
+ public final String uri;
+
+ public Item(String uri) {
+ this.uri = uri;
+ }
+ }
+
+ public interface Listener {
+ public void onStarted();
+ public void onEnded();
+ public void onItemAdded(Item item);
+ public void onItemRemoved(Item item);
+ public void onRemoveAll();
+ }
+
+ private final LibVLC mLibVLC;
+ private final Handler mWeakHandler = new MediaDiscovererEventHandler(this);
+ private final Listener mListener;
+
+ private static class MediaDiscovererEventHandler extends WeakHandler<MediaDiscoverer> {
+ public MediaDiscovererEventHandler(MediaDiscoverer owner) {
+ super(owner);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ final MediaDiscoverer discover = getOwner();
+ if(discover != null)
+ discover.dispatchMessage(msg);
+ }
+ };
+
+ private void dispatchMessage(Message msg) {
+ if (mListener == null)
+ return;
+ final int event = msg.getData().getInt("event");
+ switch (event) {
+ case EventHandler.MediaDiscovererStarted:
+ mListener.onStarted();
+ break;
+ case EventHandler.MediaDiscovererEnded:
+ mListener.onEnded();
+ break;
+ case EventHandler.MediaDiscovererItemAdded:
+ case EventHandler.MediaDiscovererItemRemoved: {
+ final Item item = new Item(msg.getData().getString("item_uri"));
+ if (event == EventHandler.MediaDiscovererItemAdded)
+ mListener.onItemAdded(item);
+ else
+ mListener.onItemRemoved(item);
+ break;
+ }
+ case EventHandler.MediaDiscovererItemRemoveAll:
+ mListener.onRemoveAll();
+ break;
+ }
+ }
+
+ public MediaDiscoverer(LibVLC libVLC, Listener listener) {
+ mLibVLC = libVLC;
+ mListener = listener;
+ EventHandler.getInstance().addHandler(mWeakHandler);
+ }
+
+ public void create(String name) throws LibVlcException {
+ mLibVLC.mediaDiscoverCreate(name);
+ }
+
+ public void release() {
+ mLibVLC.mediaDiscoverRelease();
+ }
+
+ public void browse(String path) throws LibVlcException {
+ mLibVLC.mediaDiscoverBrowse(path);
+ }
+}
--
2.1.3
More information about the Android
mailing list