Commit 4246cfd4 authored by Thomas Guillem's avatar Thomas Guillem
Browse files

libvlc: remove MediaList singletons

Add MediaListPlayer: a wrapper that handle MediaList and play items of the
list.
parent d18f590b
......@@ -88,8 +88,6 @@ public class EventHandler {
//public static final int VlmMediaInstanceStatusEnd = 0x609;
//public static final int VlmMediaInstanceStatusError = 0x60a;
public static final int CustomMediaListExpanding = 0x2000;
public static final int CustomMediaListExpandingEnd = 0x2001;
public static final int CustomMediaListItemAdded = 0x2002;
public static final int CustomMediaListItemDeleted = 0x2003;
public static final int CustomMediaListItemMoved = 0x2004;
......
......@@ -63,12 +63,9 @@ public class LibVLC {
/** libVLC instance C pointer */
private long mLibVlcInstance = 0; // Read-only, reserved for JNI
/** libvlc_media_player pointer and index */
private int mInternalMediaPlayerIndex = 0; // Read-only, reserved for JNI
/** libvlc_media_player pointer */
private long mInternalMediaPlayerInstance = 0; // Read-only, reserved for JNI
private MediaList mMediaList; // Pointer to media list being followed
/** Buffer for VLC messages */
private StringBuffer mDebugLogBuffer;
private boolean mIsBufferingLog = false;
......@@ -211,15 +208,6 @@ public class LibVLC {
}
}
/**
* Get the media list that LibVLC is following right now.
*
* @return The media list object being followed
*/
public MediaList getMediaList() {
return mMediaList;
}
/**
* Give to LibVLC the surface to draw the video.
* @param f the surface to draw
......@@ -515,7 +503,6 @@ public class LibVLC {
File cacheDir = context.getCacheDir();
mCachePath = (cacheDir != null) ? cacheDir.getAbsolutePath() : null;
nativeInit();
mMediaList = new MediaList(this);
setEventHandler(EventHandler.getInstance());
mIsInitialized = true;
}
......@@ -567,22 +554,6 @@ public class LibVLC {
mAout.release();
}
/**
* 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 = getMediaOptions(media);
mInternalMediaPlayerIndex = position;
playMRL(mrl, options);
}
/**
* Play an MRL directly.
*
......@@ -591,7 +562,6 @@ public class LibVLC {
public void playMRL(String mrl) {
// index=-1 will return options from libvlc instance without relying on MediaList
String[] options = getMediaOptions(false, false);
mInternalMediaPlayerIndex = 0;
playMRL(mrl, options);
}
......@@ -639,7 +609,7 @@ public class LibVLC {
/**
* Play an mrl
*/
private native void playMRL(String mrl, String[] mediaOptions);
public native void playMRL(String mrl, String[] mediaOptions);
/**
* Returns true if any media is playing
......@@ -790,26 +760,6 @@ public class LibVLC {
public native static boolean nativeIsPathDirectory(String path);
/**
* 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 = mMediaList.expandMedia(mInternalMediaPlayerIndex);
if(r == 0)
this.playIndex(mInternalMediaPlayerIndex);
return r;
}
/**
* Expand the current media.
* @return the index of the media was expanded, and -1 if no media was expanded
*/
public int expand() {
return mMediaList.expandMedia(mInternalMediaPlayerIndex);
}
private native void setEventHandler(EventHandler eventHandler);
private native void detachEventHandler();
......
......@@ -61,28 +61,6 @@ public class MediaList {
return position >= 0 && position < mInternalList.size();
}
/**
* This function checks the currently playing media for subitems at the given
* position, and if any exist, it will expand them at the same position
* and replace the current media.
*
* @param position The position to expand
* @return -1 if no subitems were found, 0 if subitems were expanded
*/
public int expandMedia(int position) {
ArrayList<String> children = new ArrayList<String>();
int ret = mLibVLC.expandMedia(children);
if(ret == 0) {
mEventHandler.callback(EventHandler.CustomMediaListExpanding, new Bundle());
this.remove(position);
for(String mrl : children) {
this.insert(position, mrl);
}
mEventHandler.callback(EventHandler.CustomMediaListExpandingEnd, new Bundle());
}
return ret;
}
public void insert(int position, String mrl) {
insert(position, new Media(mLibVLC, mrl));
}
......
/*****************************************************************************
* 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);
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();
}
}
......@@ -38,6 +38,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.Stack;
import java.util.concurrent.atomic.AtomicBoolean;
import org.videolan.libvlc.EventHandler;
import org.videolan.libvlc.LibVLC;
......@@ -45,6 +46,7 @@ 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.MediaDatabase;
import org.videolan.vlc.R;
import org.videolan.vlc.RemoteControlClientReceiver;
......@@ -121,12 +123,14 @@ public class AudioService extends Service {
public static final int NEXT_ITEM = 3;
private LibVLC mLibVLC;
private MediaListPlayer mMediaListPlayer;
private HashMap<IAudioServiceCallback, Integer> mCallback;
private EventHandler mEventHandler;
private OnAudioFocusChangeListener audioFocusListener;
private boolean mDetectHeadset = true;
private boolean mPebbleEnabled;
private PowerManager.WakeLock mWakeLock;
private final AtomicBoolean mExpanding = new AtomicBoolean(false);
private static boolean mWasPlayingAudio = false;
......@@ -166,6 +170,7 @@ public class AudioService extends Service {
} catch (LibVlcException e) {
e.printStackTrace();
}
mMediaListPlayer = new MediaListPlayer(mLibVLC);
mCallback = new HashMap<IAudioServiceCallback, Integer>();
mCurrentIndex = -1;
......@@ -471,7 +476,7 @@ public class AudioService extends Service {
service.executeUpdate();
service.executeUpdateProgress();
String location = service.mLibVLC.getMediaList().getMRL(service.mCurrentIndex);
String location = service.mMediaListPlayer.getMediaList().getMRL(service.mCurrentIndex);
long length = service.mLibVLC.getLength();
MediaDatabase dbManager = MediaDatabase.getInstance();
Media m = dbManager.getMedia(location);
......@@ -532,7 +537,7 @@ public class AudioService extends Service {
case EventHandler.MediaPlayerEncounteredError:
service.showToast(service.getString(
R.string.invalid_location,
service.mLibVLC.getMediaList().getMRL(
service.mMediaListPlayer.getMediaList().getMRL(
service.mCurrentIndex)), Toast.LENGTH_SHORT);
service.executeUpdate();
service.executeUpdateProgress();
......@@ -560,8 +565,6 @@ public class AudioService extends Service {
private final Handler mListEventHandler = new MediaListEventHandler(this);
private static class MediaListEventHandler extends WeakHandler<AudioService> {
// Don't clobber mCurrentIndex when MediaList is expanding itself.
boolean expanding = false;
public MediaListEventHandler(AudioService audioService) {
super(audioService);
......@@ -577,7 +580,7 @@ public class AudioService extends Service {
case EventHandler.CustomMediaListItemAdded:
Log.i(TAG, "CustomMediaListItemAdded");
index = msg.getData().getInt("item_index");
if(service.mCurrentIndex >= index && !expanding)
if(service.mCurrentIndex >= index && !service.mExpanding.get())
service.mCurrentIndex++;
service.determinePrevAndNextIndices();
......@@ -586,20 +589,21 @@ public class AudioService extends Service {
case EventHandler.CustomMediaListItemDeleted:
Log.i(TAG, "CustomMediaListItemDeleted");
index = msg.getData().getInt("item_index");
if (service.mCurrentIndex == index && !expanding) {
if (service.mCurrentIndex == index && !service.mExpanding.get()) {
// The current item has been deleted
service.mCurrentIndex--;
service.determinePrevAndNextIndices();
if (service.mNextIndex != -1)
service.next();
else if (service.mCurrentIndex != -1)
service.mLibVLC.playIndex(service.mCurrentIndex);
else
else if (service.mCurrentIndex != -1) {
service.mMediaListPlayer.playIndex(service.mCurrentIndex);
service.executeOnMediaPlayedAdded();
} else
service.stop();
break;
}
if(service.mCurrentIndex > index && !expanding)
if(service.mCurrentIndex > index && !service.mExpanding.get())
service.mCurrentIndex--;
service.determinePrevAndNextIndices();
service.executeUpdate();
......@@ -626,12 +630,6 @@ public class AudioService extends Service {
service.determinePrevAndNextIndices();
service.executeUpdate();
break;
case EventHandler.CustomMediaListExpanding:
expanding = true;
break;
case EventHandler.CustomMediaListExpandingEnd:
expanding = false;
break;
}
}
};
......@@ -641,7 +639,7 @@ public class AudioService extends Service {
return;
Log.i(TAG, "Obtained video track");
String title = getCurrentMedia().getTitle();
String MRL = mLibVLC.getMediaList().getMRL(mCurrentIndex);
String MRL = mMediaListPlayer.getMediaList().getMRL(mCurrentIndex);
int index = mCurrentIndex;
mCurrentIndex = -1;
mEventHandler.removeHandler(mVlcEventHandler);
......@@ -682,7 +680,7 @@ public class AudioService extends Service {
final Media media = mMediaListPlayer.getMediaList().getMedia(mCurrentIndex);
for (IAudioServiceCallback callback : mCallback.keySet()) {
try {
callback.onMediaPlayedAdded(new MediaParcelable(media), 0);
callback.onMediaPlayedAdded(media, 0);
} catch (RemoteException e) {
e.printStackTrace();
}
......@@ -695,7 +693,7 @@ public class AudioService extends Service {
* @return The current media or null if there is not any.
*/
private Media getCurrentMedia() {
return mLibVLC.getMediaList().getMedia(mCurrentIndex);
return mMediaListPlayer.getMediaList().getMedia(mCurrentIndex);
}
/**
......@@ -704,7 +702,7 @@ public class AudioService extends Service {
* @return True if a media is currently loaded, false otherwise
*/
private boolean hasCurrentMedia() {
return mCurrentIndex >= 0 && mCurrentIndex < mLibVLC.getMediaList().size();
return mCurrentIndex >= 0 && mCurrentIndex < mMediaListPlayer.getMediaList().size();
}
private final Handler mHandler = new AudioServiceHandler(this);
......@@ -860,7 +858,7 @@ public class AudioService extends Service {
private void stop() {
mLibVLC.stop();
mEventHandler.removeHandler(mVlcEventHandler);
mLibVLC.getMediaList().getEventHandler().removeHandler(mListEventHandler);
mMediaListPlayer.getMediaList().getEventHandler().removeHandler(mListEventHandler);
setRemoteControlClientPlaybackState(EventHandler.MediaPlayerStopped);
mCurrentIndex = -1;
mPrevious.clear();
......@@ -876,12 +874,18 @@ public class AudioService extends Service {
}
private void determinePrevAndNextIndices(boolean expand) {
mNextIndex = expand ? mLibVLC.expand() : -1;
if (expand) {
mExpanding.set(true);
mNextIndex = mMediaListPlayer.expand();
mExpanding.set(false);
} else {
mNextIndex = -1;
}
mPrevIndex = -1;
if (mNextIndex == -1) {
// No subitems; play the next item.
int size = mLibVLC.getMediaList().size();
int size = mMediaListPlayer.getMediaList().size();
// Repeating once doesn't change the index
if (mRepeating == RepeatType.Once) {
......@@ -931,14 +935,15 @@ public class AudioService extends Service {
mPrevious.push(mCurrentIndex);
mCurrentIndex = mNextIndex;
int size = mLibVLC.getMediaList().size();
int size = mMediaListPlayer.getMediaList().size();
if (size == 0 || mCurrentIndex < 0 || mCurrentIndex >= size) {
Log.w(TAG, "Warning: invalid next index, aborted !");
stop();
return;
}
mLibVLC.playIndex(mCurrentIndex);
mMediaListPlayer.playIndex(mCurrentIndex);
executeOnMediaPlayedAdded();
mHandler.sendEmptyMessage(SHOW_PROGRESS);
setUpRemoteControlClient();
......@@ -991,14 +996,15 @@ public class AudioService extends Service {
if (mPrevious.size() > 0)
mPrevious.pop();
int size = mLibVLC.getMediaList().size();
int size = mMediaListPlayer.getMediaList().size();
if (size == 0 || mPrevIndex < 0 || mCurrentIndex >= size) {
Log.w(TAG, "Warning: invalid previous index, aborted !");
stop();
return;
}
mLibVLC.playIndex(mCurrentIndex);
mMediaListPlayer.playIndex(mCurrentIndex);
executeOnMediaPlayedAdded();
mHandler.sendEmptyMessage(SHOW_PROGRESS);
setUpRemoteControlClient();
showNotification();
......@@ -1087,7 +1093,7 @@ public class AudioService extends Service {
@Override
public String getArtistPrev() throws RemoteException {
if (mPrevIndex != -1)
return Util.getMediaArtist(AudioService.this, mLibVLC.getMediaList().getMedia(mPrevIndex));
return Util.getMediaArtist(AudioService.this, mMediaListPlayer.getMediaList().getMedia(mPrevIndex));
else
return null;
}
......@@ -1095,7 +1101,7 @@ public class AudioService extends Service {
@Override
public String getArtistNext() throws RemoteException {
if (mNextIndex != -1)
return Util.getMediaArtist(AudioService.this, mLibVLC.getMediaList().getMedia(mNextIndex));
return Util.getMediaArtist(AudioService.this, mMediaListPlayer.getMediaList().getMedia(mNextIndex));
else
return null;
}
......@@ -1111,7 +1117,7 @@ public class AudioService extends Service {
@Override
public String getTitlePrev() throws RemoteException {
if (mPrevIndex != -1)
return mLibVLC.getMediaList().getMedia(mPrevIndex).getTitle();
return mMediaListPlayer.getMediaList().getMedia(mPrevIndex).getTitle();
else
return null;
}
......@@ -1119,7 +1125,7 @@ public class AudioService extends Service {
@Override
public String getTitleNext() throws RemoteException {
if (mNextIndex != -1)
return mLibVLC.getMediaList().getMedia(mNextIndex).getTitle();
return mMediaListPlayer.getMediaList().getMedia(mNextIndex).getTitle();
else
return null;
}
......@@ -1135,7 +1141,7 @@ public class AudioService extends Service {
@Override
public Bitmap getCoverPrev() throws RemoteException {
if (mPrevIndex != -1)
return AudioUtil.getCover(AudioService.this, mLibVLC.getMediaList().getMedia(mPrevIndex), 64);
return AudioUtil.getCover(AudioService.this, mMediaListPlayer.getMediaList().getMedia(mPrevIndex), 64);
else
return null;
}
......@@ -1143,7 +1149,7 @@ public class AudioService extends Service {
@Override
public Bitmap getCoverNext() throws RemoteException {
if (mNextIndex != -1)
return AudioUtil.getCover(AudioService.this, mLibVLC.getMediaList().getMedia(mNextIndex), 64);
return AudioUtil.getCover(AudioService.this, mMediaListPlayer.getMediaList().getMedia(mNextIndex), 64);
else
return null;
}
......@@ -1197,9 +1203,9 @@ public class AudioService extends Service {
Log.v(TAG, "Loading position " + ((Integer)position).toString() + " in " + mediaPathList.toString());
mEventHandler.addHandler(mVlcEventHandler);
mLibVLC.getMediaList().getEventHandler().removeHandler(mListEventHandler);
mLibVLC.getMediaList().clear();
MediaList mediaList = mLibVLC.getMediaList();
mMediaListPlayer.getMediaList().getEventHandler().removeHandler(mListEventHandler);
mMediaListPlayer.getMediaList().clear();
MediaList mediaList = mMediaListPlayer.getMediaList();
mPrevious.clear();
......@@ -1221,11 +1227,11 @@ public class AudioService extends Service {
mediaList.add(media);
}
if (mLibVLC.getMediaList().size() == 0) {
if (mMediaListPlayer.getMediaList().size() == 0) {
Log.w(TAG, "Warning: empty media list, nothing to play !");
return;
}
if (mLibVLC.getMediaList().size() > position && position >= 0) {
if (mMediaListPlayer.getMediaList().size() > position && position >= 0) {
mCurrentIndex = position;
} else {
Log.w(TAG, "Warning: positon " + position + " out of bounds");
......@@ -1233,9 +1239,10 @@ public class AudioService extends Service {
}
// Add handler after loading the list
mLibVLC.getMediaList().getEventHandler().addHandler(mListEventHandler);
mMediaListPlayer.getMediaList().getEventHandler().addHandler(mListEventHandler);
mLibVLC.playIndex(mCurrentIndex);
mMediaListPlayer.playIndex(mCurrentIndex);
executeOnMediaPlayedAdded();
mHandler.sendEmptyMessage(SHOW_PROGRESS);
setUpRemoteControlClient();
showNotification();
......@@ -1253,11 +1260,11 @@ public class AudioService extends Service {
*/
@Override
public void playIndex(int index) {
if (mLibVLC.getMediaList().size() == 0) {
if (mMediaListPlayer.getMediaList().size() == 0) {
Log.w(TAG, "Warning: empty media list, nothing to play !");
return;
}
if (index >= 0 && index < mLibVLC.getMediaList().size()) {
if (index >= 0 && index < mMediaListPlayer.getMediaList().size()) {
mCurrentIndex = index;
} else {
Log.w(TAG, "Warning: index " + index + " out of bounds");
......@@ -1265,7 +1272,8 @@ public class AudioService extends Service {
}
mEventHandler.addHandler(mVlcEventHandler);
mLibVLC.playIndex(mCurrentIndex);
mMediaListPlayer.playIndex(mCurrentIndex);
executeOnMediaPlayedAdded();
mHandler.sendEmptyMessage(SHOW_PROGRESS);
setUpRemoteControlClient();
showNotification();
......@@ -1282,7 +1290,7 @@ public class AudioService extends Service {
*/
@Override
public void showWithoutParse(int index) throws RemoteException {
String URI = mLibVLC.getMediaList().getMRL(index);
String URI = mMediaListPlayer.getMediaList().getMRL(index);
Log.v(TAG, "Showing index " + index + " with playing URI " + URI);
// Show an URI without interrupting/losing the current stream
......@@ -1322,7 +1330,7 @@ public class AudioService extends Service {
Log.v(TAG, "Creating on-the-fly Media object for " + location);
media = new Media(mLibVLC, location);
}
mLibVLC.getMediaList().add(media);
mMediaListPlayer.getMediaList().add(media);
}
AudioService.this.saveMediaList();
determinePrevAndNextIndices();
......@@ -1334,34 +1342,43 @@ public class AudioService extends Service {
*/
@Override
public void moveItem(int positionStart, int positionEnd) throws RemoteException {
mLibVLC.getMediaList().move(positionStart, positionEnd);
mMediaListPlayer.getMediaList().move(positionStart, positionEnd);
AudioService.this.saveMediaList();
}
@Override
public void remove(int position) {
mLibVLC.getMediaList().remove(position);
mMediaListPlayer.getMediaList().remove(position);
AudioService.this.saveMediaList();
}
@Override
public void removeLocation(String location) {
mLibVLC.getMediaList().remove(location);
mMediaListPlayer.getMediaList().remove(location);
AudioService.this.saveMediaList();
}
@Override
public List<Media> getMedias() {
final ArrayList<Media> ml = new ArrayList<Media>();
for (int i = 0; i < mMediaListPlayer.getMediaList().size(); i++) {
ml.add(mMediaListPlayer.getMediaList().getMedia(i));
}
return ml;
}