[Android] [PATCH 03/13] refactor Media/MediaList/MediaListPlayer

Thomas Guillem thomas at gllm.fr
Thu Jan 15 19:22:20 CET 2015


Prepare for new Media* class that follow libvlc API.

Rename Media to MediaHolder since it will be a holder of the future Media class.

Move these classes from libvlc to vlc-android since these class depends too
much of the vlc application. Indeed there are mainly used by MediaDatabase that
belongs to application and not the lib.
---
 libvlc/src/org/videolan/libvlc/EventHandler.java   |   2 +-
 libvlc/src/org/videolan/libvlc/LibVLC.java         |   3 +-
 libvlc/src/org/videolan/libvlc/Media.aidl          |  23 -
 libvlc/src/org/videolan/libvlc/Media.java          | 478 --------------------
 libvlc/src/org/videolan/libvlc/MediaList.java      | 159 -------
 .../src/org/videolan/libvlc/MediaListPlayer.java   |  89 ----
 .../src/org/videolan/vlc/MediaDatabase.java        |  22 +-
 vlc-android/src/org/videolan/vlc/MediaGroup.java   |  25 +-
 vlc-android/src/org/videolan/vlc/MediaHolder.aidl  |  23 +
 vlc-android/src/org/videolan/vlc/MediaHolder.java  | 482 +++++++++++++++++++++
 .../src/org/videolan/vlc/MediaHolderList.java      | 159 +++++++
 .../org/videolan/vlc/MediaHolderListPlayer.java    |  91 ++++
 vlc-android/src/org/videolan/vlc/MediaLibrary.java |  45 +-
 vlc-android/src/org/videolan/vlc/Thumbnailer.java  |   7 +-
 .../src/org/videolan/vlc/audio/AudioService.java   |  40 +-
 .../videolan/vlc/audio/AudioServiceController.java |  10 +-
 .../src/org/videolan/vlc/gui/DirectoryAdapter.java |   8 +-
 .../src/org/videolan/vlc/gui/HistoryAdapter.java   |  10 +-
 .../src/org/videolan/vlc/gui/SearchFragment.java   |  14 +-
 .../org/videolan/vlc/gui/SearchResultAdapter.java  |  10 +-
 .../vlc/gui/audio/AudioAlbumsSongsFragment.java    |  10 +-
 .../vlc/gui/audio/AudioBrowserFragment.java        |  10 +-
 .../vlc/gui/audio/AudioBrowserListAdapter.java     |  32 +-
 .../org/videolan/vlc/gui/audio/AudioPlayer.java    |   6 +-
 .../vlc/gui/audio/AudioPlaylistAdapter.java        |  14 +-
 .../src/org/videolan/vlc/gui/audio/AudioUtil.java  |  12 +-
 .../videolan/vlc/gui/audio/MediaComparators.java   |  30 +-
 .../videolan/vlc/gui/video/MediaInfoFragment.java  |   6 +-
 .../vlc/gui/video/VideoBrowserInterface.java       |   4 +-
 .../videolan/vlc/gui/video/VideoGridFragment.java  |  26 +-
 .../videolan/vlc/gui/video/VideoListAdapter.java   |  18 +-
 .../vlc/gui/video/VideoPlayerActivity.java         |  14 +-
 .../org/videolan/vlc/interfaces/IAudioService.aidl |   4 +-
 .../vlc/interfaces/IAudioServiceCallback.aidl      |   4 +-
 .../src/org/videolan/vlc/util/BitmapUtil.java      |   4 +-
 vlc-android/src/org/videolan/vlc/util/Util.java    |  22 +-
 36 files changed, 958 insertions(+), 958 deletions(-)
 delete mode 100644 libvlc/src/org/videolan/libvlc/Media.aidl
 delete mode 100644 libvlc/src/org/videolan/libvlc/Media.java
 delete mode 100644 libvlc/src/org/videolan/libvlc/MediaList.java
 delete mode 100644 libvlc/src/org/videolan/libvlc/MediaListPlayer.java
 create mode 100644 vlc-android/src/org/videolan/vlc/MediaHolder.aidl
 create mode 100644 vlc-android/src/org/videolan/vlc/MediaHolder.java
 create mode 100644 vlc-android/src/org/videolan/vlc/MediaHolderList.java
 create mode 100644 vlc-android/src/org/videolan/vlc/MediaHolderListPlayer.java

diff --git a/libvlc/src/org/videolan/libvlc/EventHandler.java b/libvlc/src/org/videolan/libvlc/EventHandler.java
index 6242b2d..2141439 100644
--- a/libvlc/src/org/videolan/libvlc/EventHandler.java
+++ b/libvlc/src/org/videolan/libvlc/EventHandler.java
@@ -97,7 +97,7 @@ public class EventHandler {
     private ArrayList<Handler> mEventHandler;
     private static EventHandler mInstance;
 
-    EventHandler() {
+    public EventHandler() {
         mEventHandler = new ArrayList<Handler>();
     }
 
diff --git a/libvlc/src/org/videolan/libvlc/LibVLC.java b/libvlc/src/org/videolan/libvlc/LibVLC.java
index 78e1bc5..702d727 100644
--- a/libvlc/src/org/videolan/libvlc/LibVLC.java
+++ b/libvlc/src/org/videolan/libvlc/LibVLC.java
@@ -796,6 +796,5 @@ public class LibVLC {
     public native int setWindowSize(int width, int height);
 
     /* MediaList */
-    protected native void loadPlaylist(String mrl, ArrayList<String> items);
-    protected native int expandMedia(ArrayList<String> children);
+    public native int expandMedia(ArrayList<String> children);
 }
diff --git a/libvlc/src/org/videolan/libvlc/Media.aidl b/libvlc/src/org/videolan/libvlc/Media.aidl
deleted file mode 100644
index 9b30419..0000000
--- a/libvlc/src/org/videolan/libvlc/Media.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-/*****************************************************************************
- * Media.aidl
- *****************************************************************************
- * Copyright © 2015 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.
- *****************************************************************************/
-
-package org.videolan.libvlc;
-
-parcelable Media;
diff --git a/libvlc/src/org/videolan/libvlc/Media.java b/libvlc/src/org/videolan/libvlc/Media.java
deleted file mode 100644
index 62ba1e5..0000000
--- a/libvlc/src/org/videolan/libvlc/Media.java
+++ /dev/null
@@ -1,478 +0,0 @@
-/*****************************************************************************
- * Media.java
- *****************************************************************************
- * Copyright © 2011-2013 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.
- *****************************************************************************/
-
-package org.videolan.libvlc;
-
-import java.util.HashSet;
-import java.util.Locale;
-
-import android.graphics.Bitmap;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.Log;
-
-public class Media implements Parcelable {
-    public final static String TAG = "VLC/LibVLC/Media";
-
-    public final static HashSet<String> VIDEO_EXTENSIONS;
-    public final static HashSet<String> AUDIO_EXTENSIONS;
-    public final static HashSet<String> SUBTITLES_EXTENSIONS;
-
-    static {
-        final String[] video_extensions = {
-                ".3g2", ".3gp", ".3gp2", ".3gpp", ".amv", ".asf", ".avi", ".divx", ".drc", ".dv",
-                ".f4v", ".flv", ".gvi", ".gxf", ".ismv", ".iso", ".m1v", ".m2v", ".m2t", ".m2ts",
-                ".m4v", ".mkv", ".mov", ".mp2", ".mp2v", ".mp4", ".mp4v", ".mpe", ".mpeg",
-                ".mpeg1", ".mpeg2", ".mpeg4", ".mpg", ".mpv2", ".mts", ".mtv", ".mxf", ".mxg",
-                ".nsv", ".nut", ".nuv", ".ogm", ".ogv", ".ogx", ".ps", ".rec", ".rm", ".rmvb",
-                ".tod", ".ts", ".tts", ".vob", ".vro", ".webm", ".wm", ".wmv", ".wtv", ".xesc" };
-
-        final String[] audio_extensions = {
-                ".3ga", ".a52", ".aac", ".ac3", ".adt", ".adts", ".aif", ".aifc", ".aiff", ".amr",
-                ".aob", ".ape", ".awb", ".caf", ".dts", ".flac", ".it", ".m4a", ".m4b", ".m4p",
-                ".mid", ".mka", ".mlp", ".mod", ".mpa", ".mp1", ".mp2", ".mp3", ".mpc", ".mpga",
-                ".oga", ".ogg", ".oma", ".opus", ".ra", ".ram", ".rmi", ".s3m", ".spx", ".tta",
-                ".voc", ".vqf", ".w64", ".wav", ".wma", ".wv", ".xa", ".xm" };
-
-        final String[] subtitles_extensions = {
-                "idx", "sub",  "srt", "ssa", "ass",  "smi", "utf", "utf8", "utf-8",
-                "rt",   "aqt", "txt", "usf", "jss",  "cdg", "psb", "mpsub","mpl2",
-                "pjs", "dks", "stl", "vtt" };
-
-        VIDEO_EXTENSIONS = new HashSet<String>();
-        for (String item : video_extensions)
-            VIDEO_EXTENSIONS.add(item);
-        AUDIO_EXTENSIONS = new HashSet<String>();
-        for (String item : audio_extensions)
-            AUDIO_EXTENSIONS.add(item);
-        SUBTITLES_EXTENSIONS = new HashSet<String>();
-        for (String item : subtitles_extensions)
-            SUBTITLES_EXTENSIONS.add(item);
-    }
-
-    public final static int TYPE_ALL = -1;
-    public final static int TYPE_VIDEO = 0;
-    public final static int TYPE_AUDIO = 1;
-    public final static int TYPE_GROUP = 2;
-
-    /** Metadata from libvlc_media */
-    protected String mTitle;
-    private String mArtist;
-    private String mGenre;
-    private String mCopyright;
-    private String mAlbum;
-    private int mTrackNumber;
-    private String mAlbumArtist;
-    private String mDescription;
-    private String mRating;
-    private String mDate;
-    private String mSettings;
-    private String mNowPlaying;
-    private String mPublisher;
-    private String mEncodedBy;
-    private String mTrackID;
-    private String mArtworkURL;
-
-    public final static int libvlc_meta_Title       = 0;
-    public final static int libvlc_meta_Artist      = 1;
-    public final static int libvlc_meta_Genre       = 2;
-//    public final static int libvlc_meta_Copyright   = 3;
-    public final static int libvlc_meta_Album       = 4;
-//    public final static int libvlc_meta_TrackNumber = 5;
-//    public final static int libvlc_meta_Description = 6;
-//    public final static int libvlc_meta_Rating      = 7;
-//    public final static int libvlc_meta_Date        = 8;
-//    public final static int libvlc_meta_Setting     = 9;
-//    public final static int libvlc_meta_URL         = 10;
-//    public final static int libvlc_meta_Language    = 11;
-    public final static int libvlc_meta_NowPlaying  = 12;
-//    public final static int libvlc_meta_Publisher   = 13;
-//    public final static int libvlc_meta_EncodedBy   = 14;
-    public final static int libvlc_meta_ArtworkURL  = 15;
-//    public final static int libvlc_meta_TrackID     = 16;
-//    public final static int libvlc_meta_TrackTotal  = 17;
-//    public final static int libvlc_meta_Director    = 18;
-//    public final static int libvlc_meta_Season      = 19;
-//    public final static int libvlc_meta_Episode     = 20;
-//    public final static int libvlc_meta_ShowName    = 21;
-//    public final static int libvlc_meta_Actors      = 22;
-    public final static int libvlc_meta_AlbumArtist = 23;
-//    public final static int libvlc_meta_DiscNumber  = 24;
-
-    private final String mLocation;
-    private String mFilename;
-    private long mTime = 0;
-    private int mAudioTrack = -1;
-    private int mSpuTrack = -2;
-    private long mLength = 0;
-    private int mType;
-    private int mWidth = 0;
-    private int mHeight = 0;
-    private Bitmap mPicture;
-    private boolean mIsPictureParsed;
-    private int mFlags = 0;
-
-    /**
-     * Create a new Media
-     * @param libVLC A pointer to the libVLC instance. Should not be NULL
-     * @param URI The URI of the media.
-     */
-    public Media(LibVLC libVLC, String URI) {
-        if(libVLC == null)
-            throw new NullPointerException("libVLC was null");
-
-        mLocation = URI;
-
-        mType = TYPE_ALL;
-        TrackInfo[] tracks = libVLC.readTracksInfo(mLocation);
-
-        extractTrackInfo(tracks);
-    }
-
-    private void extractTrackInfo(TrackInfo[] tracks) {
-        if (tracks == null) {
-            mTitle = null;
-            mArtist = null;
-            mAlbum = null;
-            mGenre = null;
-            mAlbumArtist = null;
-            return;
-        }
-
-        for (TrackInfo track : tracks) {
-            if (track.Type == TrackInfo.TYPE_VIDEO) {
-                mType = TYPE_VIDEO;
-                mWidth = track.Width;
-                mHeight = track.Height;
-            } else if (mType == TYPE_ALL && track.Type == TrackInfo.TYPE_AUDIO){
-                mType = TYPE_AUDIO;
-            } else if (track.Type == TrackInfo.TYPE_META) {
-                mLength = track.Length;
-                mTitle = track.Title != null ? track.Title.trim() : null;
-                mArtist = track.Artist != null ? track.Artist.trim() : null;
-                mAlbum = track.Album != null ? track.Album.trim() : null;
-                mGenre = track.Genre != null ? track.Genre.trim() : null;
-                mAlbumArtist = track.AlbumArtist != null ? track.AlbumArtist.trim() : null;
-                mArtworkURL = track.ArtworkURL;
-                mNowPlaying = track.NowPlaying;
-                if (!TextUtils.isEmpty(track.TrackNumber)) {
-                    try {
-                        mTrackNumber = Integer.parseInt(track.TrackNumber);
-                    } catch (NumberFormatException ignored) {
-                    }
-                }
-                Log.d(TAG, "Title " + mTitle);
-                Log.d(TAG, "Artist " + mArtist);
-                Log.d(TAG, "Genre " + mGenre);
-                Log.d(TAG, "Album " + mAlbum);
-            }
-        }
-
-        /* No useful ES found */
-        if (mType == TYPE_ALL) {
-            int dotIndex = mLocation.lastIndexOf(".");
-            if (dotIndex != -1) {
-                String fileExt = mLocation.substring(dotIndex).toLowerCase(Locale.ENGLISH);
-                if( Media.VIDEO_EXTENSIONS.contains(fileExt) ) {
-                    mType = TYPE_VIDEO;
-                } else if (Media.AUDIO_EXTENSIONS.contains(fileExt)) {
-                    mType = TYPE_AUDIO;
-                }
-            }
-        }
-    }
-
-    private void init(long time, long length, int type,
-                      Bitmap picture, String title, String artist, String genre, String album, String albumArtist,
-                      int width, int height, String artworkURL, int audio, int spu, int trackNumber) {
-        mFilename = null;
-        mTime = time;
-        mAudioTrack = audio;
-        mSpuTrack = spu;
-        mLength = length;
-        mType = type;
-        mPicture = picture;
-        mWidth = width;
-        mHeight = height;
-
-        mTitle = title;
-        mArtist = artist;
-        mGenre = genre;
-        mAlbum = album;
-        mAlbumArtist = albumArtist;
-        mArtworkURL = artworkURL;
-        mTrackNumber = trackNumber;
-    }
-
-    public Media(String location, long time, long length, int type,
-                 Bitmap picture, String title, String artist, String genre, String album, String albumArtist,
-                 int width, int height, String artworkURL, int audio, int spu, int trackNumber) {
-        mLocation = location;
-        init(time, length, type, picture, title, artist, genre, album, albumArtist,
-             width, height, artworkURL, audio, spu, trackNumber);
-    }
-
-    public Media(Parcel in) {
-        mLocation = in.readString();
-        init(in.readLong(),
-             in.readLong(),
-             in.readInt(),
-             (Bitmap) in.readParcelable(Bitmap.class.getClassLoader()),
-             in.readString(),
-             in.readString(),
-             in.readString(),
-             in.readString(),
-             in.readString(),
-             in.readInt(),
-             in.readInt(),
-             in.readString(),
-             in.readInt(),
-             in.readInt(),
-             in.readInt());
-    }
-
-    public String getLocation() {
-        return mLocation;
-    }
-
-    public void updateMeta(LibVLC libVLC) {
-        mTitle = libVLC.getMeta(libvlc_meta_Title);
-        mArtist = libVLC.getMeta(libvlc_meta_Artist);
-        mGenre = libVLC.getMeta(libvlc_meta_Genre);
-        mAlbum = libVLC.getMeta(libvlc_meta_Album);
-        mAlbumArtist = libVLC.getMeta(libvlc_meta_AlbumArtist);
-        mNowPlaying = libVLC.getMeta(libvlc_meta_NowPlaying);
-        mArtworkURL = libVLC.getMeta(libvlc_meta_ArtworkURL);
-    }
-
-    public String getFileName() {
-        if (mFilename == null) {
-            mFilename = LibVlcUtil.URItoFileName(mLocation);
-        }
-        return mFilename;
-    }
-
-    public long getTime() {
-        return mTime;
-    }
-
-    public void setTime(long time) {
-        mTime = time;
-    }
-
-    public int getAudioTrack() {
-        return mAudioTrack;
-    }
-
-    public void setAudioTrack(int track) {
-        mAudioTrack = track;
-    }
-
-    public int getSpuTrack() {
-        return mSpuTrack;
-    }
-
-    public void setSpuTrack(int track) {
-        mSpuTrack = track;
-    }
-
-    public long getLength() {
-        return mLength;
-    }
-
-    public int getType() {
-        return mType;
-    }
-
-    public int getWidth() {
-        return mWidth;
-    }
-
-    public int getHeight() {
-        return mHeight;
-    }
-
-    /**
-     * Returns the raw picture object. Likely to be NULL in VLC for Android
-     * due to lazy-loading.
-     *
-     * Use {@link org.videolan.vlc.util.Bitmap#getPictureFromCache(Media)} instead.
-     *
-     * @return The raw picture or NULL
-     */
-    public Bitmap getPicture() {
-        return mPicture;
-    }
-
-    /**
-     * Sets the raw picture object.
-     *
-     * In VLC for Android, use {@link org.videolan.vlc.MediaDatabase#setPicture(Media, Bitmap)} instead.
-     *
-     * @param p
-     */
-    public void setPicture(Bitmap p) {
-        mPicture = p;
-    }
-
-    public boolean isPictureParsed() {
-        return mIsPictureParsed;
-    }
-
-    public void setPictureParsed(boolean isParsed) {
-        mIsPictureParsed = isParsed;
-    }
-
-    public String getTitle() {
-        if (mTitle != null && mType != TYPE_VIDEO)
-            return mTitle;
-        else {
-            String fileName = getFileName();
-            if (fileName == null)
-                return "";
-            int end = fileName.lastIndexOf(".");
-            if (end <= 0)
-                return fileName;
-            return fileName.substring(0, end);
-        }
-    }
-
-    public String getReferenceArtist() {
-        return mAlbumArtist == null ? mArtist : mAlbumArtist;
-    }
-
-    public String getArtist() {
-        return mArtist;
-    }
-
-    public Boolean isArtistUnknown() {
-        return mArtist == null;
-    }
-
-    public String getGenre() {
-        if (mGenre == null)
-            return null;
-        else if (mGenre.length() > 1)/* Make genres case insensitive via normalisation */
-            return Character.toUpperCase(mGenre.charAt(0)) + mGenre.substring(1).toLowerCase(Locale.getDefault());
-        else
-            return mGenre;
-    }
-
-    public String getCopyright() {
-        return mCopyright;
-    }
-
-    public String getAlbum() {
-        return mAlbum;
-    }
-
-    public String getAlbumArtist() {
-        return mAlbumArtist;
-    }
-
-    public Boolean isAlbumUnknown() {
-        return mAlbum == null;
-    }
-
-    public int getTrackNumber() {
-        return mTrackNumber;
-    }
-
-    public String getDescription() {
-        return mDescription;
-    }
-
-    public String getRating() {
-        return mRating;
-    }
-
-    public String getDate() {
-        return mDate;
-    }
-
-    public String getSettings() {
-        return mSettings;
-    }
-
-    public String getNowPlaying() {
-        return mNowPlaying;
-    }
-
-    public String getPublisher() {
-        return mPublisher;
-    }
-
-    public String getEncodedBy() {
-        return mEncodedBy;
-    }
-
-    public String getTrackID() {
-        return mTrackID;
-    }
-
-    public String getArtworkURL() {
-        return mArtworkURL;
-    }
-
-    public void addFlags(int flags) {
-        mFlags |= flags;
-    }
-    public void setFlags(int flags) {
-        mFlags = flags;
-    }
-    public int getFlags() {
-        return mFlags;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeValue(getLocation());
-        dest.writeLong(getTime());
-        dest.writeLong(getLength());
-        dest.writeInt(getType());
-        dest.writeParcelable(getPicture(), flags);
-        dest.writeValue(getTitle());
-        dest.writeValue(getArtist());
-        dest.writeValue(getGenre());
-        dest.writeValue(getAlbum());
-        dest.writeValue(getAlbumArtist());
-        dest.writeInt(getWidth());
-        dest.writeInt(getHeight());
-        dest.writeValue(getArtworkURL());
-        dest.writeInt(getAudioTrack());
-        dest.writeInt(getSpuTrack());
-        dest.writeInt(getTrackNumber());
-    }
-
-    public static final Parcelable.Creator<Media> CREATOR = new Parcelable.Creator<Media>() {
-        public Media createFromParcel(Parcel in) {
-            return new Media(in);
-        }
-        public Media[] newArray(int size) {
-            return new Media[size];
-        }
-    };
-}
diff --git a/libvlc/src/org/videolan/libvlc/MediaList.java b/libvlc/src/org/videolan/libvlc/MediaList.java
deleted file mode 100644
index 8419c5c..0000000
--- a/libvlc/src/org/videolan/libvlc/MediaList.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*****************************************************************************
- * MediaList.java
- *****************************************************************************
- * Copyright © 2013 VLC authors and VideoLAN
- * Copyright © 2013 Edward Wang
- *
- * 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.
- *****************************************************************************/
-package org.videolan.libvlc;
-
-import java.util.ArrayList;
-
-import android.os.Bundle;
-
-/**
- * Java/JNI wrapper for the libvlc_media_list_t structure.
- */
-public class MediaList {
-    private static final String TAG = "VLC/LibVLC/MediaList";
-
-
-    /* TODO: add locking */
-    private ArrayList<Media> mInternalList;
-    private LibVLC mLibVLC; // Used to create new objects that require a libvlc instance
-    private EventHandler mEventHandler;
-
-    public MediaList(LibVLC libVLC) {
-        mEventHandler = new EventHandler(); // used in init() below to fire events at the correct targets
-        mInternalList = new ArrayList<Media>();
-        mLibVLC = libVLC;
-    }
-
-    public void add(Media media) {
-        mInternalList.add(media);
-    }
-
-    /**
-     * Clear the media list. (remove all media)
-     */
-    public void clear() {
-        // Signal to observers of media being deleted.
-        for(int i = 0; i < mInternalList.size(); i++) {
-            signal_list_event(EventHandler.CustomMediaListItemDeleted, i, mInternalList.get(i).getLocation());
-        }
-        mInternalList.clear();
-    }
-
-    private boolean isValid(int position) {
-        return position >= 0 && position < mInternalList.size();
-    }
-
-    public void insert(int position, String mrl) {
-        insert(position, new Media(mLibVLC, mrl));
-    }
-    public void insert(int position, Media media) {
-        mInternalList.add(position, media);
-        signal_list_event(EventHandler.CustomMediaListItemAdded, position, media.getLocation());
-    }
-
-    /**
-     * Move a media from one position to another
-     *
-     * @param startPosition start position
-     * @param endPosition end position
-     * @throws IndexOutOfBoundsException
-     */
-    public void move(int startPosition, int endPosition) {
-        if (!(isValid(startPosition)
-              && endPosition >= 0 && endPosition <= mInternalList.size()))
-            throw new IndexOutOfBoundsException("Indexes out of range");
-
-        Media toMove = mInternalList.get(startPosition);
-        mInternalList.remove(startPosition);
-        if (startPosition >= endPosition)
-            mInternalList.add(endPosition, toMove);
-        else
-            mInternalList.add(endPosition - 1, toMove);
-        Bundle b = new Bundle();
-        b.putInt("index_before", startPosition);
-        b.putInt("index_after", endPosition);
-        mEventHandler.callback(EventHandler.CustomMediaListItemMoved, b);
-    }
-
-    public void remove(int position) {
-        if (!isValid(position))
-            return;
-        String uri = mInternalList.get(position).getLocation();
-        mInternalList.remove(position);
-        signal_list_event(EventHandler.CustomMediaListItemDeleted, position, uri);
-    }
-
-    public void remove(String location) {
-        for (int i = 0; i < mInternalList.size(); ++i) {
-            String uri = mInternalList.get(i).getLocation();
-            if (uri.equals(location)) {
-                mInternalList.remove(i);
-                signal_list_event(EventHandler.CustomMediaListItemDeleted, i, uri);
-                i--;
-            }
-        }
-    }
-
-    public int size() {
-        return mInternalList.size();
-    }
-
-    public Media getMedia(int position) {
-        if (!isValid(position))
-            return null;
-        return mInternalList.get(position);
-    }
-
-    /**
-     * @param position The index of the media in the list
-     * @return null if not found
-     */
-    public String getMRL(int position) {
-        if (!isValid(position))
-            return null;
-        return mInternalList.get(position).getLocation();
-    }
-
-    public EventHandler getEventHandler() {
-        return mEventHandler;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("LibVLC Media List: {");
-        for(int i = 0; i < size(); i++) {
-            sb.append(((Integer)i).toString());
-            sb.append(": ");
-            sb.append(getMRL(i));
-            sb.append(", ");
-        }
-        sb.append("}");
-        return sb.toString();
-    }
-
-    private void signal_list_event(int event, int position, String uri) {
-        Bundle b = new Bundle();
-        b.putString("item_uri", uri);
-        b.putInt("item_index", position);
-        mEventHandler.callback(event, b);
-    }
-}
diff --git a/libvlc/src/org/videolan/libvlc/MediaListPlayer.java b/libvlc/src/org/videolan/libvlc/MediaListPlayer.java
deleted file mode 100644
index a7fa532..0000000
--- a/libvlc/src/org/videolan/libvlc/MediaListPlayer.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*****************************************************************************
- * MediaListPlayer.java
- *****************************************************************************
- * Copyright © 2015 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.
- *****************************************************************************/
-
-package org.videolan.libvlc;
-
-import java.util.ArrayList;
-
-
-public class MediaListPlayer {
-
-    private int mPlayerIndex = 0;
-    final private LibVLC mLibVLC;
-    final private MediaList mMediaList;
-
-    public MediaListPlayer(LibVLC libVLC) {
-        mLibVLC = libVLC;
-        mMediaList = new MediaList(libVLC);
-    }
-
-    public MediaList getMediaList() {
-        return mMediaList;
-    }
-
-    /**
-     * Play a media from the media list (playlist)
-     *
-     * @param position The index of the media
-     */
-    public void playIndex(int position) {
-        String mrl = mMediaList.getMRL(position);
-        if (mrl == null)
-            return;
-
-        final Media media = mMediaList.getMedia(position);
-        String[] options = mLibVLC.getMediaOptions(media != null ? media.getFlags() : 0);
-        mPlayerIndex = position;
-        mLibVLC.playMRL(mrl, options);
-    }
-
-    /**
-     * Expand and continue playing the current media.
-     *
-     * @return the index of the media was expanded, and -1 if no media was expanded
-     */
-   public int expandAndPlay() {
-       int r = expand();
-       if(r == 0)
-           playIndex(mPlayerIndex);
-       return r;
-   }
-
-   /**
-    * Expand the current media.
-    * @return the index of the media was expanded, and -1 if no media was expanded
-    */
-   public int expand() {
-       ArrayList<String> children = new ArrayList<String>();
-       int ret = mLibVLC.expandMedia(children);
-       if(ret == 0) {
-           mMediaList.remove(mPlayerIndex);
-           for(String mrl : children) {
-               mMediaList.insert(mPlayerIndex, mrl);
-           }
-       }
-       return ret;
-   }
-
-   public int expand(int index) {
-       mPlayerIndex = index;
-       return expand();
-   }
-}
diff --git a/vlc-android/src/org/videolan/vlc/MediaDatabase.java b/vlc-android/src/org/videolan/vlc/MediaDatabase.java
index 5926c97..07e7827 100644
--- a/vlc-android/src/org/videolan/vlc/MediaDatabase.java
+++ b/vlc-android/src/org/videolan/vlc/MediaDatabase.java
@@ -31,8 +31,6 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Set;
 
-import org.videolan.libvlc.Media;
-
 import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
@@ -478,7 +476,7 @@ public class MediaDatabase {
      * Add a new media to the database. The picture can only added by update.
      * @param media which you like to add to the database
      */
-    public synchronized void addMedia(Media media) {
+    public synchronized void addMedia(MediaHolder media) {
 
         ContentValues values = new ContentValues();
 
@@ -556,7 +554,7 @@ public class MediaDatabase {
         String[] queryColumns = new String[]{MEDIA_LOCATION, MEDIA_TITLE, MEDIA_ALBUM, MEDIA_ARTIST, MEDIA_TYPE};
         String queryString = MEDIA_TITLE+" LIKE ? OR "+MEDIA_ALBUM+" LIKE ? OR "+MEDIA_ARTIST+" LIKE ?";
         String [] queryArgs;
-        if (type != Media.TYPE_ALL) {
+        if (type != MediaHolder.TYPE_ALL) {
             queryString = "( " + queryString + " ) AND " + MEDIA_TYPE + "=?";
             queryArgs = new String[]{"%"+filter+"%", "%"+filter+"%", "%"+filter+"%", String.valueOf(type)};
         } else
@@ -573,10 +571,10 @@ public class MediaDatabase {
         return mediaList;
     }
 
-    public synchronized HashMap<String, Media> getMedias() {
+    public synchronized HashMap<String, MediaHolder> getMedias() {
 
         Cursor cursor;
-        HashMap<String, Media> medias = new HashMap<String, Media>();
+        HashMap<String, MediaHolder> medias = new HashMap<String, MediaHolder>();
         int chunk_count = 0;
         int count = 0;
 
@@ -606,7 +604,7 @@ public class MediaDatabase {
             if (cursor.moveToFirst()) {
                 do {
                     String location = cursor.getString(14);
-                    Media media = new Media(location,
+                    MediaHolder media = new MediaHolder(location,
                             cursor.getLong(0),      // MEDIA_TIME
                             cursor.getLong(1),      // MEDIA_LENGTH
                             cursor.getInt(2),       // MEDIA_TYPE
@@ -650,7 +648,7 @@ public class MediaDatabase {
                     MEDIA_TIME, //1 long
                     MEDIA_TABLE_NAME,
                     MEDIA_TYPE,
-                    Media.TYPE_VIDEO,
+                    MediaHolder.TYPE_VIDEO,
                     CHUNK_SIZE,
                     chunk_count * CHUNK_SIZE), null);
 
@@ -670,10 +668,10 @@ public class MediaDatabase {
         return times;
     }
 
-    public synchronized Media getMedia(String location) {
+    public synchronized MediaHolder getMedia(String location) {
 
         Cursor cursor;
-        Media media = null;
+        MediaHolder media = null;
 
         try {
             cursor = mDb.query(
@@ -702,7 +700,7 @@ public class MediaDatabase {
             return null;
         }
         if (cursor.moveToFirst()) {
-            media = new Media(location,
+            media = new MediaHolder(location,
                     cursor.getLong(0),
                     cursor.getLong(1),
                     cursor.getInt(2),
@@ -946,7 +944,7 @@ public class MediaDatabase {
         mDb.delete(MEDIA_TABLE_NAME, null, null);
     }
 
-    public static void setPicture(Media m, Bitmap p) {
+    public static void setPicture(MediaHolder m, Bitmap p) {
         Log.d(TAG, "Setting new picture for " + m.getTitle());
         try {
             getInstance().updateMedia(
diff --git a/vlc-android/src/org/videolan/vlc/MediaGroup.java b/vlc-android/src/org/videolan/vlc/MediaGroup.java
index ff4fac6..c2542da 100644
--- a/vlc-android/src/org/videolan/vlc/MediaGroup.java
+++ b/vlc-android/src/org/videolan/vlc/MediaGroup.java
@@ -23,23 +23,22 @@ package org.videolan.vlc;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.videolan.libvlc.Media;
 import org.videolan.vlc.util.BitmapUtil;
 
-public class MediaGroup extends Media {
+public class MediaGroup extends MediaHolder {
 
     public final static String TAG = "VLC/MediaGroup";
 
     public final static int MIN_GROUP_LENGTH = 6;
 
-    private ArrayList<Media> mMedias;
+    private ArrayList<MediaHolder> mMedias;
 
-    public MediaGroup(Media media)
+    public MediaGroup(MediaHolder media)
     {
         super(media.getLocation(),
                 media.getTime(),
                 media.getLength(),
-                Media.TYPE_GROUP,
+                MediaHolder.TYPE_GROUP,
                 BitmapUtil.getPictureFromCache(media),
                 media.getTitle(),
                 media.getArtist(),
@@ -52,19 +51,19 @@ public class MediaGroup extends Media {
                 media.getAudioTrack(),
                 media.getSpuTrack(),
                 media.getTrackNumber());
-        mMedias = new ArrayList<Media>();
+        mMedias = new ArrayList<MediaHolder>();
         mMedias.add(media);
     }
 
-    public void add(Media media) {
+    public void add(MediaHolder media) {
         mMedias.add(media);
     }
 
-    public Media getMedia() {
+    public MediaHolder getMedia() {
         return mMedias.size() == 1 ? mMedias.get(0) : this;
     }
 
-    public Media getFirstMedia() {
+    public MediaHolder getFirstMedia() {
         return mMedias.get(0);
     }
 
@@ -72,19 +71,19 @@ public class MediaGroup extends Media {
         return mMedias.size();
     }
 
-    public void merge(Media media, String title) {
+    public void merge(MediaHolder media, String title) {
         mMedias.add(media);
         this.mTitle = title;
     }
 
-    public static List<MediaGroup> group(List<Media> mediaList) {
+    public static List<MediaGroup> group(List<MediaHolder> mediaList) {
         ArrayList<MediaGroup> groups = new ArrayList<MediaGroup>();
-        for (Media media : mediaList)
+        for (MediaHolder media : mediaList)
             insertInto(groups, media);
         return groups;
     }
 
-    private static void insertInto(ArrayList<MediaGroup> groups, Media media)
+    private static void insertInto(ArrayList<MediaGroup> groups, MediaHolder media)
     {
         for (MediaGroup mediaGroup : groups) {
             String group = mediaGroup.getTitle();
diff --git a/vlc-android/src/org/videolan/vlc/MediaHolder.aidl b/vlc-android/src/org/videolan/vlc/MediaHolder.aidl
new file mode 100644
index 0000000..6cf3f6e
--- /dev/null
+++ b/vlc-android/src/org/videolan/vlc/MediaHolder.aidl
@@ -0,0 +1,23 @@
+/*****************************************************************************
+ * MediaHolder.aidl
+ *****************************************************************************
+ * Copyright © 2015 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.
+ *****************************************************************************/
+
+package org.videolan.vlc;
+
+parcelable MediaHolder;
diff --git a/vlc-android/src/org/videolan/vlc/MediaHolder.java b/vlc-android/src/org/videolan/vlc/MediaHolder.java
new file mode 100644
index 0000000..4201265
--- /dev/null
+++ b/vlc-android/src/org/videolan/vlc/MediaHolder.java
@@ -0,0 +1,482 @@
+/*****************************************************************************
+ * MediaHolder.java
+ *****************************************************************************
+ * Copyright © 2011-2015 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.
+ *****************************************************************************/
+
+package org.videolan.vlc;
+
+import java.util.HashSet;
+import java.util.Locale;
+
+import org.videolan.libvlc.LibVLC;
+import org.videolan.libvlc.LibVlcUtil;
+import org.videolan.libvlc.TrackInfo;
+
+import android.graphics.Bitmap;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.Log;
+
+public class MediaHolder implements Parcelable {
+    public final static String TAG = "VLC/MediaHolder";
+
+    public final static HashSet<String> VIDEO_EXTENSIONS;
+    public final static HashSet<String> AUDIO_EXTENSIONS;
+    public final static HashSet<String> SUBTITLES_EXTENSIONS;
+
+    static {
+        final String[] video_extensions = {
+                ".3g2", ".3gp", ".3gp2", ".3gpp", ".amv", ".asf", ".avi", ".divx", ".drc", ".dv",
+                ".f4v", ".flv", ".gvi", ".gxf", ".ismv", ".iso", ".m1v", ".m2v", ".m2t", ".m2ts",
+                ".m4v", ".mkv", ".mov", ".mp2", ".mp2v", ".mp4", ".mp4v", ".mpe", ".mpeg",
+                ".mpeg1", ".mpeg2", ".mpeg4", ".mpg", ".mpv2", ".mts", ".mtv", ".mxf", ".mxg",
+                ".nsv", ".nut", ".nuv", ".ogm", ".ogv", ".ogx", ".ps", ".rec", ".rm", ".rmvb",
+                ".tod", ".ts", ".tts", ".vob", ".vro", ".webm", ".wm", ".wmv", ".wtv", ".xesc" };
+
+        final String[] audio_extensions = {
+                ".3ga", ".a52", ".aac", ".ac3", ".adt", ".adts", ".aif", ".aifc", ".aiff", ".amr",
+                ".aob", ".ape", ".awb", ".caf", ".dts", ".flac", ".it", ".m4a", ".m4b", ".m4p",
+                ".mid", ".mka", ".mlp", ".mod", ".mpa", ".mp1", ".mp2", ".mp3", ".mpc", ".mpga",
+                ".oga", ".ogg", ".oma", ".opus", ".ra", ".ram", ".rmi", ".s3m", ".spx", ".tta",
+                ".voc", ".vqf", ".w64", ".wav", ".wma", ".wv", ".xa", ".xm" };
+
+        final String[] subtitles_extensions = {
+                "idx", "sub",  "srt", "ssa", "ass",  "smi", "utf", "utf8", "utf-8",
+                "rt",   "aqt", "txt", "usf", "jss",  "cdg", "psb", "mpsub","mpl2",
+                "pjs", "dks", "stl", "vtt" };
+
+        VIDEO_EXTENSIONS = new HashSet<String>();
+        for (String item : video_extensions)
+            VIDEO_EXTENSIONS.add(item);
+        AUDIO_EXTENSIONS = new HashSet<String>();
+        for (String item : audio_extensions)
+            AUDIO_EXTENSIONS.add(item);
+        SUBTITLES_EXTENSIONS = new HashSet<String>();
+        for (String item : subtitles_extensions)
+            SUBTITLES_EXTENSIONS.add(item);
+    }
+
+    public final static int TYPE_ALL = -1;
+    public final static int TYPE_VIDEO = 0;
+    public final static int TYPE_AUDIO = 1;
+    public final static int TYPE_GROUP = 2;
+
+    /** Metadata from libvlc_media */
+    protected String mTitle;
+    private String mArtist;
+    private String mGenre;
+    private String mCopyright;
+    private String mAlbum;
+    private int mTrackNumber;
+    private String mAlbumArtist;
+    private String mDescription;
+    private String mRating;
+    private String mDate;
+    private String mSettings;
+    private String mNowPlaying;
+    private String mPublisher;
+    private String mEncodedBy;
+    private String mTrackID;
+    private String mArtworkURL;
+
+    public final static int libvlc_meta_Title       = 0;
+    public final static int libvlc_meta_Artist      = 1;
+    public final static int libvlc_meta_Genre       = 2;
+//    public final static int libvlc_meta_Copyright   = 3;
+    public final static int libvlc_meta_Album       = 4;
+//    public final static int libvlc_meta_TrackNumber = 5;
+//    public final static int libvlc_meta_Description = 6;
+//    public final static int libvlc_meta_Rating      = 7;
+//    public final static int libvlc_meta_Date        = 8;
+//    public final static int libvlc_meta_Setting     = 9;
+//    public final static int libvlc_meta_URL         = 10;
+//    public final static int libvlc_meta_Language    = 11;
+    public final static int libvlc_meta_NowPlaying  = 12;
+//    public final static int libvlc_meta_Publisher   = 13;
+//    public final static int libvlc_meta_EncodedBy   = 14;
+    public final static int libvlc_meta_ArtworkURL  = 15;
+//    public final static int libvlc_meta_TrackID     = 16;
+//    public final static int libvlc_meta_TrackTotal  = 17;
+//    public final static int libvlc_meta_Director    = 18;
+//    public final static int libvlc_meta_Season      = 19;
+//    public final static int libvlc_meta_Episode     = 20;
+//    public final static int libvlc_meta_ShowName    = 21;
+//    public final static int libvlc_meta_Actors      = 22;
+    public final static int libvlc_meta_AlbumArtist = 23;
+//    public final static int libvlc_meta_DiscNumber  = 24;
+
+    private final String mLocation;
+    private String mFilename;
+    private long mTime = 0;
+    private int mAudioTrack = -1;
+    private int mSpuTrack = -2;
+    private long mLength = 0;
+    private int mType;
+    private int mWidth = 0;
+    private int mHeight = 0;
+    private Bitmap mPicture;
+    private boolean mIsPictureParsed;
+    private int mFlags = 0;
+
+    /**
+     * Create a new Media
+     * @param libVLC A pointer to the libVLC instance. Should not be NULL
+     * @param URI The URI of the media.
+     */
+    public MediaHolder(LibVLC libVLC, String URI) {
+        if(libVLC == null)
+            throw new NullPointerException("libVLC was null");
+
+        mLocation = URI;
+
+        mType = TYPE_ALL;
+        TrackInfo[] tracks = libVLC.readTracksInfo(mLocation);
+
+        extractTrackInfo(tracks);
+    }
+
+    private void extractTrackInfo(TrackInfo[] tracks) {
+        if (tracks == null) {
+            mTitle = null;
+            mArtist = null;
+            mAlbum = null;
+            mGenre = null;
+            mAlbumArtist = null;
+            return;
+        }
+
+        for (TrackInfo track : tracks) {
+            if (track.Type == TrackInfo.TYPE_VIDEO) {
+                mType = TYPE_VIDEO;
+                mWidth = track.Width;
+                mHeight = track.Height;
+            } else if (mType == TYPE_ALL && track.Type == TrackInfo.TYPE_AUDIO){
+                mType = TYPE_AUDIO;
+            } else if (track.Type == TrackInfo.TYPE_META) {
+                mLength = track.Length;
+                mTitle = track.Title != null ? track.Title.trim() : null;
+                mArtist = track.Artist != null ? track.Artist.trim() : null;
+                mAlbum = track.Album != null ? track.Album.trim() : null;
+                mGenre = track.Genre != null ? track.Genre.trim() : null;
+                mAlbumArtist = track.AlbumArtist != null ? track.AlbumArtist.trim() : null;
+                mArtworkURL = track.ArtworkURL;
+                mNowPlaying = track.NowPlaying;
+                if (!TextUtils.isEmpty(track.TrackNumber)) {
+                    try {
+                        mTrackNumber = Integer.parseInt(track.TrackNumber);
+                    } catch (NumberFormatException ignored) {
+                    }
+                }
+                Log.d(TAG, "Title " + mTitle);
+                Log.d(TAG, "Artist " + mArtist);
+                Log.d(TAG, "Genre " + mGenre);
+                Log.d(TAG, "Album " + mAlbum);
+            }
+        }
+
+        /* No useful ES found */
+        if (mType == TYPE_ALL) {
+            int dotIndex = mLocation.lastIndexOf(".");
+            if (dotIndex != -1) {
+                String fileExt = mLocation.substring(dotIndex).toLowerCase(Locale.ENGLISH);
+                if( MediaHolder.VIDEO_EXTENSIONS.contains(fileExt) ) {
+                    mType = TYPE_VIDEO;
+                } else if (MediaHolder.AUDIO_EXTENSIONS.contains(fileExt)) {
+                    mType = TYPE_AUDIO;
+                }
+            }
+        }
+    }
+
+    private void init(long time, long length, int type,
+                      Bitmap picture, String title, String artist, String genre, String album, String albumArtist,
+                      int width, int height, String artworkURL, int audio, int spu, int trackNumber) {
+        mFilename = null;
+        mTime = time;
+        mAudioTrack = audio;
+        mSpuTrack = spu;
+        mLength = length;
+        mType = type;
+        mPicture = picture;
+        mWidth = width;
+        mHeight = height;
+
+        mTitle = title;
+        mArtist = artist;
+        mGenre = genre;
+        mAlbum = album;
+        mAlbumArtist = albumArtist;
+        mArtworkURL = artworkURL;
+        mTrackNumber = trackNumber;
+    }
+
+    public MediaHolder(String location, long time, long length, int type,
+                 Bitmap picture, String title, String artist, String genre, String album, String albumArtist,
+                 int width, int height, String artworkURL, int audio, int spu, int trackNumber) {
+        mLocation = location;
+        init(time, length, type, picture, title, artist, genre, album, albumArtist,
+             width, height, artworkURL, audio, spu, trackNumber);
+    }
+
+    public MediaHolder(Parcel in) {
+        mLocation = in.readString();
+        init(in.readLong(),
+             in.readLong(),
+             in.readInt(),
+             (Bitmap) in.readParcelable(Bitmap.class.getClassLoader()),
+             in.readString(),
+             in.readString(),
+             in.readString(),
+             in.readString(),
+             in.readString(),
+             in.readInt(),
+             in.readInt(),
+             in.readString(),
+             in.readInt(),
+             in.readInt(),
+             in.readInt());
+    }
+
+    public String getLocation() {
+        return mLocation;
+    }
+
+    public void updateMeta(LibVLC libVLC) {
+        mTitle = libVLC.getMeta(libvlc_meta_Title);
+        mArtist = libVLC.getMeta(libvlc_meta_Artist);
+        mGenre = libVLC.getMeta(libvlc_meta_Genre);
+        mAlbum = libVLC.getMeta(libvlc_meta_Album);
+        mAlbumArtist = libVLC.getMeta(libvlc_meta_AlbumArtist);
+        mNowPlaying = libVLC.getMeta(libvlc_meta_NowPlaying);
+        mArtworkURL = libVLC.getMeta(libvlc_meta_ArtworkURL);
+    }
+
+    public String getFileName() {
+        if (mFilename == null) {
+            mFilename = LibVlcUtil.URItoFileName(mLocation);
+        }
+        return mFilename;
+    }
+
+    public long getTime() {
+        return mTime;
+    }
+
+    public void setTime(long time) {
+        mTime = time;
+    }
+
+    public int getAudioTrack() {
+        return mAudioTrack;
+    }
+
+    public void setAudioTrack(int track) {
+        mAudioTrack = track;
+    }
+
+    public int getSpuTrack() {
+        return mSpuTrack;
+    }
+
+    public void setSpuTrack(int track) {
+        mSpuTrack = track;
+    }
+
+    public long getLength() {
+        return mLength;
+    }
+
+    public int getType() {
+        return mType;
+    }
+
+    public int getWidth() {
+        return mWidth;
+    }
+
+    public int getHeight() {
+        return mHeight;
+    }
+
+    /**
+     * Returns the raw picture object. Likely to be NULL in VLC for Android
+     * due to lazy-loading.
+     *
+     * Use {@link org.videolan.vlc.util.Bitmap#getPictureFromCache(MediaHolder)} instead.
+     *
+     * @return The raw picture or NULL
+     */
+    public Bitmap getPicture() {
+        return mPicture;
+    }
+
+    /**
+     * Sets the raw picture object.
+     *
+     * In VLC for Android, use {@link org.videolan.vlc.MediaDatabase#setPicture(MediaHolder, Bitmap)} instead.
+     *
+     * @param p
+     */
+    public void setPicture(Bitmap p) {
+        mPicture = p;
+    }
+
+    public boolean isPictureParsed() {
+        return mIsPictureParsed;
+    }
+
+    public void setPictureParsed(boolean isParsed) {
+        mIsPictureParsed = isParsed;
+    }
+
+    public String getTitle() {
+        if (mTitle != null && mType != TYPE_VIDEO)
+            return mTitle;
+        else {
+            String fileName = getFileName();
+            if (fileName == null)
+                return "";
+            int end = fileName.lastIndexOf(".");
+            if (end <= 0)
+                return fileName;
+            return fileName.substring(0, end);
+        }
+    }
+
+    public String getReferenceArtist() {
+        return mAlbumArtist == null ? mArtist : mAlbumArtist;
+    }
+
+    public String getArtist() {
+        return mArtist;
+    }
+
+    public Boolean isArtistUnknown() {
+        return mArtist == null;
+    }
+
+    public String getGenre() {
+        if (mGenre == null)
+            return null;
+        else if (mGenre.length() > 1)/* Make genres case insensitive via normalisation */
+            return Character.toUpperCase(mGenre.charAt(0)) + mGenre.substring(1).toLowerCase(Locale.getDefault());
+        else
+            return mGenre;
+    }
+
+    public String getCopyright() {
+        return mCopyright;
+    }
+
+    public String getAlbum() {
+        return mAlbum;
+    }
+
+    public String getAlbumArtist() {
+        return mAlbumArtist;
+    }
+
+    public Boolean isAlbumUnknown() {
+        return mAlbum == null;
+    }
+
+    public int getTrackNumber() {
+        return mTrackNumber;
+    }
+
+    public String getDescription() {
+        return mDescription;
+    }
+
+    public String getRating() {
+        return mRating;
+    }
+
+    public String getDate() {
+        return mDate;
+    }
+
+    public String getSettings() {
+        return mSettings;
+    }
+
+    public String getNowPlaying() {
+        return mNowPlaying;
+    }
+
+    public String getPublisher() {
+        return mPublisher;
+    }
+
+    public String getEncodedBy() {
+        return mEncodedBy;
+    }
+
+    public String getTrackID() {
+        return mTrackID;
+    }
+
+    public String getArtworkURL() {
+        return mArtworkURL;
+    }
+
+    public void addFlags(int flags) {
+        mFlags |= flags;
+    }
+    public void setFlags(int flags) {
+        mFlags = flags;
+    }
+    public int getFlags() {
+        return mFlags;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeValue(getLocation());
+        dest.writeLong(getTime());
+        dest.writeLong(getLength());
+        dest.writeInt(getType());
+        dest.writeParcelable(getPicture(), flags);
+        dest.writeValue(getTitle());
+        dest.writeValue(getArtist());
+        dest.writeValue(getGenre());
+        dest.writeValue(getAlbum());
+        dest.writeValue(getAlbumArtist());
+        dest.writeInt(getWidth());
+        dest.writeInt(getHeight());
+        dest.writeValue(getArtworkURL());
+        dest.writeInt(getAudioTrack());
+        dest.writeInt(getSpuTrack());
+        dest.writeInt(getTrackNumber());
+    }
+
+    public static final Parcelable.Creator<MediaHolder> CREATOR = new Parcelable.Creator<MediaHolder>() {
+        public MediaHolder createFromParcel(Parcel in) {
+            return new MediaHolder(in);
+        }
+        public MediaHolder[] newArray(int size) {
+            return new MediaHolder[size];
+        }
+    };
+}
diff --git a/vlc-android/src/org/videolan/vlc/MediaHolderList.java b/vlc-android/src/org/videolan/vlc/MediaHolderList.java
new file mode 100644
index 0000000..1c348ae
--- /dev/null
+++ b/vlc-android/src/org/videolan/vlc/MediaHolderList.java
@@ -0,0 +1,159 @@
+/*****************************************************************************
+ * MediaHolderList.java
+ *****************************************************************************
+ * Copyright © 2013-2015 VLC authors and VideoLAN
+ * Copyright © 2013 Edward Wang
+ *
+ * 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.
+ *****************************************************************************/
+package org.videolan.vlc;
+
+import java.util.ArrayList;
+
+import org.videolan.libvlc.EventHandler;
+import org.videolan.libvlc.LibVLC;
+
+import android.os.Bundle;
+
+public class MediaHolderList {
+    private static final String TAG = "VLC/MediaHolderList";
+
+
+    /* TODO: add locking */
+    private ArrayList<MediaHolder> mInternalList;
+    private LibVLC mLibVLC; // Used to create new objects that require a libvlc instance
+    private EventHandler mEventHandler;
+
+    public MediaHolderList(LibVLC libVLC) {
+        mEventHandler = new EventHandler(); // used in init() below to fire events at the correct targets
+        mInternalList = new ArrayList<MediaHolder>();
+        mLibVLC = libVLC;
+    }
+
+    public void add(MediaHolder media) {
+        mInternalList.add(media);
+    }
+
+    /**
+     * Clear the media list. (remove all media)
+     */
+    public void clear() {
+        // Signal to observers of media being deleted.
+        for(int i = 0; i < mInternalList.size(); i++) {
+            signal_list_event(EventHandler.CustomMediaListItemDeleted, i, mInternalList.get(i).getLocation());
+        }
+        mInternalList.clear();
+    }
+
+    private boolean isValid(int position) {
+        return position >= 0 && position < mInternalList.size();
+    }
+
+    public void insert(int position, String mrl) {
+        insert(position, new MediaHolder(mLibVLC, mrl));
+    }
+    public void insert(int position, MediaHolder media) {
+        mInternalList.add(position, media);
+        signal_list_event(EventHandler.CustomMediaListItemAdded, position, media.getLocation());
+    }
+
+    /**
+     * Move a media from one position to another
+     *
+     * @param startPosition start position
+     * @param endPosition end position
+     * @throws IndexOutOfBoundsException
+     */
+    public void move(int startPosition, int endPosition) {
+        if (!(isValid(startPosition)
+              && endPosition >= 0 && endPosition <= mInternalList.size()))
+            throw new IndexOutOfBoundsException("Indexes out of range");
+
+        MediaHolder toMove = mInternalList.get(startPosition);
+        mInternalList.remove(startPosition);
+        if (startPosition >= endPosition)
+            mInternalList.add(endPosition, toMove);
+        else
+            mInternalList.add(endPosition - 1, toMove);
+        Bundle b = new Bundle();
+        b.putInt("index_before", startPosition);
+        b.putInt("index_after", endPosition);
+        mEventHandler.callback(EventHandler.CustomMediaListItemMoved, b);
+    }
+
+    public void remove(int position) {
+        if (!isValid(position))
+            return;
+        String uri = mInternalList.get(position).getLocation();
+        mInternalList.remove(position);
+        signal_list_event(EventHandler.CustomMediaListItemDeleted, position, uri);
+    }
+
+    public void remove(String location) {
+        for (int i = 0; i < mInternalList.size(); ++i) {
+            String uri = mInternalList.get(i).getLocation();
+            if (uri.equals(location)) {
+                mInternalList.remove(i);
+                signal_list_event(EventHandler.CustomMediaListItemDeleted, i, uri);
+                i--;
+            }
+        }
+    }
+
+    public int size() {
+        return mInternalList.size();
+    }
+
+    public MediaHolder getMedia(int position) {
+        if (!isValid(position))
+            return null;
+        return mInternalList.get(position);
+    }
+
+    /**
+     * @param position The index of the media in the list
+     * @return null if not found
+     */
+    public String getMRL(int position) {
+        if (!isValid(position))
+            return null;
+        return mInternalList.get(position).getLocation();
+    }
+
+    public EventHandler getEventHandler() {
+        return mEventHandler;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("LibVLC Media List: {");
+        for(int i = 0; i < size(); i++) {
+            sb.append(((Integer)i).toString());
+            sb.append(": ");
+            sb.append(getMRL(i));
+            sb.append(", ");
+        }
+        sb.append("}");
+        return sb.toString();
+    }
+
+    private void signal_list_event(int event, int position, String uri) {
+        Bundle b = new Bundle();
+        b.putString("item_uri", uri);
+        b.putInt("item_index", position);
+        mEventHandler.callback(event, b);
+    }
+}
diff --git a/vlc-android/src/org/videolan/vlc/MediaHolderListPlayer.java b/vlc-android/src/org/videolan/vlc/MediaHolderListPlayer.java
new file mode 100644
index 0000000..6fb01a6
--- /dev/null
+++ b/vlc-android/src/org/videolan/vlc/MediaHolderListPlayer.java
@@ -0,0 +1,91 @@
+/*****************************************************************************
+ * MediaHolderListPlayer.java
+ *****************************************************************************
+ * Copyright © 2015 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.
+ *****************************************************************************/
+
+package org.videolan.vlc;
+
+import java.util.ArrayList;
+
+import org.videolan.libvlc.LibVLC;
+
+
+public class MediaHolderListPlayer {
+
+    private int mPlayerIndex = 0;
+    final private LibVLC mLibVLC;
+    final private MediaHolderList mMediaList;
+
+    public MediaHolderListPlayer(LibVLC libVLC) {
+        mLibVLC = libVLC;
+        mMediaList = new MediaHolderList(libVLC);
+    }
+
+    public MediaHolderList getMediaList() {
+        return mMediaList;
+    }
+
+    /**
+     * Play a media from the media list (playlist)
+     *
+     * @param position The index of the media
+     */
+    public void playIndex(int position) {
+        String mrl = mMediaList.getMRL(position);
+        if (mrl == null)
+            return;
+
+        final MediaHolder media = mMediaList.getMedia(position);
+        String[] options = mLibVLC.getMediaOptions(media != null ? media.getFlags() : 0);
+        mPlayerIndex = position;
+        mLibVLC.playMRL(mrl, options);
+    }
+
+    /**
+     * Expand and continue playing the current media.
+     *
+     * @return the index of the media was expanded, and -1 if no media was expanded
+     */
+   public int expandAndPlay() {
+       int r = expand();
+       if(r == 0)
+           playIndex(mPlayerIndex);
+       return r;
+   }
+
+   /**
+    * Expand the current media.
+    * @return the index of the media was expanded, and -1 if no media was expanded
+    */
+   public int expand() {
+       ArrayList<String> children = new ArrayList<String>();
+       int ret = mLibVLC.expandMedia(children);
+       if(ret == 0) {
+           mMediaList.remove(mPlayerIndex);
+           for(String mrl : children) {
+               mMediaList.insert(mPlayerIndex, mrl);
+           }
+       }
+       return ret;
+   }
+
+   public int expand(int index) {
+       mPlayerIndex = index;
+       return expand();
+   }
+}
diff --git a/vlc-android/src/org/videolan/vlc/MediaLibrary.java b/vlc-android/src/org/videolan/vlc/MediaLibrary.java
index 15c8ad3..7c1b319 100644
--- a/vlc-android/src/org/videolan/vlc/MediaLibrary.java
+++ b/vlc-android/src/org/videolan/vlc/MediaLibrary.java
@@ -35,7 +35,6 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import org.videolan.libvlc.LibVLC;
 import org.videolan.libvlc.LibVlcException;
-import org.videolan.libvlc.Media;
 import org.videolan.vlc.gui.MainActivity;
 import org.videolan.vlc.util.AndroidDevices;
 import org.videolan.vlc.util.Util;
@@ -54,7 +53,7 @@ public class MediaLibrary {
     public static final int MEDIA_ITEMS_UPDATED = 100;
 
     private static MediaLibrary mInstance;
-    private final ArrayList<Media> mItemList;
+    private final ArrayList<MediaHolder> mItemList;
     private final ArrayList<Handler> mUpdateHandler;
     private final ReadWriteLock mItemListLock;
     private boolean isStopping = false;
@@ -82,7 +81,7 @@ public class MediaLibrary {
 
     private MediaLibrary() {
         mInstance = this;
-        mItemList = new ArrayList<Media>();
+        mItemList = new ArrayList<MediaHolder>();
         mUpdateHandler = new ArrayList<Handler>();
         mItemListLock = new ReentrantReadWriteLock();
     }
@@ -133,8 +132,8 @@ public class MediaLibrary {
         mUpdateHandler.remove(handler);
     }
 
-    public ArrayList<Media> searchMedia(String query, int type){
-        ArrayList<Media> mediaList = new ArrayList<Media>();
+    public ArrayList<MediaHolder> searchMedia(String query, int type){
+        ArrayList<MediaHolder> mediaList = new ArrayList<MediaHolder>();
         ArrayList<String> pathList = MediaDatabase.getInstance().searchMedia(query, type);
         if (!pathList.isEmpty()){
             for (String path : pathList) {
@@ -144,12 +143,12 @@ public class MediaLibrary {
         return mediaList;
     }
 
-    public ArrayList<Media> getVideoItems() {
-        ArrayList<Media> videoItems = new ArrayList<Media>();
+    public ArrayList<MediaHolder> getVideoItems() {
+        ArrayList<MediaHolder> videoItems = new ArrayList<MediaHolder>();
         mItemListLock.readLock().lock();
         for (int i = 0; i < mItemList.size(); i++) {
-            Media item = mItemList.get(i);
-            if (item != null && item.getType() == Media.TYPE_VIDEO) {
+            MediaHolder item = mItemList.get(i);
+            if (item != null && item.getType() == MediaHolder.TYPE_VIDEO) {
                 videoItems.add(item);
             }
         }
@@ -157,12 +156,12 @@ public class MediaLibrary {
         return videoItems;
     }
 
-    public ArrayList<Media> getAudioItems() {
-        ArrayList<Media> audioItems = new ArrayList<Media>();
+    public ArrayList<MediaHolder> getAudioItems() {
+        ArrayList<MediaHolder> audioItems = new ArrayList<MediaHolder>();
         mItemListLock.readLock().lock();
         for (int i = 0; i < mItemList.size(); i++) {
-            Media item = mItemList.get(i);
-            if (item.getType() == Media.TYPE_AUDIO) {
+            MediaHolder item = mItemList.get(i);
+            if (item.getType() == MediaHolder.TYPE_AUDIO) {
                 audioItems.add(item);
             }
         }
@@ -170,14 +169,14 @@ public class MediaLibrary {
         return audioItems;
     }
 
-    public ArrayList<Media> getMediaItems() {
+    public ArrayList<MediaHolder> getMediaItems() {
         return mItemList;
     }
 
-    public Media getMediaItem(String location) {
+    public MediaHolder getMediaItem(String location) {
         mItemListLock.readLock().lock();
         for (int i = 0; i < mItemList.size(); i++) {
-            Media item = mItemList.get(i);
+            MediaHolder item = mItemList.get(i);
             if (item.getLocation().equals(location)) {
                 mItemListLock.readLock().unlock();
                 return item;
@@ -187,10 +186,10 @@ public class MediaLibrary {
         return null;
     }
 
-    public ArrayList<Media> getMediaItems(List<String> pathList) {
-        ArrayList<Media> items = new ArrayList<Media>();
+    public ArrayList<MediaHolder> getMediaItems(List<String> pathList) {
+        ArrayList<MediaHolder> items = new ArrayList<MediaHolder>();
         for (int i = 0; i < pathList.size(); i++) {
-            Media item = getMediaItem(pathList.get(i));
+            MediaHolder item = getMediaItem(pathList.get(i));
             items.add(item);
         }
         return items;
@@ -233,7 +232,7 @@ public class MediaLibrary {
             directories.addAll(mediaDirs);
 
             // get all existing media items
-            HashMap<String, Media> existingMedias = DBManager.getMedias();
+            HashMap<String, MediaHolder> existingMedias = DBManager.getMedias();
 
             // list of all added files
             HashSet<String> addedLocations = new HashSet<String>();
@@ -319,7 +318,7 @@ public class MediaLibrary {
                     } else {
                         mItemListLock.writeLock().lock();
                         // create new media item
-                        Media m = new Media(libVlcInstance, fileURI);
+                        MediaHolder m = new MediaHolder(libVlcInstance, fileURI);
                         mItemList.add(m);
                         // Add this item to database
                         MediaDatabase db = MediaDatabase.getInstance();
@@ -396,8 +395,8 @@ public class MediaLibrary {
                     int dotIndex = fileName.lastIndexOf(".");
                     if (dotIndex != -1) {
                         String fileExt = fileName.substring(dotIndex);
-                        accepted = Media.AUDIO_EXTENSIONS.contains(fileExt) ||
-                                   Media.VIDEO_EXTENSIONS.contains(fileExt);
+                        accepted = MediaHolder.AUDIO_EXTENSIONS.contains(fileExt) ||
+                                   MediaHolder.VIDEO_EXTENSIONS.contains(fileExt);
                     }
                 }
             }
diff --git a/vlc-android/src/org/videolan/vlc/Thumbnailer.java b/vlc-android/src/org/videolan/vlc/Thumbnailer.java
index 22280d6..f99c074 100644
--- a/vlc-android/src/org/videolan/vlc/Thumbnailer.java
+++ b/vlc-android/src/org/videolan/vlc/Thumbnailer.java
@@ -31,7 +31,6 @@ import java.util.concurrent.locks.ReentrantLock;
 
 import org.videolan.libvlc.LibVLC;
 import org.videolan.libvlc.LibVlcException;
-import org.videolan.libvlc.Media;
 import org.videolan.vlc.gui.video.VideoBrowserInterface;
 import org.videolan.vlc.util.BitmapUtil;
 import org.videolan.vlc.util.VLCInstance;
@@ -48,7 +47,7 @@ public class Thumbnailer implements Runnable {
 
     private VideoBrowserInterface mVideoBrowser;
 
-    private final Queue<Media> mItems = new LinkedList<Media>();
+    private final Queue<MediaHolder> mItems = new LinkedList<MediaHolder>();
 
     private boolean isStopping = false;
     private final Lock lock = new ReentrantLock();
@@ -114,7 +113,7 @@ public class Thumbnailer implements Runnable {
      * Add a new id of the file browser item to create its thumbnail.
      * @param id the if of the file browser item.
      */
-    public void addJob(Media item) {
+    public void addJob(MediaHolder item) {
         if(BitmapUtil.getPictureFromCache(item) != null || item.isPictureParsed())
             return;
         lock.lock();
@@ -160,7 +159,7 @@ public class Thumbnailer implements Runnable {
                 break;
             }
             total = totalCount;
-            Media item = mItems.poll();
+            MediaHolder item = mItems.poll();
             lock.unlock();
 
             if (mVideoBrowser != null) {
diff --git a/vlc-android/src/org/videolan/vlc/audio/AudioService.java b/vlc-android/src/org/videolan/vlc/audio/AudioService.java
index 62f2977..0fd43f7 100644
--- a/vlc-android/src/org/videolan/vlc/audio/AudioService.java
+++ b/vlc-android/src/org/videolan/vlc/audio/AudioService.java
@@ -44,10 +44,10 @@ import org.videolan.libvlc.EventHandler;
 import org.videolan.libvlc.LibVLC;
 import org.videolan.libvlc.LibVlcException;
 import org.videolan.libvlc.LibVlcUtil;
-import org.videolan.libvlc.Media;
-import org.videolan.libvlc.MediaList;
-import org.videolan.libvlc.MediaListPlayer;
+import org.videolan.vlc.MediaHolder;
 import org.videolan.vlc.MediaDatabase;
+import org.videolan.vlc.MediaHolderList;
+import org.videolan.vlc.MediaHolderListPlayer;
 import org.videolan.vlc.R;
 import org.videolan.vlc.RemoteControlClientReceiver;
 import org.videolan.vlc.VLCApplication;
@@ -123,7 +123,7 @@ public class AudioService extends Service {
     public static final int NEXT_ITEM = 3;
 
     private LibVLC mLibVLC;
-    private MediaListPlayer mMediaListPlayer;
+    private MediaHolderListPlayer mMediaListPlayer;
     private HashMap<IAudioServiceCallback, Integer> mCallback;
     private EventHandler mEventHandler;
     private OnAudioFocusChangeListener audioFocusListener;
@@ -170,7 +170,7 @@ public class AudioService extends Service {
         } catch (LibVlcException e) {
             e.printStackTrace();
         }
-        mMediaListPlayer = new MediaListPlayer(mLibVLC);
+        mMediaListPlayer = new MediaHolderListPlayer(mLibVLC);
 
         mCallback = new HashMap<IAudioServiceCallback, Integer>();
         mCurrentIndex = -1;
@@ -479,7 +479,7 @@ public class AudioService extends Service {
                     String location = service.mMediaListPlayer.getMediaList().getMRL(service.mCurrentIndex);
                     long length = service.mLibVLC.getLength();
                     MediaDatabase dbManager = MediaDatabase.getInstance();
-                    Media m = dbManager.getMedia(location);
+                    MediaHolder m = dbManager.getMedia(location);
                     /**
                      * 1) There is a media to update
                      * 2) It has a length of 0
@@ -677,7 +677,7 @@ public class AudioService extends Service {
     }
 
     private void executeOnMediaPlayedAdded() {
-        final Media media = mMediaListPlayer.getMediaList().getMedia(mCurrentIndex);
+        final MediaHolder media = mMediaListPlayer.getMediaList().getMedia(mCurrentIndex);
         for (IAudioServiceCallback callback : mCallback.keySet()) {
             try {
                 callback.onMediaPlayedAdded(media, 0);
@@ -692,7 +692,7 @@ public class AudioService extends Service {
      *
      * @return The current media or null if there is not any.
      */
-    private Media getCurrentMedia() {
+    private MediaHolder getCurrentMedia() {
         return mMediaListPlayer.getMediaList().getMedia(mCurrentIndex);
     }
 
@@ -738,7 +738,7 @@ public class AudioService extends Service {
     @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
     private void showNotification() {
         try {
-            Media media = getCurrentMedia();
+            MediaHolder media = getCurrentMedia();
             if (media == null)
                 return;
             Bitmap cover = AudioUtil.getCover(this, media, 64);
@@ -961,7 +961,7 @@ public class AudioService extends Service {
         if (!LibVlcUtil.isICSOrLater()) // NOP check
             return;
 
-        Media media = getCurrentMedia();
+        MediaHolder media = getCurrentMedia();
         if (mRemoteControlClient != null && media != null) {
             MetadataEditor editor = mRemoteControlClient.editMetadata(true);
             if (media.getNowPlaying() != null) {
@@ -1031,7 +1031,7 @@ public class AudioService extends Service {
     }
 
     private Bitmap getCover() {
-        Media media = getCurrentMedia();
+        MediaHolder media = getCurrentMedia();
         return media != null ? AudioUtil.getCover(this, media, 512) : null;
     }
 
@@ -1083,7 +1083,7 @@ public class AudioService extends Service {
         @Override
         public String getArtist() throws RemoteException {
             if (hasCurrentMedia()) {
-                final Media media = getCurrentMedia();
+                final MediaHolder media = getCurrentMedia();
                 return media.isArtistUnknown() && media.getNowPlaying() != null ?
                         media.getNowPlaying()
                         : Util.getMediaArtist(AudioService.this, media);
@@ -1206,14 +1206,14 @@ public class AudioService extends Service {
 
             mMediaListPlayer.getMediaList().getEventHandler().removeHandler(mListEventHandler);
             mMediaListPlayer.getMediaList().clear();
-            MediaList mediaList = mMediaListPlayer.getMediaList();
+            MediaHolderList mediaList = mMediaListPlayer.getMediaList();
 
             mPrevious.clear();
 
             MediaDatabase db = MediaDatabase.getInstance();
             for (int i = 0; i < mediaPathList.size(); i++) {
                 String location = mediaPathList.get(i);
-                Media media = db.getMedia(location);
+                MediaHolder media = db.getMedia(location);
                 if(media == null) {
                     if(!validateLocation(location)) {
                         Log.w(TAG, "Invalid location " + location);
@@ -1221,7 +1221,7 @@ public class AudioService extends Service {
                         continue;
                     }
                     Log.v(TAG, "Creating on-the-fly Media object for " + location);
-                    media = new Media(mLibVLC, location);
+                    media = new MediaHolder(mLibVLC, location);
                 }
                 if (noVideo)
                     media.addFlags(LibVLC.MEDIA_FLAG_NO_VIDEO);
@@ -1322,14 +1322,14 @@ public class AudioService extends Service {
             MediaDatabase db = MediaDatabase.getInstance();
             for (int i = 0; i < mediaLocationList.size(); i++) {
                 String location = mediaLocationList.get(i);
-                Media media = db.getMedia(location);
+                MediaHolder media = db.getMedia(location);
                 if(media == null) {
                     if (!validateLocation(location)) {
                         showToast(getResources().getString(R.string.invalid_location, location), Toast.LENGTH_SHORT);
                         continue;
                     }
                     Log.v(TAG, "Creating on-the-fly Media object for " + location);
-                    media = new Media(mLibVLC, location);
+                    media = new MediaHolder(mLibVLC, location);
                 }
                 mMediaListPlayer.getMediaList().add(media);
             }
@@ -1364,8 +1364,8 @@ public class AudioService extends Service {
         }
 
         @Override
-        public List<Media> getMedias() {
-            final ArrayList<Media> ml = new ArrayList<Media>();
+        public List<MediaHolder> getMedias() {
+            final ArrayList<MediaHolder> ml = new ArrayList<MediaHolder>();
             for (int i = 0; i < mMediaListPlayer.getMediaList().size(); i++) {
                 ml.add(mMediaListPlayer.getMediaList().getMedia(i));
             }
@@ -1450,7 +1450,7 @@ public class AudioService extends Service {
         i.setAction(ACTION_WIDGET_UPDATE);
 
         if (hasCurrentMedia()) {
-            final Media media = getCurrentMedia();
+            final MediaHolder media = getCurrentMedia();
             i.putExtra("title", media.getTitle());
             i.putExtra("artist", media.isArtistUnknown() && media.getNowPlaying() != null ?
                     media.getNowPlaying()
diff --git a/vlc-android/src/org/videolan/vlc/audio/AudioServiceController.java b/vlc-android/src/org/videolan/vlc/audio/AudioServiceController.java
index 2901961..30e65d6 100644
--- a/vlc-android/src/org/videolan/vlc/audio/AudioServiceController.java
+++ b/vlc-android/src/org/videolan/vlc/audio/AudioServiceController.java
@@ -25,7 +25,7 @@ import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.videolan.libvlc.Media;
+import org.videolan.vlc.MediaHolder;
 import org.videolan.vlc.interfaces.IAudioPlayer;
 import org.videolan.vlc.interfaces.IAudioPlayerControl;
 import org.videolan.vlc.interfaces.IAudioService;
@@ -53,7 +53,7 @@ public class AudioServiceController implements IAudioPlayerControl {
     private final ArrayList<MediaPlayedListener> mMediaPlayedListener;
 
     public interface MediaPlayedListener {
-        public void onMediaPlayedAdded(Media media, int index);
+        public void onMediaPlayedAdded(MediaHolder media, int index);
         public void onMediaPlayedRemoved(int index);
     }
 
@@ -69,7 +69,7 @@ public class AudioServiceController implements IAudioPlayerControl {
         }
 
         @Override
-        public void onMediaPlayedAdded(Media media, int index) throws RemoteException {
+        public void onMediaPlayedAdded(MediaHolder media, int index) throws RemoteException {
             updateMediaPlayedAdded(media, index);
         }
 
@@ -239,7 +239,7 @@ public class AudioServiceController implements IAudioPlayerControl {
             player.updateProgress();
     }
 
-    private void updateMediaPlayedAdded(Media media, int index) {
+    private void updateMediaPlayedAdded(MediaHolder media, int index) {
         for (MediaPlayedListener listener : mMediaPlayedListener) {
             listener.onMediaPlayedAdded(media, index);
         }
@@ -337,7 +337,7 @@ public class AudioServiceController implements IAudioPlayerControl {
     }
 
     @SuppressWarnings("unchecked")
-    public List<Media> getMedias() {
+    public List<MediaHolder> getMedias() {
         return remoteProcedureCall(mAudioServiceBinder, List.class, null, "getMedias", null, null);
     }
 
diff --git a/vlc-android/src/org/videolan/vlc/gui/DirectoryAdapter.java b/vlc-android/src/org/videolan/vlc/gui/DirectoryAdapter.java
index a499db8..21a2bd3 100644
--- a/vlc-android/src/org/videolan/vlc/gui/DirectoryAdapter.java
+++ b/vlc-android/src/org/videolan/vlc/gui/DirectoryAdapter.java
@@ -29,7 +29,7 @@ import java.util.ListIterator;
 import java.util.regex.Pattern;
 
 import org.videolan.libvlc.LibVLC;
-import org.videolan.libvlc.Media;
+import org.videolan.vlc.MediaHolder;
 import org.videolan.vlc.R;
 import org.videolan.vlc.VLCApplication;
 import org.videolan.vlc.util.AndroidDevices;
@@ -59,14 +59,14 @@ public class DirectoryAdapter extends BaseAdapter {
         final StringBuilder sb = new StringBuilder();
         sb.append(".+(\\.)((?i)(");
         boolean first = true;
-        for (String ext : Media.VIDEO_EXTENSIONS) {
+        for (String ext : MediaHolder.VIDEO_EXTENSIONS) {
             if (!first)
                 sb.append('|');
             else
                 first = false;
             sb.append(ext.substring(1));
         }
-        for (String ext : Media.AUDIO_EXTENSIONS) {
+        for (String ext : MediaHolder.AUDIO_EXTENSIONS) {
             sb.append('|');
             sb.append(ext.substring(1));
         }
@@ -343,7 +343,7 @@ public class DirectoryAdapter extends BaseAdapter {
         String holderText = "";
         if(selectedNode.isFile()) {
             Log.d(TAG, "Loading media " + selectedNode.name);
-            Media m = new Media(LibVLC.getExistingInstance(), getMediaLocation(position));
+            MediaHolder m = new MediaHolder(LibVLC.getExistingInstance(), getMediaLocation(position));
             holder.title.setText(m.getTitle());
             holderText = Util.getMediaSubtitle(context, m);
         } else
diff --git a/vlc-android/src/org/videolan/vlc/gui/HistoryAdapter.java b/vlc-android/src/org/videolan/vlc/gui/HistoryAdapter.java
index 2b96c8a..b85dcee 100644
--- a/vlc-android/src/org/videolan/vlc/gui/HistoryAdapter.java
+++ b/vlc-android/src/org/videolan/vlc/gui/HistoryAdapter.java
@@ -22,7 +22,7 @@ package org.videolan.vlc.gui;
 
 import java.util.ArrayList;
 
-import org.videolan.libvlc.Media;
+import org.videolan.vlc.MediaHolder;
 import org.videolan.vlc.R;
 import org.videolan.vlc.VLCApplication;
 import org.videolan.vlc.audio.AudioServiceController;
@@ -44,14 +44,14 @@ public class HistoryAdapter extends BaseAdapter implements AudioServiceControlle
 
     private LayoutInflater mInflater;
     private final AudioServiceController mAudioController;
-    private final ArrayList<Media> mMediaList;
+    private final ArrayList<MediaHolder> mMediaList;
 
     public HistoryAdapter(Context context) {
         mInflater = LayoutInflater.from(context);
 
         mAudioController = AudioServiceController.getInstance();
 
-        mMediaList = new ArrayList<Media>();
+        mMediaList = new ArrayList<MediaHolder>();
 
         mAudioController.addMediaPlayedListener(this);
     }
@@ -94,7 +94,7 @@ public class HistoryAdapter extends BaseAdapter implements AudioServiceControlle
             holder = (DirectoryAdapter.DirectoryViewHolder) v.getTag();
 
         String holderText = "";
-        Media m = mMediaList.get(position);
+        MediaHolder m = mMediaList.get(position);
         if (m == null )
             return v;
 
@@ -117,7 +117,7 @@ public class HistoryAdapter extends BaseAdapter implements AudioServiceControlle
     }
 
     @Override
-    public void onMediaPlayedAdded(Media media, int index) {
+    public void onMediaPlayedAdded(MediaHolder media, int index) {
         mMediaList.add(index, media);
         notifyDataSetChanged();
     }
diff --git a/vlc-android/src/org/videolan/vlc/gui/SearchFragment.java b/vlc-android/src/org/videolan/vlc/gui/SearchFragment.java
index da8c950..e2feed2 100644
--- a/vlc-android/src/org/videolan/vlc/gui/SearchFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/SearchFragment.java
@@ -22,7 +22,7 @@ package org.videolan.vlc.gui;
 
 import java.util.ArrayList;
 
-import org.videolan.libvlc.Media;
+import org.videolan.vlc.MediaHolder;
 import org.videolan.vlc.MediaDatabase;
 import org.videolan.vlc.MediaLibrary;
 import org.videolan.vlc.R;
@@ -105,7 +105,7 @@ public class SearchFragment extends ListFragment {
         mResultAdapter.clear();
         new Thread(new Runnable() {
             public void run() {
-                final ArrayList<Media> mediaList = MediaLibrary.getInstance().searchMedia(key, type);
+                final ArrayList<MediaHolder> mediaList = MediaLibrary.getInstance().searchMedia(key, type);
                 mHandler.post(new Runnable() {
                     public void run() {
                         int count = mediaList.size();
@@ -158,7 +158,7 @@ public class SearchFragment extends ListFragment {
         @Override
         public void onTextChanged(CharSequence s, int start, int before, int count) {
             if (s.length() > 0) {
-                search(s.toString(), Media.TYPE_ALL);
+                search(s.toString(), MediaHolder.TYPE_ALL);
             } else {
                 showSearchHistory();
             }
@@ -198,15 +198,15 @@ public class SearchFragment extends ListFragment {
             db.addSearchhistoryItem(mSearchText.getText().toString());
 
             // open media in the player
-            Media item = (Media) getListView().getItemAtPosition(position);
+            MediaHolder item = (MediaHolder) getListView().getItemAtPosition(position);
             if (item != null) {
-                if (item.getType() == Media.TYPE_VIDEO) {
+                if (item.getType() == MediaHolder.TYPE_VIDEO) {
                     VideoPlayerActivity.start(getActivity(), item.getLocation());
                 } else {
                     ArrayList<String> arr = new ArrayList<String>();
                     for (int i = 0; i < getListAdapter().getCount(); i++) {
-                        Media audioItem = (Media) getListAdapter().getItem(i);
-                        if (audioItem.getType() == Media.TYPE_AUDIO)
+                        MediaHolder audioItem = (MediaHolder) getListAdapter().getItem(i);
+                        if (audioItem.getType() == MediaHolder.TYPE_AUDIO)
                             arr.add(audioItem.getLocation());
                     }
                     AudioServiceController.getInstance().load(arr, arr.indexOf(item.getLocation()));
diff --git a/vlc-android/src/org/videolan/vlc/gui/SearchResultAdapter.java b/vlc-android/src/org/videolan/vlc/gui/SearchResultAdapter.java
index 6eb7a36..c068152 100644
--- a/vlc-android/src/org/videolan/vlc/gui/SearchResultAdapter.java
+++ b/vlc-android/src/org/videolan/vlc/gui/SearchResultAdapter.java
@@ -22,7 +22,7 @@ package org.videolan.vlc.gui;
 
 import java.util.Comparator;
 
-import org.videolan.libvlc.Media;
+import org.videolan.vlc.MediaHolder;
 
 import android.content.Context;
 import android.view.LayoutInflater;
@@ -31,8 +31,8 @@ import android.view.ViewGroup;
 import android.widget.ArrayAdapter;
 import android.widget.TextView;
 
-public class SearchResultAdapter extends ArrayAdapter<Media>
-        implements Comparator<Media> {
+public class SearchResultAdapter extends ArrayAdapter<MediaHolder>
+        implements Comparator<MediaHolder> {
 
     public SearchResultAdapter(Context context) {
         super(context, 0);
@@ -51,14 +51,14 @@ public class SearchResultAdapter extends ArrayAdapter<Media>
         } else
             holder = (ViewHolder) view.getTag();
 
-        Media item = getItem(position);
+        MediaHolder item = getItem(position);
         holder.text.setText(item.getTitle());
 
         return view;
     }
 
     @Override
-    public int compare(Media object1, Media object2) {
+    public int compare(MediaHolder object1, MediaHolder object2) {
         return object1.getTitle().compareToIgnoreCase(object2.getTitle());
     }
 
diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/AudioAlbumsSongsFragment.java b/vlc-android/src/org/videolan/vlc/gui/audio/AudioAlbumsSongsFragment.java
index 457871c..da8bee3 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioAlbumsSongsFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioAlbumsSongsFragment.java
@@ -25,7 +25,7 @@ import java.util.Collections;
 import java.util.List;
 
 import org.videolan.libvlc.LibVlcUtil;
-import org.videolan.libvlc.Media;
+import org.videolan.vlc.MediaHolder;
 import org.videolan.vlc.MediaLibrary;
 import org.videolan.vlc.R;
 import org.videolan.vlc.audio.AudioServiceController;
@@ -81,7 +81,7 @@ public class AudioAlbumsSongsFragment extends Fragment implements SwipeRefreshLa
     public final static String EXTRA_NAME2 = "name2";
     public final static String EXTRA_MODE = "mode";
 
-    private ArrayList<Media> mediaList;
+    private ArrayList<MediaHolder> mediaList;
     private String mTitle;
 
     TabHost mTabHost;
@@ -91,7 +91,7 @@ public class AudioAlbumsSongsFragment extends Fragment implements SwipeRefreshLa
     /* All subclasses of Fragment must include a public empty constructor. */
     public AudioAlbumsSongsFragment() { }
 
-    public void setMediaList(ArrayList<Media> mediaList, String title) {
+    public void setMediaList(ArrayList<MediaHolder> mediaList, String title) {
         this.mediaList = mediaList;
         mTitle = title;
     }
@@ -296,7 +296,7 @@ public class AudioAlbumsSongsFragment extends Fragment implements SwipeRefreshLa
                         @Override
                         public void run(Object o) {
                             AudioBrowserListAdapter.ListItem listItem = (AudioBrowserListAdapter.ListItem)o;
-                            Media media = listItem.mMediaList.get(0);
+                            MediaHolder media = listItem.mMediaList.get(0);
                             mMediaLibrary.getMediaItems().remove(media);
                             mSongsAdapter.removeMedia(media);
                             mAlbumsAdapter.removeMedia(media);
@@ -355,7 +355,7 @@ public class AudioAlbumsSongsFragment extends Fragment implements SwipeRefreshLa
                     @Override
                     public void run() {
                         for (int i = 0; i < mediaList.size(); ++i) {
-                            Media media = mediaList.get(i);
+                            MediaHolder media = mediaList.get(i);
                             mAlbumsAdapter.addSeparator(Util.getMediaReferenceArtist(activity, media), media);
                             mAlbumsAdapter.add(Util.getMediaAlbum(activity, media), null, media);
                             mSongsAdapter.addSeparator(Util.getMediaAlbum(activity, media), media);
diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.java b/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.java
index 8f3c120..4fb7497 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.java
@@ -51,7 +51,7 @@ import android.widget.PopupMenu;
 import android.widget.PopupMenu.OnMenuItemClickListener;
 
 import org.videolan.libvlc.LibVlcUtil;
-import org.videolan.libvlc.Media;
+import org.videolan.vlc.MediaHolder;
 import org.videolan.vlc.MediaLibrary;
 import org.videolan.vlc.R;
 import org.videolan.vlc.audio.AudioServiceController;
@@ -83,7 +83,7 @@ public class AudioBrowserFragment extends Fragment implements SwipeRefreshLayout
     private AudioServiceController mAudioController;
     private MediaLibrary mMediaLibrary;
 
-    List<Media> mAudioList;
+    List<MediaHolder> mAudioList;
     private AudioBrowserListAdapter mArtistsAdapter;
     private AudioBrowserListAdapter mAlbumsAdapter;
     private AudioBrowserListAdapter mSongsAdapter;
@@ -302,7 +302,7 @@ public class AudioBrowserFragment extends Fragment implements SwipeRefreshLayout
     OnItemClickListener artistListListener = new OnItemClickListener() {
         @Override
         public void onItemClick(AdapterView<?> av, View v, int p, long id) {
-            ArrayList<Media> mediaList = mArtistsAdapter.getMedia(p);
+            ArrayList<MediaHolder> mediaList = mArtistsAdapter.getMedia(p);
             MainActivity activity = (MainActivity)getActivity();
             AudioAlbumsSongsFragment frag = (AudioAlbumsSongsFragment)activity.showSecondaryFragment("albumsSongs");
             if (frag != null) {
@@ -322,7 +322,7 @@ public class AudioBrowserFragment extends Fragment implements SwipeRefreshLayout
     OnItemClickListener genreListListener = new OnItemClickListener() {
         @Override
         public void onItemClick(AdapterView<?> av, View v, int p, long id) {
-            ArrayList<Media> mediaList = mGenresAdapter.getMedia(p);
+            ArrayList<MediaHolder> mediaList = mGenresAdapter.getMedia(p);
             MainActivity activity = (MainActivity)getActivity();
             AudioAlbumsSongsFragment frag = (AudioAlbumsSongsFragment)activity.showSecondaryFragment("albumsSongs");
             if (frag != null) {
@@ -389,7 +389,7 @@ public class AudioBrowserFragment extends Fragment implements SwipeRefreshLayout
                         @Override
                         public void run(Object o) {
                             AudioBrowserListAdapter.ListItem listItem = (AudioBrowserListAdapter.ListItem)o;
-                            Media media = listItem.mMediaList.get(0);
+                            MediaHolder media = listItem.mMediaList.get(0);
                             mMediaLibrary.getMediaItems().remove(media);
                             mAudioController.removeLocation(media.getLocation());
                             updateLists();
diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserListAdapter.java b/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserListAdapter.java
index 0e3aafb..780fcf9 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserListAdapter.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserListAdapter.java
@@ -28,7 +28,7 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 
-import org.videolan.libvlc.Media;
+import org.videolan.vlc.MediaHolder;
 import org.videolan.vlc.R;
 import org.videolan.vlc.util.BitmapCache;
 import org.videolan.vlc.util.Util;
@@ -84,11 +84,11 @@ public class AudioBrowserListAdapter extends BaseAdapter implements SectionIndex
     class ListItem {
         public String mTitle;
         public String mSubTitle;
-        public ArrayList<Media> mMediaList;
+        public ArrayList<MediaHolder> mMediaList;
         public boolean mIsSeparator;
 
-        public ListItem(String title, String subTitle, Media media, boolean isSeparator) {
-            mMediaList = new ArrayList<Media>();
+        public ListItem(String title, String subTitle, MediaHolder media, boolean isSeparator) {
+            mMediaList = new ArrayList<MediaHolder>();
             if (media != null)
                 mMediaList.add(media);
             mTitle = title;
@@ -110,7 +110,7 @@ public class AudioBrowserListAdapter extends BaseAdapter implements SectionIndex
         mAlignMode = Integer.valueOf(preferences.getString("audio_title_alignment", "0"));
     }
 
-    public void add(String title, String subTitle, Media media) {
+    public void add(String title, String subTitle, MediaHolder media) {
         if(title == null) return;
         title = title.trim();
         if(subTitle != null) subTitle = subTitle.trim();
@@ -123,13 +123,13 @@ public class AudioBrowserListAdapter extends BaseAdapter implements SectionIndex
         }
     }
 
-    public void addAll(List<Media> mediaList, final int type) {
-        final LinkedList<Media> list = new LinkedList<Media>(mediaList);
+    public void addAll(List<MediaHolder> mediaList, final int type) {
+        final LinkedList<MediaHolder> list = new LinkedList<MediaHolder>(mediaList);
         mContext.runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 String title, subTitle;
-                for (Media media : list) {
+                for (MediaHolder media : list) {
                     switch (type){
                         case TYPE_ALBUMS:
                             title = Util.getMediaAlbum(mContext, media);
@@ -217,7 +217,7 @@ public class AudioBrowserListAdapter extends BaseAdapter implements SectionIndex
         }
     }
 
-    public void addSeparator(String title, Media media) {
+    public void addSeparator(String title, MediaHolder media) {
         if(title == null) return;
         title = title.trim();
         if (mSeparatorItemMap.containsKey(title))
@@ -234,7 +234,7 @@ public class AudioBrowserListAdapter extends BaseAdapter implements SectionIndex
         for (ListItem album : mSeparatorItemMap.values()){
             mItems.add(album);
             Collections.sort(album.mMediaList, MediaComparators.byTrackNumber);
-            for (Media media : album.mMediaList)
+            for (MediaHolder media : album.mMediaList)
                 add(media.getTitle(), null, media);
         }
     }
@@ -244,7 +244,7 @@ public class AudioBrowserListAdapter extends BaseAdapter implements SectionIndex
      * Remove also all the list items that contain only this media.
      * @param media the media to remove
      */
-    public void removeMedia(Media media) {
+    public void removeMedia(MediaHolder media) {
         for (int i = 0; i < mItems.size(); ++i) {
             ListItem item = mItems.get(i);
             if (item.mMediaList == null)
@@ -312,7 +312,7 @@ public class AudioBrowserListAdapter extends BaseAdapter implements SectionIndex
 
         RelativeLayout.LayoutParams paramsCover;
         if (mItemType == ITEM_WITH_COVER) {
-            Media media = mItems.get(position).mMediaList.get(0);
+            MediaHolder media = mItems.get(position).mMediaList.get(0);
             Bitmap cover = AudioUtil.getCover(v.getContext(), media, 64);
             if (cover == null)
                 cover = BitmapCache.GetFromResource(v, R.drawable.icon);
@@ -462,9 +462,9 @@ public class AudioBrowserListAdapter extends BaseAdapter implements SectionIndex
         return sections.toArray();
     }
 
-    public ArrayList<Media> getMedia(int position) {
+    public ArrayList<MediaHolder> getMedia(int position) {
         // Return all the media of a list item list.
-        ArrayList<Media> mediaList = new ArrayList<Media>();
+        ArrayList<MediaHolder> mediaList = new ArrayList<MediaHolder>();
         if (!mItems.get(position).mIsSeparator)
             mediaList.addAll(mItems.get(position).mMediaList);
         return mediaList;
@@ -478,7 +478,7 @@ public class AudioBrowserListAdapter extends BaseAdapter implements SectionIndex
         // Return all the media locations of a list item list.
         ArrayList<String> locations = new ArrayList<String>();
         if (isEnabled(position)) {
-            ArrayList<Media> mediaList = mItems.get(position).mMediaList;
+            ArrayList<MediaHolder> mediaList = mItems.get(position).mMediaList;
             if (sortByTrackNumber)
                 Collections.sort(mediaList, MediaComparators.byTrackNumber);
             for (int i = 0; i < mediaList.size(); ++i)
@@ -503,7 +503,7 @@ public class AudioBrowserListAdapter extends BaseAdapter implements SectionIndex
                 if(position == i && !mItems.get(i).mMediaList.isEmpty())
                     outputPosition = outputList.size();
 
-                for(Media k : mItems.get(i).mMediaList) {
+                for(MediaHolder k : mItems.get(i).mMediaList) {
                     outputList.add(k.getLocation());
                 }
             }
diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.java b/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.java
index ac592d6..b5970c5 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.java
@@ -25,7 +25,7 @@ import java.util.List;
 import android.content.Context;
 import android.content.Intent;
 
-import org.videolan.libvlc.Media;
+import org.videolan.vlc.MediaHolder;
 import org.videolan.vlc.R;
 import org.videolan.vlc.audio.AudioServiceController;
 import org.videolan.vlc.audio.RepeatType;
@@ -389,12 +389,12 @@ public class AudioPlayer extends Fragment implements IAudioPlayer {
 
         mSongsListAdapter.clear();
 
-        final List<Media> audioList = mAudioController.getMedias();
+        final List<MediaHolder> audioList = mAudioController.getMedias();
         final String currentItem = mAudioController.getCurrentMediaLocation();
 
         if (audioList != null) {
             for (int i = 0; i < audioList.size(); i++) {
-                final Media media = audioList.get(i);
+                final MediaHolder media = audioList.get(i);
                 if (currentItem != null && currentItem.equals(media.getLocation()))
                     currentIndex = i;
                 mSongsListAdapter.add(media);
diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlaylistAdapter.java b/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlaylistAdapter.java
index 239cd4c..c319fcf 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlaylistAdapter.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlaylistAdapter.java
@@ -23,7 +23,7 @@ package org.videolan.vlc.gui.audio;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.videolan.libvlc.Media;
+import org.videolan.vlc.MediaHolder;
 import org.videolan.vlc.R;
 import org.videolan.vlc.util.Util;
 import org.videolan.vlc.widget.AudioPlaylistItemViewGroup;
@@ -44,9 +44,9 @@ import android.widget.ImageButton;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
-public class AudioPlaylistAdapter extends ArrayAdapter<Media> {
+public class AudioPlaylistAdapter extends ArrayAdapter<MediaHolder> {
 
-    private ArrayList<Media> mMediaList;
+    private ArrayList<MediaHolder> mMediaList;
     private int mCurrentIndex;
     private Context mContext;
     private int mAlignMode;
@@ -54,20 +54,20 @@ public class AudioPlaylistAdapter extends ArrayAdapter<Media> {
     public AudioPlaylistAdapter(Context context) {
         super(context, 0);
         mContext = context;
-        mMediaList = new ArrayList<Media>();
+        mMediaList = new ArrayList<MediaHolder>();
         mCurrentIndex = -1;
         SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
         mAlignMode = Integer.valueOf(preferences.getString("audio_title_alignment", "0"));
     }
 
     @Override
-    public void add(Media m) {
+    public void add(MediaHolder m) {
         mMediaList.add(m);
         super.add(m);
     }
 
     @Override
-    public void remove(Media m) {
+    public void remove(MediaHolder m) {
         mMediaList.remove(m);
         super.remove(m);
     }
@@ -107,7 +107,7 @@ public class AudioPlaylistAdapter extends ArrayAdapter<Media> {
         holder.layoutFooter.setVisibility(LinearLayout.VISIBLE);
         holder.itemGroup.scrollTo(1);
 
-        Media media = getItem(position);
+        MediaHolder media = getItem(position);
         final String title = media.getTitle();
         final String artist = Util.getMediaSubtitle(mContext, media);
         final int pos = position;
diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/AudioUtil.java b/vlc-android/src/org/videolan/vlc/gui/audio/AudioUtil.java
index bfd3edb..ee0cec1 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioUtil.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioUtil.java
@@ -31,7 +31,7 @@ import java.security.NoSuchAlgorithmException;
 import java.util.Arrays;
 
 import org.videolan.libvlc.LibVlcUtil;
-import org.videolan.libvlc.Media;
+import org.videolan.vlc.MediaHolder;
 import org.videolan.vlc.R;
 import org.videolan.vlc.VLCApplication;
 import org.videolan.vlc.util.AndroidDevices;
@@ -74,7 +74,7 @@ public class AudioUtil {
      */
     public static String PLAYLIST_DIR = null;
 
-    public static void setRingtone(Media song, Context context){
+    public static void setRingtone(MediaHolder song, Context context){
         File newringtone = LibVlcUtil.URItoFile(song.getLocation());
         if(newringtone == null || (newringtone != null && !newringtone.exists())) {
             Toast.makeText(context.getApplicationContext(),context.getString(R.string.ringtone_error), Toast.LENGTH_SHORT).show();
@@ -152,7 +152,7 @@ public class AudioUtil {
             dir.delete();
     }
 
-    private static String getCoverFromMediaStore(Context context, Media media) {
+    private static String getCoverFromMediaStore(Context context, MediaHolder media) {
         final String album = media.getAlbum();
         if (album == null)
             return null;
@@ -177,7 +177,7 @@ public class AudioUtil {
         return null;
     }
 
-    private static String getCoverFromVlc(Context context, Media media) throws NoSuchAlgorithmException, UnsupportedEncodingException {
+    private static String getCoverFromVlc(Context context, MediaHolder media) throws NoSuchAlgorithmException, UnsupportedEncodingException {
         String artworkURL = media.getArtworkURL();
         if (artworkURL != null && artworkURL.startsWith("file://")) {
             return Uri.decode(artworkURL).replace("file://", "");
@@ -212,7 +212,7 @@ public class AudioUtil {
         return null;
     }
 
-    private static String getCoverFromFolder(Context context, Media media) {
+    private static String getCoverFromFolder(Context context, MediaHolder media) {
         File f = LibVlcUtil.URItoFile(media.getLocation());
         if (f != null && f.getParentFile() != null && f.getParentFile().listFiles() != null)
             for (File s : f.getParentFile().listFiles()) {
@@ -224,7 +224,7 @@ public class AudioUtil {
     }
 
     @SuppressLint("NewApi")
-    public synchronized static Bitmap getCover(Context context, Media media, int width) {
+    public synchronized static Bitmap getCover(Context context, MediaHolder media, int width) {
         String coverPath = null;
         Bitmap cover = null;
         String cachePath = null;
diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/MediaComparators.java b/vlc-android/src/org/videolan/vlc/gui/audio/MediaComparators.java
index eefe497..3ab11fb 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/MediaComparators.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/MediaComparators.java
@@ -21,7 +21,7 @@ package org.videolan.vlc.gui.audio;
 
 import java.util.Comparator;
 
-import org.videolan.libvlc.Media;
+import org.videolan.vlc.MediaHolder;
 
 public class MediaComparators {
 
@@ -35,32 +35,32 @@ public class MediaComparators {
         return String.CASE_INSENSITIVE_ORDER.compare(s1, s2);
     }
 
-    public static final Comparator<Media> byName = new Comparator<Media>() {
+    public static final Comparator<MediaHolder> byName = new Comparator<MediaHolder>() {
         @Override
-        public int compare(Media m1, Media m2) {
+        public int compare(MediaHolder m1, MediaHolder m2) {
             return nullInsensitiveStringCompare(m1.getTitle(), m2.getTitle());
         };
     };
 
-    public static final Comparator<Media> byMRL = new Comparator<Media>() {
+    public static final Comparator<MediaHolder> byMRL = new Comparator<MediaHolder>() {
         @Override
-        public int compare(Media m1, Media m2) {
+        public int compare(MediaHolder m1, MediaHolder m2) {
             return nullInsensitiveStringCompare(m1.getLocation(), m2.getLocation());
         };
     };
 
-    public static final Comparator<Media> byLength = new Comparator<Media>() {
+    public static final Comparator<MediaHolder> byLength = new Comparator<MediaHolder>() {
         @Override
-        public int compare(Media m1, Media m2) {
+        public int compare(MediaHolder m1, MediaHolder m2) {
             if(m1.getLength() > m2.getLength()) return -1;
             if(m1.getLength() < m2.getLength()) return 1;
             else return 0;
         };
     };
 
-    public static final Comparator<Media> byAlbum = new Comparator<Media>() {
+    public static final Comparator<MediaHolder> byAlbum = new Comparator<MediaHolder>() {
         @Override
-        public int compare(Media m1, Media m2) {
+        public int compare(MediaHolder m1, MediaHolder m2) {
             int res = nullInsensitiveStringCompare(m1.getAlbum(), m2.getAlbum());
             if (res == 0)
                 res = byMRL.compare(m1, m2);
@@ -68,9 +68,9 @@ public class MediaComparators {
         };
     };
 
-    public static final Comparator<Media> byArtist = new Comparator<Media>() {
+    public static final Comparator<MediaHolder> byArtist = new Comparator<MediaHolder>() {
         @Override
-        public int compare(Media m1, Media m2) {
+        public int compare(MediaHolder m1, MediaHolder m2) {
             int res = nullInsensitiveStringCompare(m1.getReferenceArtist(), m2.getReferenceArtist());
             if (res == 0)
                 res = byAlbum.compare(m1, m2);
@@ -78,9 +78,9 @@ public class MediaComparators {
         };
     };
 
-    public static final Comparator<Media> byGenre = new Comparator<Media>() {
+    public static final Comparator<MediaHolder> byGenre = new Comparator<MediaHolder>() {
         @Override
-        public int compare(Media m1, Media m2) {
+        public int compare(MediaHolder m1, MediaHolder m2) {
             int res = nullInsensitiveStringCompare(m1.getGenre(), m2.getGenre());
             if (res == 0)
                 res = byArtist.compare(m1, m2);
@@ -88,9 +88,9 @@ public class MediaComparators {
         };
     };
 
-    public static final Comparator<Media> byTrackNumber = new Comparator<Media>() {
+    public static final Comparator<MediaHolder> byTrackNumber = new Comparator<MediaHolder>() {
         @Override
-        public int compare(Media m1, Media m2) {
+        public int compare(MediaHolder m1, MediaHolder m2) {
             if(m1.getTrackNumber() < m2.getTrackNumber()) return -1;
             if(m1.getTrackNumber() > m2.getTrackNumber()) return 1;
             else return 0;
diff --git a/vlc-android/src/org/videolan/vlc/gui/video/MediaInfoFragment.java b/vlc-android/src/org/videolan/vlc/gui/video/MediaInfoFragment.java
index f2d97ed..b56c64c 100644
--- a/vlc-android/src/org/videolan/vlc/gui/video/MediaInfoFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/video/MediaInfoFragment.java
@@ -26,8 +26,8 @@ import java.nio.ByteBuffer;
 import org.videolan.libvlc.LibVLC;
 import org.videolan.libvlc.LibVlcException;
 import org.videolan.libvlc.LibVlcUtil;
-import org.videolan.libvlc.Media;
 import org.videolan.libvlc.TrackInfo;
+import org.videolan.vlc.MediaHolder;
 import org.videolan.vlc.MediaLibrary;
 import org.videolan.vlc.R;
 import org.videolan.vlc.gui.MainActivity;
@@ -60,7 +60,7 @@ public class MediaInfoFragment extends ListFragment {
     public final static String TAG = "VLC/MediaInfoFragment";
     LibVLC mLibVlc = null;
 
-    private Media mItem;
+    private MediaHolder mItem;
     private Bitmap mImage;
     private TextView mLengthView;
     private TextView mSizeView;
@@ -173,7 +173,7 @@ public class MediaInfoFragment extends ListFragment {
         for (int i = 0; i<files.length ; ++i){
             filename = Uri.decode(files[i]);
             extension = filename.substring(filename.lastIndexOf('.')+1);
-            if (!Media.SUBTITLES_EXTENSIONS.contains(extension))
+            if (!MediaHolder.SUBTITLES_EXTENSIONS.contains(extension))
                 continue;
             if (filename.startsWith(videoName)) {
                 mHandler.obtainMessage(SHOW_SUBTITLES).sendToTarget();
diff --git a/vlc-android/src/org/videolan/vlc/gui/video/VideoBrowserInterface.java b/vlc-android/src/org/videolan/vlc/gui/video/VideoBrowserInterface.java
index 69219ab..97cdbac 100644
--- a/vlc-android/src/org/videolan/vlc/gui/video/VideoBrowserInterface.java
+++ b/vlc-android/src/org/videolan/vlc/gui/video/VideoBrowserInterface.java
@@ -2,7 +2,7 @@ package org.videolan.vlc.gui.video;
 
 import java.util.concurrent.BrokenBarrierException;
 
-import org.videolan.libvlc.Media;
+import org.videolan.vlc.MediaHolder;
 
 public interface VideoBrowserInterface {
     public static final long HEADER_VIDEO = 0;
@@ -17,7 +17,7 @@ public interface VideoBrowserInterface {
 	public static final String AUDIO_FILTER = "filter";
 
 	public void resetBarrier();
-	public void setItemToUpdate(Media item);
+	public void setItemToUpdate(MediaHolder item);
 	public void await() throws InterruptedException, BrokenBarrierException;
 	public void updateItem();
 	public void updateList();
diff --git a/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.java b/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.java
index 1cb3233..601022b 100644
--- a/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.java
@@ -59,8 +59,8 @@ import android.widget.TextView;
 import org.videolan.libvlc.LibVLC;
 import org.videolan.libvlc.LibVlcException;
 import org.videolan.libvlc.LibVlcUtil;
-import org.videolan.libvlc.Media;
 import org.videolan.libvlc.TrackInfo;
+import org.videolan.vlc.MediaHolder;
 import org.videolan.vlc.MediaDatabase;
 import org.videolan.vlc.MediaGroup;
 import org.videolan.vlc.MediaLibrary;
@@ -96,7 +96,7 @@ public class VideoGridFragment extends Fragment implements IBrowser, ISortable,
     protected GridView mGridView;
     protected TextView mTextViewNomedia;
     protected View mViewNomedia;
-    protected Media mItemToUpdate;
+    protected MediaHolder mItemToUpdate;
     protected String mGroup;
     protected final CyclicBarrier mBarrier = new CyclicBarrier(2);
 
@@ -281,7 +281,7 @@ public class VideoGridFragment extends Fragment implements IBrowser, ISortable,
 
     @Override
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-        Media media = mVideoAdapter.getItem(position);
+        MediaHolder media = mVideoAdapter.getItem(position);
         if (media instanceof MediaGroup) {
             MainActivity activity = (MainActivity)getActivity();
             VideoGridFragment frag = (VideoGridFragment)activity.showSecondaryFragment("videoGroupList");
@@ -293,16 +293,16 @@ public class VideoGridFragment extends Fragment implements IBrowser, ISortable,
             playVideo(media, false);
     }
 
-    protected void playVideo(Media media, boolean fromStart) {
+    protected void playVideo(MediaHolder media, boolean fromStart) {
         VideoPlayerActivity.start(getActivity(), media.getLocation(), fromStart);
     }
 
-    protected void playAudio(Media media) {
+    protected void playAudio(MediaHolder media) {
         mAudioController.load(media.getLocation(), true);
     }
 
     private boolean handleContextItemSelected(MenuItem menu, int position) {
-        Media media = mVideoAdapter.getItem(position);
+        MediaHolder media = mVideoAdapter.getItem(position);
         switch (menu.getItemId())
         {
         case R.id.video_list_play_from_start:
@@ -325,7 +325,7 @@ public class VideoGridFragment extends Fragment implements IBrowser, ISortable,
                     new VLCRunnable(media) {
                         @Override
                         public void run(Object o) {
-                            Media media = (Media) o;
+                            MediaHolder media = (MediaHolder) o;
                             mMediaLibrary.getMediaItems().remove(media);
                             mVideoAdapter.remove(media);
                             mAudioController.removeLocation(media.getLocation());
@@ -341,7 +341,7 @@ public class VideoGridFragment extends Fragment implements IBrowser, ISortable,
     public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
         // Do not show the menu of media group.
         AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo;
-        Media media = mVideoAdapter.getItem(info.position);
+        MediaHolder media = mVideoAdapter.getItem(info.position);
         if (media instanceof MediaGroup)
             return;
         MenuInflater inflater = getActivity().getMenuInflater();
@@ -349,7 +349,7 @@ public class VideoGridFragment extends Fragment implements IBrowser, ISortable,
         setContextMenuItems(menu, media);
     }
 
-    private void setContextMenuItems(Menu menu, Media media) {
+    private void setContextMenuItems(Menu menu, MediaHolder media) {
         long lastTime = media.getTime();
         if (lastTime > 0)
             menu.findItem(R.id.video_list_play_from_start).setVisible(true);
@@ -383,7 +383,7 @@ public class VideoGridFragment extends Fragment implements IBrowser, ISortable,
 
         PopupMenu popupMenu = new PopupMenu(getActivity(), anchor);
         popupMenu.getMenuInflater().inflate(R.menu.video_list, popupMenu.getMenu());
-        Media media = mVideoAdapter.getItem(position);
+        MediaHolder media = mVideoAdapter.getItem(position);
         setContextMenuItems(popupMenu.getMenu(), media);
         popupMenu.setOnMenuItemClickListener(new OnMenuItemClickListener() {
             @Override
@@ -418,7 +418,7 @@ public class VideoGridFragment extends Fragment implements IBrowser, ISortable,
     public void updateList() {
         if (!mSwipeRefreshLayout.isRefreshing())
             mSwipeRefreshLayout.setRefreshing(true);
-        final List<Media> itemList = mMediaLibrary.getVideoItems();
+        final List<MediaHolder> itemList = mMediaLibrary.getVideoItems();
 
         if (mThumbnailer != null)
             mThumbnailer.clearJobs();
@@ -434,7 +434,7 @@ public class VideoGridFragment extends Fragment implements IBrowser, ISortable,
                 public void run() {
                     if (mGroup != null || itemList.size() <= 10) {
                         mVideoAdapter.setNotifyOnChange(false);
-                        for (Media item : itemList) {
+                        for (MediaHolder item : itemList) {
                             if (mGroup == null || item.getTitle().startsWith(mGroup)) {
                                 mVideoAdapter.add(item);
                                 if (mThumbnailer != null)
@@ -485,7 +485,7 @@ public class VideoGridFragment extends Fragment implements IBrowser, ISortable,
         mVideoAdapter.sortBy(sortby);
     }
 
-    public void setItemToUpdate(Media item) {
+    public void setItemToUpdate(MediaHolder item) {
         mItemToUpdate = item;
         mHandler.sendEmptyMessage(VideoListHandler.UPDATE_ITEM);
     }
diff --git a/vlc-android/src/org/videolan/vlc/gui/video/VideoListAdapter.java b/vlc-android/src/org/videolan/vlc/gui/video/VideoListAdapter.java
index 7d29359..6471e77 100644
--- a/vlc-android/src/org/videolan/vlc/gui/video/VideoListAdapter.java
+++ b/vlc-android/src/org/videolan/vlc/gui/video/VideoListAdapter.java
@@ -24,7 +24,7 @@ import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Locale;
 
-import org.videolan.libvlc.Media;
+import org.videolan.vlc.MediaHolder;
 import org.videolan.vlc.MediaGroup;
 import org.videolan.vlc.R;
 import org.videolan.vlc.util.BitmapCache;
@@ -45,8 +45,8 @@ import android.widget.ImageView;
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
-public class VideoListAdapter extends ArrayAdapter<Media>
-                                 implements Comparator<Media> {
+public class VideoListAdapter extends ArrayAdapter<MediaHolder>
+                                 implements Comparator<MediaHolder> {
 
     public final static int SORT_BY_TITLE = 0;
     public final static int SORT_BY_LENGTH = 1;
@@ -64,7 +64,7 @@ public class VideoListAdapter extends ArrayAdapter<Media>
 
     public final static String TAG = "VLC/MediaLibraryAdapter";
 
-    public synchronized void update(Media item) {
+    public synchronized void update(MediaHolder item) {
         int position = getPosition(item);
         if (position != -1) {
             remove(item);
@@ -76,7 +76,7 @@ public class VideoListAdapter extends ArrayAdapter<Media>
         boolean notify = false;
         // update times
         for (int i = 0; i < getCount(); ++i) {
-            Media media = getItem(i);
+            MediaHolder media = getItem(i);
             Long time = times.get(media.getLocation());
             if (time != null) {
                 media.setTime(time);
@@ -118,7 +118,7 @@ public class VideoListAdapter extends ArrayAdapter<Media>
     }
 
     @Override
-    public int compare(Media item1, Media item2) {
+    public int compare(MediaHolder item1, MediaHolder item2) {
         int compare = 0;
         switch (mSortBy) {
             case SORT_BY_TITLE:
@@ -174,7 +174,7 @@ public class VideoListAdapter extends ArrayAdapter<Media>
             }
         });
 
-        Media media = getItem(position);
+        MediaHolder media = getItem(position);
 
         /* Thumbnail */
         Bitmap thumbnail = BitmapUtil.getPictureFromCache(media);
@@ -202,7 +202,7 @@ public class VideoListAdapter extends ArrayAdapter<Media>
         return v;
     }
 
-    private void fillGroupView(ViewHolder holder, Media media) {
+    private void fillGroupView(ViewHolder holder, MediaHolder media) {
         MediaGroup mediaGroup = (MediaGroup) media;
         int size = mediaGroup.size();
         String text = getContext().getResources().getQuantityString(R.plurals.videos_quantity, size, size);
@@ -213,7 +213,7 @@ public class VideoListAdapter extends ArrayAdapter<Media>
         holder.progress.setVisibility(View.INVISIBLE);
     }
 
-    private void fillVideoView(ViewHolder holder, Media media) {
+    private void fillVideoView(ViewHolder holder, MediaHolder media) {
         /* Time / Duration */
         if (media.getLength() > 0) {
             long lastTime = media.getTime();
diff --git a/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java b/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
index d1e497d..321748f 100644
--- a/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
@@ -43,9 +43,9 @@ import org.videolan.libvlc.IVideoPlayer;
 import org.videolan.libvlc.LibVLC;
 import org.videolan.libvlc.LibVlcException;
 import org.videolan.libvlc.LibVlcUtil;
-import org.videolan.libvlc.Media;
-import org.videolan.libvlc.MediaListPlayer;
+import org.videolan.vlc.MediaHolder;
 import org.videolan.vlc.MediaDatabase;
+import org.videolan.vlc.MediaHolderListPlayer;
 import org.videolan.vlc.R;
 import org.videolan.vlc.VLCApplication;
 import org.videolan.vlc.audio.AudioServiceController;
@@ -150,7 +150,7 @@ public class VideoPlayerActivity extends ActionBarActivity implements IVideoPlay
     private MediaRouter.SimpleCallback mMediaRouterCallback;
     private SecondaryDisplay mPresentation;
     private LibVLC mLibVLC;
-    private MediaListPlayer mMediaListPlayer;
+    private MediaHolderListPlayer mMediaListPlayer;
     private String mLocation;
     private GestureDetectorCompat mDetector;
 
@@ -376,7 +376,7 @@ public class VideoPlayerActivity extends ActionBarActivity implements IVideoPlay
             Log.d(TAG, "LibVLC initialisation failed");
             return;
         }
-        mMediaListPlayer = new MediaListPlayer(mLibVLC);
+        mMediaListPlayer = new MediaHolderListPlayer(mLibVLC);
 
         mSurfaceView = (SurfaceView) findViewById(R.id.player_surface);
         mSurfaceHolder = mSurfaceView.getHolder();
@@ -2159,7 +2159,7 @@ public class VideoPlayerActivity extends ActionBarActivity implements IVideoPlay
         int time = (int) mLibVLC.getTime();
         int length = (int) mLibVLC.getLength();
         if (length == 0) {
-            Media media = MediaDatabase.getInstance().getMedia(mLocation);
+            MediaHolder media = MediaDatabase.getInstance().getMedia(mLocation);
             if (media != null)
                 length = (int) media.getLength();
         }
@@ -2367,7 +2367,7 @@ public class VideoPlayerActivity extends ActionBarActivity implements IVideoPlay
             mMediaListPlayer.playIndex(savedIndexPosition);
         } else if (mLocation != null && mLocation.length() > 0 && !dontParse) {
             AudioServiceController.getInstance().stop(); // Stop the previous playback.
-            mMediaListPlayer.getMediaList().add(new Media(mLibVLC, mLocation));
+            mMediaListPlayer.getMediaList().add(new MediaHolder(mLibVLC, mLocation));
             savedIndexPosition = mMediaListPlayer.getMediaList().size() - 1;
             mMediaListPlayer.playIndex(savedIndexPosition);
         }
@@ -2375,7 +2375,7 @@ public class VideoPlayerActivity extends ActionBarActivity implements IVideoPlay
 
         if (mLocation != null && mLocation.length() > 0 && !dontParse) {
             // restore last position
-            Media media = MediaDatabase.getInstance().getMedia(mLocation);
+            MediaHolder media = MediaDatabase.getInstance().getMedia(mLocation);
             if(media != null) {
                 // in media library
                 if(media.getTime() > 0 && !fromStart)
diff --git a/vlc-android/src/org/videolan/vlc/interfaces/IAudioService.aidl b/vlc-android/src/org/videolan/vlc/interfaces/IAudioService.aidl
index cf78bff..516a587 100644
--- a/vlc-android/src/org/videolan/vlc/interfaces/IAudioService.aidl
+++ b/vlc-android/src/org/videolan/vlc/interfaces/IAudioService.aidl
@@ -20,7 +20,7 @@
 
 package org.videolan.vlc.interfaces;
 import org.videolan.vlc.interfaces.IAudioServiceCallback;
-import org.videolan.libvlc.Media;
+import org.videolan.vlc.MediaHolder;
 
 interface IAudioService {
     void play();
@@ -35,7 +35,7 @@ interface IAudioService {
     void moveItem(int positionStart, int positionEnd);
     void remove(int position);
     void removeLocation(String location);
-    List<Media> getMedias();
+    List<MediaHolder> getMedias();
     List<String> getMediaLocations();
     String getCurrentMediaLocation();
     boolean isPlaying();
diff --git a/vlc-android/src/org/videolan/vlc/interfaces/IAudioServiceCallback.aidl b/vlc-android/src/org/videolan/vlc/interfaces/IAudioServiceCallback.aidl
index 7497c1d..d728960 100644
--- a/vlc-android/src/org/videolan/vlc/interfaces/IAudioServiceCallback.aidl
+++ b/vlc-android/src/org/videolan/vlc/interfaces/IAudioServiceCallback.aidl
@@ -19,11 +19,11 @@
  *****************************************************************************/
 
 package org.videolan.vlc.interfaces;
-import org.videolan.libvlc.Media;
+import org.videolan.vlc.MediaHolder;
 
 interface IAudioServiceCallback {
     void update();
     void updateProgress();
-    void onMediaPlayedAdded(in Media media, int index);
+    void onMediaPlayedAdded(in MediaHolder media, int index);
     void onMediaPlayedRemoved(int index);
 }
diff --git a/vlc-android/src/org/videolan/vlc/util/BitmapUtil.java b/vlc-android/src/org/videolan/vlc/util/BitmapUtil.java
index 3a43dae..8c53259 100644
--- a/vlc-android/src/org/videolan/vlc/util/BitmapUtil.java
+++ b/vlc-android/src/org/videolan/vlc/util/BitmapUtil.java
@@ -20,7 +20,7 @@
 
 package org.videolan.vlc.util;
 
-import org.videolan.libvlc.Media;
+import org.videolan.vlc.MediaHolder;
 import org.videolan.vlc.MediaDatabase;
 import org.videolan.vlc.VLCApplication;
 
@@ -79,7 +79,7 @@ public class BitmapUtil {
         return bitmap;
     }
 
-    public static Bitmap getPictureFromCache(Media media)
+    public static Bitmap getPictureFromCache(MediaHolder media)
     {
         // mPicture is not null only if passed through
         // the ctor which is deprecated by now.
diff --git a/vlc-android/src/org/videolan/vlc/util/Util.java b/vlc-android/src/org/videolan/vlc/util/Util.java
index 7c77b2a..4cce2d6 100644
--- a/vlc-android/src/org/videolan/vlc/util/Util.java
+++ b/vlc-android/src/org/videolan/vlc/util/Util.java
@@ -29,7 +29,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import org.videolan.libvlc.LibVLC;
 import org.videolan.libvlc.LibVlcUtil;
-import org.videolan.libvlc.Media;
+import org.videolan.vlc.MediaHolder;
 import org.videolan.vlc.MediaLibrary;
 import org.videolan.vlc.R;
 import org.videolan.vlc.VLCApplication;
@@ -103,10 +103,10 @@ public class Util {
      * @param mrl MRL of the media
      * @return A media object from the media library or newly created
      */
-    public static Media getOrCreateMedia(LibVLC libVLC, String mrl) {
-        Media mlItem = MediaLibrary.getInstance().getMediaItem(mrl);
+    public static MediaHolder getOrCreateMedia(LibVLC libVLC, String mrl) {
+        MediaHolder mlItem = MediaLibrary.getInstance().getMediaItem(mrl);
         if(mlItem == null)
-            mlItem = new Media(libVLC, mrl);
+            mlItem = new MediaHolder(libVLC, mrl);
         return mlItem;
     }
 
@@ -210,34 +210,34 @@ public class Util {
         }
     }
 
-    public static String getMediaArtist(Context ctx, Media media) {
+    public static String getMediaArtist(Context ctx, MediaHolder media) {
         final String artist = media.getArtist();
         return artist != null ? artist : getMediaString(ctx, R.string.unknown_artist);
     }
 
-    public static String getMediaReferenceArtist(Context ctx, Media media) {
+    public static String getMediaReferenceArtist(Context ctx, MediaHolder media) {
         final String artist = media.getReferenceArtist();
         return artist != null ? artist : getMediaString(ctx, R.string.unknown_artist);
     }
 
-    public static String getMediaAlbumArtist(Context ctx, Media media) {
+    public static String getMediaAlbumArtist(Context ctx, MediaHolder media) {
         final String albumArtist = media.getAlbumArtist();
         return albumArtist != null ? albumArtist : getMediaString(ctx, R.string.unknown_artist);
     }
 
-    public static String getMediaAlbum(Context ctx, Media media) {
+    public static String getMediaAlbum(Context ctx, MediaHolder media) {
         final String album = media.getAlbum();
         return album != null ? album : getMediaString(ctx, R.string.unknown_album);
 
     }
 
-    public static String getMediaGenre(Context ctx, Media media) {
+    public static String getMediaGenre(Context ctx, MediaHolder media) {
         final String genre = media.getGenre();
         return genre != null ? genre : getMediaString(ctx, R.string.unknown_genre);
     }
 
-    public static String getMediaSubtitle(Context ctx, Media media) {
-        if (media.getType() == Media.TYPE_VIDEO)
+    public static String getMediaSubtitle(Context ctx, MediaHolder media) {
+        if (media.getType() == MediaHolder.TYPE_VIDEO)
             return "";
         else
             return media.getNowPlaying() != null
-- 
2.1.3



More information about the Android mailing list