[Android] [PATCH] Add open stream feature in UI

Edward Wang edward.c.wang at compdigitec.com
Sun Mar 11 00:47:16 CET 2012


---
 vlc-android/res/menu/media_library.xml             |    4 +
 vlc-android/res/values/strings.xml                 |    1 +
 vlc-android/src/org/videolan/vlc/AudioService.java |   12 ++-
 vlc-android/src/org/videolan/vlc/Media.java        |   82 +++++++++++++++++++-
 .../src/org/videolan/vlc/gui/MainActivity.java     |   28 +++++++
 .../vlc/gui/audio/AudioBrowserActivity.java        |    4 +-
 6 files changed, 122 insertions(+), 9 deletions(-)

diff --git a/vlc-android/res/menu/media_library.xml b/vlc-android/res/menu/media_library.xml
index 06c0166..bc2ee09 100644
--- a/vlc-android/res/menu/media_library.xml
+++ b/vlc-android/res/menu/media_library.xml
@@ -25,4 +25,8 @@
         android:id="@+id/ml_menu_refresh"
         android:icon="@drawable/ic_menu_refresh"
         android:title="@string/refresh" />
+    <item
+        android:id="@+id/ml_menu_open_stream"
+        android:icon="@android:drawable/ic_btn_speak_now"
+        android:title="@string/open_stream" />
 </menu>
diff --git a/vlc-android/res/values/strings.xml b/vlc-android/res/values/strings.xml
index 541132b..b1810ac 100644
--- a/vlc-android/res/values/strings.xml
+++ b/vlc-android/res/values/strings.xml
@@ -78,4 +78,5 @@
     <string name="track_video_info">Codec: %1$s\nResolution: %2$dx%3$d</string>
     <string name="track_text">Subtitles track</string>
     <string name="track_unknown">Unknown track</string>
+    <string name="open_stream">Open Stream</string>
 </resources>
diff --git a/vlc-android/src/org/videolan/vlc/AudioService.java b/vlc-android/src/org/videolan/vlc/AudioService.java
index 233c276..cd681d2 100644
--- a/vlc-android/src/org/videolan/vlc/AudioService.java
+++ b/vlc-android/src/org/videolan/vlc/AudioService.java
@@ -292,7 +292,7 @@ public class AudioService extends Service {
                 return;
             }
         }
-        mLibVLC.readMedia(mCurrentMedia.getPath());
+        mLibVLC.readMedia(mCurrentMedia.getMRL());
         mHandler.sendEmptyMessage(SHOW_PROGRESS);
         showNotification();
         updateWidget(this);
@@ -306,7 +306,7 @@ public class AudioService extends Service {
             mCurrentMedia = mMediaList.get(index - 1);
         else
             return;
-        mLibVLC.readMedia(mCurrentMedia.getPath());
+        mLibVLC.readMedia(mCurrentMedia.getMRL());
         mHandler.sendEmptyMessage(SHOW_PROGRESS);
         showNotification();
         updateWidget(this);
@@ -418,7 +418,7 @@ public class AudioService extends Service {
             if (mCurrentMedia != null)
                 return mCurrentMedia.getTitle();
             else
-                return null;
+                return "(null)";
         }
 
         public Bitmap getCover() {
@@ -470,6 +470,10 @@ public class AudioService extends Service {
             for (int i = 0; i < mediaPathList.size(); i++) {
                 String path = mediaPathList.get(i);
                 Media media = db.getMedia(AudioService.this, path);
+                if(media == null) {
+                    Log.v(TAG, "Creating remote Media object for " + path);
+                    media = new Media(AudioService.this, path);
+                }
                 mMediaList.add(media);
             }
 
@@ -478,7 +482,7 @@ public class AudioService extends Service {
             }
 
             if (mCurrentMedia != null)
-                mLibVLC.readMedia(mCurrentMedia.getPath());
+                mLibVLC.readMedia(mCurrentMedia.getMRL());
             showNotification();
         }
 
diff --git a/vlc-android/src/org/videolan/vlc/Media.java b/vlc-android/src/org/videolan/vlc/Media.java
index 9f1662c..25c2cdc 100644
--- a/vlc-android/src/org/videolan/vlc/Media.java
+++ b/vlc-android/src/org/videolan/vlc/Media.java
@@ -21,6 +21,8 @@
 package org.videolan.vlc;
 
 import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
 
 import android.content.Context;
 import android.graphics.Bitmap;
@@ -63,6 +65,7 @@ public class Media implements Comparable<Media> {
     private String mTrackID;
 
     private File mFile;
+    private String mMRL;
     private long mTime = 0;
     private long mLength = 0;
     private int mType;
@@ -76,7 +79,10 @@ public class Media implements Comparable<Media> {
      */
     public Media(Context context, File file) {
         this.mFile = file;
-
+        // LibVLC expects the file:///sdcard/... format, but by default
+        // Java gives file:/sdcard, which angers LibVLC
+        mMRL = file.toURI().toString().replace("file:/", "file:///");
+        
         LibVLC mLibVlc = null;
         try {
             mLibVlc = LibVLC.getInstance();
@@ -112,10 +118,57 @@ public class Media implements Comparable<Media> {
         DatabaseManager db = DatabaseManager.getInstance(context);
         db.addMedia(this);
     }
+    
+    /**
+     * Create a new remote Media
+     * @param file: any valid MRL that LibVLC accepts
+     */
+    public Media(Context context, String _mrl) {
+        this.mFile = null;
+        this.mMRL = _mrl;
+
+        LibVLC mLibVlc = null;
+        try {
+            mLibVlc = LibVLC.getInstance();
+            mType = (mLibVlc.hasVideoTrack(mMRL)) ? TYPE_VIDEO : TYPE_AUDIO;
+            mLength = mLibVlc.getLengthFromFile(mMRL);
+
+            String[] array = mLibVlc.readMediaMeta(mMRL);
+
+            int i;
+            for (i = 0; i < array.length; i++) {
+                String s = array[i++];
+                String v = array[i];
+
+                if (s.equals("title")) {
+                    mTitle = v;
+                    Log.d(TAG, "Title " + mTitle);
+                } else if (s.equals("artist")) {
+                    mArtist = Util.getValue(context, v, R.string.unknown_artist);
+                    Log.d(TAG, "Artist " + mArtist);
+                } else if (s.equals("genre")) {
+                    mGenre = Util.getValue(context, v, R.string.unknown_genre);
+                    Log.d(TAG, "Genre " + mGenre);
+                } else if (s.equals("album")) {
+                    mAlbum = Util.getValue(context, v, R.string.unknown_album);
+                    Log.d(TAG, "Album " + mAlbum);
+                }
+            }
+        } catch (LibVlcException e) {
+            e.printStackTrace();
+        }
+
+        // Add this item to database
+        //DatabaseManager db = DatabaseManager.getInstance(context);
+        //db.addMedia(this);
+    }
 
     public Media(Context context, File file, long time, long length, int type,
             Bitmap picture, String title, String artist, String genre, String album) {
         mFile = file;
+        // LibVLC expects the file:///sdcard/... format, but by default
+        // Java gives file:/sdcard, which angers LibVLC
+        mMRL = file.toURI().toString().replace("file:/", "file:///");
         mTime = time;
         mLength = length;
         mType = type;
@@ -134,13 +187,33 @@ public class Media implements Comparable<Media> {
         return mTitle.toUpperCase().compareTo(
                 another.getTitle().toUpperCase());
     }
+    
+    /**
+     * Convert to string for debugging aid
+     */
+    public String toString() {
+        String buf = "";
+        buf += "Media information:\n";
+        buf += "Media Path: " + ((mFile == null) ? "none" : mFile.getPath());
+        buf += "Media MRL: " + mMRL.toString();
+        buf += "Media Title: " + mTitle;
+        return buf;
+    }
 
     public File getFile() {
         return mFile;
     }
 
     public String getPath() {
-        return mFile.getPath();
+        if(mFile == null) {
+            return mMRL;
+        } else {
+            return mFile.getPath();
+        }
+    }
+    
+    public String getMRL() {
+        return mMRL;
     }
 
     public void updateMeta() {
@@ -190,7 +263,10 @@ public class Media implements Comparable<Media> {
 
     public String getTitle() {
         if (mTitle == null)
-            return mFile.getName().substring(0, mFile.getName().lastIndexOf('.'));
+            if (mFile != null)
+                return mFile.getName().substring(0, mFile.getName().lastIndexOf('.'));
+            else
+                return mMRL;
         else
             return mTitle;
     }
diff --git a/vlc-android/src/org/videolan/vlc/gui/MainActivity.java b/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
index 2660948..42049a5 100644
--- a/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
@@ -20,8 +20,12 @@
 
 package org.videolan.vlc.gui;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.videolan.vlc.AudioServiceController;
 import org.videolan.vlc.LibVLC;
+import org.videolan.vlc.LibVlcException;
 import org.videolan.vlc.MediaLibrary;
 import org.videolan.vlc.R;
 import org.videolan.vlc.gui.audio.AudioActivityGroup;
@@ -33,10 +37,12 @@ import org.videolan.vlc.widget.AudioMiniPlayer;
 
 import android.app.Activity;
 import android.app.ActivityGroup;
+import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.TabActivity;
 import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.SharedPreferences;
@@ -232,6 +238,28 @@ public class MainActivity extends TabActivity {
             case R.id.ml_menu_refresh:
                 MediaLibrary.getInstance(this).loadMediaItems(this);
                 break;
+            case R.id.ml_menu_open_stream:
+                AlertDialog.Builder b = new AlertDialog.Builder(this);
+                final android.widget.EditText input = new android.widget.EditText(this);
+                b.setTitle("Resource MRL");
+                b.setMessage("e.g. rtsp:// or http://");
+                b.setView(input);
+                b.setPositiveButton("Open", new DialogInterface.OnClickListener() {
+                        public void onClick(DialogInterface dialog, int button) {
+                            AudioServiceController c = AudioServiceController.getInstance();
+                            ArrayList<String> media = new ArrayList<String>();
+                            media.add(input.getText().toString());
+                            c.append(media);
+                        }
+                    }
+                );
+                b.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface arg0, int arg1) {
+                        return;
+                    }});
+                b.show();
+                break;
         }
         return super.onOptionsItemSelected(item);
     }
diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserActivity.java b/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserActivity.java
index 0e9a76f..e486257 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserActivity.java
@@ -20,6 +20,7 @@
 
 package org.videolan.vlc.gui.audio;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
@@ -192,8 +193,7 @@ public class AudioBrowserActivity extends Activity implements ISortable {
         else
             mAudioController.load(medias, start_position);
 
-        Intent intent = new Intent(AudioBrowserActivity.this, AudioPlayerActivity.class);
-        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        Intent intent = new Intent(AudioBrowserActivity.this, AudioPlayerActivity.class);        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
         startActivity(intent);
         return super.onContextItemSelected(item);
     }
-- 
1.7.5.4



More information about the Android mailing list