<p>It looks very nice, do you have a sample with changing ES so we can test?</p>
<div class="gmail_quote">Le 2 juil. 2012 14:29, "Edward Wang" <<a href="mailto:edward.c.wang@compdigitec.com">edward.c.wang@compdigitec.com</a>> a écrit :<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This will allow us to support dynamically ES-changing streams, more streaming formats (TS) and more video formats (such as OGG video).<br>
---<br>
 vlc-android/jni/libvlcjni.c                        |   12 ++++-<br>
 vlc-android/src/org/videolan/vlc/AudioService.java |   49 +++++++++++++++++++-<br>
 .../org/videolan/vlc/AudioServiceController.java   |   12 +++++<br>
 vlc-android/src/org/videolan/vlc/EventManager.java |    4 +-<br>
 vlc-android/src/org/videolan/vlc/LibVLC.java       |    4 ++<br>
 .../src/org/videolan/vlc/gui/MainActivity.java     |   28 ++++--------<br>
 .../vlc/gui/video/VideoPlayerActivity.java         |   46 ++++++++++++++++++-<br>
 .../org/videolan/vlc/interfaces/IAudioService.aidl |    1 +<br>
 8 files changed, 130 insertions(+), 26 deletions(-)<br>
<br>
diff --git a/vlc-android/jni/libvlcjni.c b/vlc-android/jni/libvlcjni.c<br>
index 1d07a82..18867ff 100644<br>
--- a/vlc-android/jni/libvlcjni.c<br>
+++ b/vlc-android/jni/libvlcjni.c<br>
@@ -164,6 +164,11 @@ static void vlc_event_callback(const libvlc_event_t *ev, void *data)<br>
     JNIEnv *env;<br>
     JavaVM *myVm = data;<br>
<br>
+    int ev_opt_data = 0;<br>
+    if(ev->type == libvlc_MediaPlayerVout) {<br>
+        /* For determining the vout/ES track change */<br>
+        ev_opt_data = ev->u.media_player_vout.new_count;<br>
+    }<br>
     bool isAttached = false;<br>
<br>
     if (eventManagerInstance == NULL)<br>
@@ -187,9 +192,9 @@ static void vlc_event_callback(const libvlc_event_t *ev, void *data)<br>
     }<br>
<br>
     /* Find the callback ID */<br>
-    jmethodID methodID = (*env)->GetMethodID(env, cls, "callback", "(I)V");<br>
+    jmethodID methodID = (*env)->GetMethodID(env, cls, "callback", "(II)V");<br>
     if (methodID) {<br>
-        (*env)->CallVoidMethod(env, eventManagerInstance, methodID, ev->type);<br>
+        (*env)->CallVoidMethod(env, eventManagerInstance, methodID, ev->type, ev_opt_data);<br>
     } else {<br>
         LOGE("EventManager: failed to get the callback method");<br>
     }<br>
@@ -365,7 +370,7 @@ void Java_org_videolan_vlc_LibVLC_setEventManager(JNIEnv *env, jobject thiz, job<br>
         return;<br>
     }<br>
<br>
-    jmethodID methodID = (*env)->GetMethodID(env, cls, "callback", "(I)V");<br>
+    jmethodID methodID = (*env)->GetMethodID(env, cls, "callback", "(II)V");<br>
     if (!methodID) {<br>
         LOGE("setEventManager: failed to get the callback method");<br>
         return;<br>
@@ -526,6 +531,7 @@ void Java_org_videolan_vlc_LibVLC_readMedia(JNIEnv *env, jobject thiz,<br>
         libvlc_MediaPlayerPaused,<br>
         libvlc_MediaPlayerEndReached,<br>
         libvlc_MediaPlayerStopped,<br>
+        libvlc_MediaPlayerVout,<br>
     };<br>
     int i;<br>
     for (i = 0; i < (sizeof(mp_events) / sizeof(*mp_events)); ++i)<br>
diff --git a/vlc-android/src/org/videolan/vlc/AudioService.java b/vlc-android/src/org/videolan/vlc/AudioService.java<br>
index a1f4226..c59e1d6 100644<br>
--- a/vlc-android/src/org/videolan/vlc/AudioService.java<br>
+++ b/vlc-android/src/org/videolan/vlc/AudioService.java<br>
@@ -30,6 +30,7 @@ import java.util.Stack;<br>
<br>
 import org.videolan.vlc.gui.MainActivity;<br>
 import org.videolan.vlc.gui.audio.AudioPlayerActivity;<br>
+import org.videolan.vlc.gui.video.VideoPlayerActivity;<br>
 import org.videolan.vlc.interfaces.IAudioService;<br>
 import org.videolan.vlc.interfaces.IAudioServiceCallback;<br>
 import org.videolan.vlc.widget.VLCAppWidgetProvider;<br>
@@ -277,6 +278,21 @@ public class AudioService extends Service {<br>
                     executeUpdate();<br>
                     next();<br>
                     break;<br>
+                case EventManager.MediaPlayerVout:<br>
+                    if(msg.getData().getInt("data") > 0) {<br>
+                        Log.i(TAG, "Obtained video track");<br>
+                        mMediaList.clear();<br>
+                        hideNotification();<br>
+<br>
+                        // Got video, switch to the video player<br>
+                        Intent intent = new Intent(VLCApplication.getAppContext(), VideoPlayerActivity.class);<br>
+                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);<br>
+                        intent.putExtra("itemLocation", mCurrentMedia.getLocation());<br>
+                        // Don't lose the currently playing stream<br>
+                        intent.putExtra("dontParse", true);<br>
+                        startActivity(intent);<br>
+                    }<br>
+                    break;<br>
                 default:<br>
                     Log.e(TAG, "Event not handled");<br>
                     break;<br>
@@ -611,8 +627,39 @@ public class AudioService extends Service {<br>
             }<br>
<br>
             if (mCurrentMedia != null)<br>
-                mLibVLC.readMedia(mCurrentMedia.getLocation(), true);<br>
+                mLibVLC.readMedia(mCurrentMedia.getLocation());<br>
+            showNotification();<br>
+        }<br>
+<br>
+        @Override<br>
+        public void showWithoutParse(String URI) throws RemoteException {<br>
+            Log.v(TAG, "Showing playing URI " + URI);<br>
+            // Show an URI without interrupting/losing the current stream<br>
+<br>
+            mEventManager.addHandler(mEventHandler);<br>
+            mMediaList.clear();<br>
+            mPrevious.clear();<br>
+            // Prevent re-parsing the media, which would mean losing the connection<br>
+            mCurrentMedia = new Media(<br>
+                    getApplicationContext(),<br>
+                    URI,<br>
+                    0,<br>
+                    0,<br>
+                    Media.TYPE_AUDIO,<br>
+                    null,<br>
+                    URI,<br>
+                    VLCApplication.getAppContext().getString(R.string.unknown_artist),<br>
+                    VLCApplication.getAppContext().getString(R.string.unknown_genre),<br>
+                    VLCApplication.getAppContext().getString(R.string.unknown_album),<br>
+                    0,<br>
+                    0,<br>
+                    "");<br>
+            mMediaList.add(mCurrentMedia);<br>
+<br>
+            // Notify everyone<br>
+            mHandler.sendEmptyMessage(SHOW_PROGRESS);<br>
             showNotification();<br>
+            executeUpdate();<br>
         }<br>
<br>
         @Override<br>
diff --git a/vlc-android/src/org/videolan/vlc/AudioServiceController.java b/vlc-android/src/org/videolan/vlc/AudioServiceController.java<br>
index 5f6ef61..98627e4 100644<br>
--- a/vlc-android/src/org/videolan/vlc/AudioServiceController.java<br>
+++ b/vlc-android/src/org/videolan/vlc/AudioServiceController.java<br>
@@ -212,6 +212,18 @@ public class AudioServiceController implements IAudioPlayerControl {<br>
         updateAudioPlayer();<br>
     }<br>
<br>
+    public void showWithoutParse(String u) {<br>
+        if (mAudioServiceBinder == null) {<br>
+            return;<br>
+        }<br>
+        try {<br>
+            mAudioServiceBinder.showWithoutParse(u);<br>
+        } catch (RemoteException e) {<br>
+            Log.e(TAG, "remote procedure call failed: showWithoutParse()");<br>
+        }<br>
+        updateAudioPlayer();<br>
+    }<br>
+<br>
     @Override<br>
     public String getAlbum() {<br>
         String album = null;<br>
diff --git a/vlc-android/src/org/videolan/vlc/EventManager.java b/vlc-android/src/org/videolan/vlc/EventManager.java<br>
index 6dcb44c..19e88a1 100644<br>
--- a/vlc-android/src/org/videolan/vlc/EventManager.java<br>
+++ b/vlc-android/src/org/videolan/vlc/EventManager.java<br>
@@ -57,6 +57,7 @@ public class EventManager {<br>
     //public static final int MediaPlayerTitleChanged         = 0x10f;<br>
     //public static final int MediaPlayerSnapshotTaken        = 0x110;<br>
     //public static final int MediaPlayerLengthChanged        = 0x111;<br>
+    public static final int MediaPlayerVout                   = 0x112;<br>
<br>
     //public static final int MediaListItemAdded              = 0x200;<br>
     //public static final int MediaListWillAddItem            = 0x201;<br>
@@ -111,9 +112,10 @@ public class EventManager {<br>
     }<br>
<br>
     /** This method is called by a native thread **/<br>
-    public void callback(int event) {<br>
+    public void callback(int event, int optional_data) {<br>
         Bundle b = new Bundle();<br>
         b.putInt("event", event);<br>
+        b.putInt("data", optional_data);<br>
         for (int i = 0; i < mEventHandler.size(); i++) {<br>
             Message msg = Message.obtain();<br>
             msg.setData(b);<br>
diff --git a/vlc-android/src/org/videolan/vlc/LibVLC.java b/vlc-android/src/org/videolan/vlc/LibVLC.java<br>
index cd9444f..211c255 100644<br>
--- a/vlc-android/src/org/videolan/vlc/LibVLC.java<br>
+++ b/vlc-android/src/org/videolan/vlc/LibVLC.java<br>
@@ -229,6 +229,10 @@ public class LibVLC {<br>
         mAout.release();<br>
     }<br>
<br>
+    public void readMedia(String mrl) {<br>
+        readMedia(mLibVlcInstance, mrl, false);<br>
+    }<br>
+<br>
     /**<br>
      * Read a media.<br>
      */<br>
diff --git a/vlc-android/src/org/videolan/vlc/gui/MainActivity.java b/vlc-android/src/org/videolan/vlc/gui/MainActivity.java<br>
index f9720b0..2179cba 100644<br>
--- a/vlc-android/src/org/videolan/vlc/gui/MainActivity.java<br>
+++ b/vlc-android/src/org/videolan/vlc/gui/MainActivity.java<br>
@@ -20,7 +20,6 @@<br>
<br>
 package org.videolan.vlc.gui;<br>
<br>
-import java.io.IOException;<br>
 import java.util.ArrayList;<br>
<br>
 import org.videolan.vlc.AudioService;<br>
@@ -34,7 +33,6 @@ import org.videolan.vlc.VLCCallbackTask;<br>
 import org.videolan.vlc.gui.audio.AudioBrowserFragment;<br>
 import org.videolan.vlc.gui.video.VideoListAdapter;<br>
 import org.videolan.vlc.gui.video.VideoListFragment;<br>
-import org.videolan.vlc.gui.video.VideoPlayerActivity;<br>
 import org.videolan.vlc.interfaces.ISortable;<br>
 import org.videolan.vlc.widget.AudioMiniPlayer;<br>
<br>
@@ -479,23 +477,15 @@ public class MainActivity extends SherlockFragmentActivity {<br>
                             AudioServiceController c = AudioServiceController.getInstance();<br>
                             String s = input.getText().toString();<br>
<br>
-                            try {<br>
-                                if(!LibVLC.getExistingInstance().hasVideoTrack(s)) {<br>
-                                    Log.d(TAG, "Auto-detected audio for " + s);<br>
-                                    ArrayList<String> media = new ArrayList<String>();<br>
-                                    media.add(input.getText().toString());<br>
-                                    c.append(media);<br>
-                                } else {<br>
-                                    Log.d(TAG, "Auto-detected Video for " + s);<br>
-                                    Intent intent = new Intent(getApplicationContext(),<br>
-                                                               VideoPlayerActivity.class);<br>
-                                    intent.putExtra("itemLocation", s);<br>
-                                    startActivity(intent);<br>
-                                }<br>
-                            } catch(IOException e) {<br>
-                                /* VLC is unable to open the MRL */<br>
-                                return;<br>
-                            }<br>
+                            /* Use the audio player by default. If a video track is<br>
+                             * detected, then it will automatically switch to the video<br>
+                             * player. This allows us to support more types of streams<br>
+                             * (for example, RTSP and TS streaming) where ES can be<br>
+                             * dynamically adapted rather than a simple scan.<br>
+                             */<br>
+                            ArrayList<String> media = new ArrayList<String>();<br>
+                            media.add(s);<br>
+                            c.append(media);<br>
                         }<br>
<br>
                         @Override<br>
diff --git a/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java b/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java<br>
index 3612444..104c6ad 100644<br>
--- a/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java<br>
+++ b/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java<br>
@@ -25,12 +25,14 @@ import java.io.UnsupportedEncodingException;<br>
 import java.lang.reflect.Method;<br>
 import java.net.URLDecoder;<br>
<br>
+import org.videolan.vlc.AudioServiceController;<br>
 import org.videolan.vlc.EventManager;<br>
 import org.videolan.vlc.LibVLC;<br>
 import org.videolan.vlc.LibVlcException;<br>
 import org.videolan.vlc.R;<br>
 import org.videolan.vlc.Util;<br>
 import org.videolan.vlc.gui.PreferencesActivity;<br>
+import org.videolan.vlc.gui.audio.AudioPlayerActivity;<br>
 import org.videolan.vlc.interfaces.IPlayerControl;<br>
 import org.videolan.vlc.interfaces.OnPlayerControlListener;<br>
 import org.videolan.vlc.widget.PlayerControlClassic;<br>
@@ -114,6 +116,13 @@ public class VideoPlayerActivity extends Activity {<br>
     private ImageButton mLock;<br>
     private ImageButton mSize;<br>
<br>
+    // what video?<br>
+    private String mLocation;<br>
+    /**<br>
+     * For uninterrupted switching between audio and video mode<br>
+     */<br>
+    private boolean mSwitchingView;<br>
+<br>
     // size of the video<br>
     private int mVideoHeight;<br>
     private int mVideoWidth;<br>
@@ -200,10 +209,15 @@ public class VideoPlayerActivity extends Activity {<br>
     protected void onStart() {<br>
         super.onStart();<br>
         dimStatusBar(true);<br>
+        mSwitchingView = false;<br>
     }<br>
<br>
     @Override<br>
     protected void onPause() {<br>
+        if(mSwitchingView) {<br>
+            super.onPause();<br>
+            return;<br>
+        }<br>
         long time = 0;<br>
         if (mLibVLC.isPlaying()) {<br>
             time = mLibVLC.getTime() - 5000;<br>
@@ -222,7 +236,7 @@ public class VideoPlayerActivity extends Activity {<br>
     @Override<br>
     protected void onDestroy() {<br>
         unregisterReceiver(mBatteryReceiver);<br>
-        if (mLibVLC != null) {<br>
+        if (mLibVLC != null && !mSwitchingView) {<br>
             mLibVLC.stop();<br>
         }<br>
<br>
@@ -231,9 +245,23 @@ public class VideoPlayerActivity extends Activity {<br>
<br>
         mAudioManager = null;<br>
<br>
+        if(mSwitchingView) {<br>
+            Log.d(TAG, "mLocation = \"" + mLocation + "\"");<br>
+            AudioServiceController.getInstance().showWithoutParse(mLocation);<br>
+            Intent i = new Intent(this, AudioPlayerActivity.class);<br>
+            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);<br>
+            startActivity(i);<br>
+        }<br>
+        //AudioServiceController.getInstance().unbindAudioService(this);<br>
         super.onDestroy();<br>
     }<br>
<br>
+    @Override<br>
+    protected void onResume() {<br>
+        AudioServiceController.getInstance().bindAudioService(this);<br>
+        super.onResume();<br>
+    }<br>
+<br>
     private final BroadcastReceiver mBatteryReceiver = new BroadcastReceiver()<br>
     {<br>
         @Override<br>
@@ -372,6 +400,14 @@ public class VideoPlayerActivity extends Activity {<br>
                     /* Exit player when reach the end */<br>
                     VideoPlayerActivity.this.finish();<br>
                     break;<br>
+                case EventManager.MediaPlayerVout:<br>
+                    if(msg.getData().getInt("data") == 0) {<br>
+                        /* Video track lost, open in audio mode */<br>
+                        Log.i(TAG, "Video track lost, switching to audio");<br>
+                        VideoPlayerActivity.this.mSwitchingView = true;<br>
+                        VideoPlayerActivity.this.finish();<br>
+                    }<br>
+                    break;<br>
                 default:<br>
                     Log.e(TAG, "Event not handled");<br>
                     break;<br>
@@ -830,6 +866,7 @@ public class VideoPlayerActivity extends Activity {<br>
         String location = null;<br>
         String title = null;<br>
         String lastLocation = null;<br>
+        mSwitchingView = false;<br>
         long lastTime = 0;<br>
         SharedPreferences preferences = getSharedPreferences(PreferencesActivity.NAME, MODE_PRIVATE);<br>
<br>
@@ -842,10 +879,15 @@ public class VideoPlayerActivity extends Activity {<br>
             location = getIntent().getExtras().getString("itemLocation");<br>
         }<br>
<br>
-        if (location != null && location.length() > 0) {<br>
+        boolean dontParse = getIntent().getExtras().getBoolean("dontParse");<br>
+        if(dontParse)<br>
+            mLocation = location;<br>
+        if (location != null && location.length() > 0 && !dontParse) {<br>
             mLibVLC.readMedia(location, false);<br>
             mSurface.setKeepScreenOn(true);<br>
<br>
+            mLocation = location;<br>
+<br>
             // Save media for next time, and restore position if it's the same one as before<br>
             lastLocation = preferences.getString(PreferencesActivity.LAST_MEDIA, null);<br>
             lastTime = preferences.getLong(PreferencesActivity.LAST_TIME, 0);<br>
diff --git a/vlc-android/src/org/videolan/vlc/interfaces/IAudioService.aidl b/vlc-android/src/org/videolan/vlc/interfaces/IAudioService.aidl<br>
index 4525d94..600dc42 100644<br>
--- a/vlc-android/src/org/videolan/vlc/interfaces/IAudioService.aidl<br>
+++ b/vlc-android/src/org/videolan/vlc/interfaces/IAudioService.aidl<br>
@@ -50,4 +50,5 @@ interface IAudioService {<br>
     void addAudioCallback(IAudioServiceCallback cb);<br>
     void removeAudioCallback(IAudioServiceCallback cb);<br>
     void detectHeadset(boolean enable);<br>
+    void showWithoutParse(String URI);<br>
 }<br>
--<br>
1.7.5.4<br>
<br>
_______________________________________________<br>
Android mailing list<br>
<a href="mailto:Android@videolan.org">Android@videolan.org</a><br>
<a href="http://mailman.videolan.org/listinfo/android" target="_blank">http://mailman.videolan.org/listinfo/android</a><br>
</blockquote></div>