[Android] [PATCH 01/10] Video playlists
Geoffrey Métais
geoffrey.metais at gmail.com
Fri Nov 27 13:24:56 CET 2015
---
.../src/org/videolan/vlc/PlaybackService.java | 26 ++-
.../org/videolan/vlc/gui/audio/AudioPlayer.java | 11 --
.../vlc/gui/video/VideoPlayerActivity.java | 186 +++++++++++++--------
3 files changed, 138 insertions(+), 85 deletions(-)
diff --git a/vlc-android/src/org/videolan/vlc/PlaybackService.java b/vlc-android/src/org/videolan/vlc/PlaybackService.java
index e9d4cf0..bfd0a18 100644
--- a/vlc-android/src/org/videolan/vlc/PlaybackService.java
+++ b/vlc-android/src/org/videolan/vlc/PlaybackService.java
@@ -48,6 +48,7 @@ import android.preference.PreferenceManager;
import android.support.annotation.MainThread;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationManagerCompat;
+import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
@@ -547,6 +548,7 @@ public class PlaybackService extends Service implements IVLCVout.Callback {
};
private final MediaPlayer.EventListener mMediaPlayerListener = new MediaPlayer.EventListener() {
+
@Override
public void onEvent(MediaPlayer.Event event) {
switch (event.type) {
@@ -576,9 +578,12 @@ public class PlaybackService extends Service implements IVLCVout.Callback {
}
changeAudioFocus(true);
- showNotification();
if (!mWakeLock.isHeld())
mWakeLock.acquire();
+ if (switchToVideo())
+ hideNotification();
+ else
+ showNotification();
break;
case MediaPlayer.Event.Paused:
Log.i(TAG, "MediaPlayer.Event.Paused");
@@ -711,7 +716,7 @@ public class PlaybackService extends Service implements IVLCVout.Callback {
private boolean handleVout() {
if (!canSwitchToVideo() || !mMediaPlayer.isPlaying())
return false;
- if (mMediaPlayer.getVLCVout().areViewsAttached()) {
+ if (isVideoPlaying()) {
hideNotification(false);
return true;
} else
@@ -722,8 +727,14 @@ public class PlaybackService extends Service implements IVLCVout.Callback {
public boolean switchToVideo() {
if (!canSwitchToVideo())
return false;
- if (!mMediaPlayer.getVLCVout().areViewsAttached())
- VideoPlayerActivity.startOpened(VLCApplication.getAppContext(), mCurrentIndex);
+ if (isVideoPlaying()) {//Player is already running, just send it an intent
+ LocalBroadcastManager.getInstance(this).sendBroadcast(
+ VideoPlayerActivity.getIntent(VideoPlayerActivity.PLAY_FROM_SERVICE,
+ getCurrentMediaWrapper(), false, mCurrentIndex));
+ } else {//Start the video player
+ VideoPlayerActivity.startOpened(VLCApplication.getAppContext(),
+ getCurrentMediaWrapper().getUri(), mCurrentIndex);
+ }
return true;
}
@@ -1137,12 +1148,13 @@ public class PlaybackService extends Service implements IVLCVout.Callback {
if (mCurrentIndex < 0)
saveCurrentMedia();
Log.w(TAG, "Warning: invalid next index, aborted !");
+ //Close video player if started
+ LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(VideoPlayerActivity.EXIT_PLAYER));
stop();
return;
}
-
playIndex(mCurrentIndex, 0);
- onMediaChanged();
+ saveCurrentMedia();
}
@MainThread
@@ -1161,7 +1173,7 @@ public class PlaybackService extends Service implements IVLCVout.Callback {
setPosition(0f);
playIndex(mCurrentIndex, 0);
- onMediaChanged();
+ saveCurrentMedia();
}
@MainThread
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 3ebdad1..6d7829a 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.java
@@ -95,7 +95,6 @@ public class AudioPlayer extends PlaybackServiceFragment implements PlaybackServ
private boolean mShowRemainingTime = false;
private boolean mPreviewingSeek = false;
- private boolean mSwitchedToVideo = false;
private PlaylistAdapter mPlaylistAdapter;
@@ -176,7 +175,6 @@ public class AudioPlayer extends PlaybackServiceFragment implements PlaybackServ
public void onClick(View v) {
if (mService != null) {
mService.switchToVideo();
- mSwitchedToVideo = true;
}
}
});
@@ -301,7 +299,6 @@ public class AudioPlayer extends PlaybackServiceFragment implements PlaybackServ
if (mSettings.getBoolean(PreferencesActivity.VIDEO_RESTORE, false)){
Util.commitPreferences(mSettings.edit().putBoolean(PreferencesActivity.VIDEO_RESTORE, false));
mService.switchToVideo();
- mSwitchedToVideo = true;
return;
} else
show();
@@ -383,14 +380,6 @@ public class AudioPlayer extends PlaybackServiceFragment implements PlaybackServ
public void onMediaPlayerEvent(MediaPlayer.Event event) {
switch (event.type) {
case MediaPlayer.Event.Opening:
- mSwitchedToVideo = false;
- break;
- case MediaPlayer.Event.ESAdded:
- final boolean forceAudio = (mService.getCurrentMediaWrapper().getFlags() & MediaWrapper.MEDIA_FORCE_AUDIO) != 0;
- if (!forceAudio && !mSwitchedToVideo && event.getEsChangedType() == Media.Track.Type.Video) {
- mService.switchToVideo();
- mSwitchedToVideo = true;
- }
break;
case MediaPlayer.Event.Stopped:
hide();
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 12f3db4..cb87b0d 100644
--- a/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
@@ -50,7 +50,9 @@ import android.provider.MediaStore;
import android.provider.OpenableColumns;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
+import android.support.annotation.NonNull;
import android.support.v4.app.FragmentManager;
+import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBar;
@@ -140,6 +142,8 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
// Internal intent identifier to distinguish between internal launch and
// external intent.
public final static String PLAY_FROM_VIDEOGRID = Strings.buildPkgString("gui.video.PLAY_FROM_VIDEOGRID");
+ public final static String PLAY_FROM_SERVICE = Strings.buildPkgString("gui.video.PLAY_FROM_SERVICE");
+ public final static String EXIT_PLAYER = Strings.buildPkgString("gui.video.EXIT_PLAYER");
public final static String PLAY_EXTRA_ITEM_LOCATION = "item_location";
public final static String PLAY_EXTRA_SUBTITLES_LOCATION = "subtitles_location";
@@ -242,6 +246,7 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
private boolean mHardwareAccelerationError;
private boolean mEndReached;
private boolean mHasSubItems = false;
+ private boolean mForceStop = false;
// Playlist
private int savedIndexPosition = -1;
@@ -517,11 +522,12 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
protected void onNewIntent(Intent intent) {
setIntent(intent);
if (mPlaybackStarted) {
- Uri uri = intent.hasExtra(PLAY_EXTRA_ITEM_LOCATION) ? (Uri) intent.getExtras().getParcelable(PLAY_EXTRA_ITEM_LOCATION) : intent.getData();
+ Uri uri = intent.hasExtra(PLAY_EXTRA_ITEM_LOCATION) ?
+ (Uri) intent.getExtras().getParcelable(PLAY_EXTRA_ITEM_LOCATION) : intent.getData();
if (uri == null || uri.equals(mUri))
return;
- stopPlayback();
- startPlayback();
+ initUI();
+ mTitle.setText(mService.getCurrentMediaWrapper().getTitle());
}
}
@@ -583,12 +589,17 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
if (brightness != -1f)
setWindowBrightness(brightness);
}
+ IntentFilter filter = new IntentFilter(PLAY_FROM_SERVICE);
+ filter.addAction(EXIT_PLAYER);
+ LocalBroadcastManager.getInstance(this).registerReceiver(
+ mServiceReceiver, filter);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
@Override
protected void onStop() {
super.onStop();
+ LocalBroadcastManager.getInstance(this).unregisterReceiver(mServiceReceiver);
if (mAlertDialog != null && mAlertDialog.isShowing())
mAlertDialog.dismiss();
@@ -666,6 +677,43 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
mPlaybackStarted = true;
+ final IVLCVout vlcVout = mService.getVLCVout();
+// vlcVout.detachViews();
+ if (mPresentation == null) {
+ vlcVout.setVideoView(mSurfaceView);
+ if (mSubtitlesSurfaceView.getVisibility() != View.GONE)
+ vlcVout.setSubtitlesView(mSubtitlesSurfaceView);
+ } else {
+ vlcVout.setVideoView(mPresentation.mSurfaceView);
+ if (mSubtitlesSurfaceView.getVisibility() != View.GONE)
+ vlcVout.setSubtitlesView(mPresentation.mSubtitlesSurfaceView);
+ }
+ mSurfacesAttached = true;
+ vlcVout.addCallback(this);
+ vlcVout.attachViews();
+
+ initUI();
+
+ LibVLC().setOnHardwareAccelerationError(this);
+
+ loadMedia();
+
+ // Add any selected subtitle file from the file picker
+ if(mSubtitleSelectedFiles.size() > 0) {
+ for(String file : mSubtitleSelectedFiles) {
+ Log.i(TAG, "Adding user-selected subtitle " + file);
+ mService.addSubtitleTrack(file);
+ }
+ }
+
+ // Set user playback speed
+ mService.setRate(mSettings.getFloat(PreferencesActivity.VIDEO_SPEED, 1));
+ }
+
+ private void initUI() {
+
+ cleanUI();
+
/* Dispatch ActionBar touch events to the Activity */
mActionBarView.setOnTouchListener(new View.OnTouchListener() {
@Override
@@ -718,35 +766,7 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
if (mMediaRouter != null)
mediaRouterAddCallback(true);
- LibVLC().setOnHardwareAccelerationError(this);
- final IVLCVout vlcVout = mService.getVLCVout();
- vlcVout.detachViews();
- if (mPresentation == null) {
- vlcVout.setVideoView(mSurfaceView);
- if (mSubtitlesSurfaceView.getVisibility() != View.GONE)
- vlcVout.setSubtitlesView(mSubtitlesSurfaceView);
- } else {
- vlcVout.setVideoView(mPresentation.mSurfaceView);
- if (mSubtitlesSurfaceView.getVisibility() != View.GONE)
- vlcVout.setSubtitlesView(mPresentation.mSubtitlesSurfaceView);
- }
- mSurfacesAttached = true;
- vlcVout.addCallback(this);
- vlcVout.attachViews();
mSurfaceView.setKeepScreenOn(true);
-
- loadMedia();
-
- // Add any selected subtitle file from the file picker
- if(mSubtitleSelectedFiles.size() > 0) {
- for(String file : mSubtitleSelectedFiles) {
- Log.i(TAG, "Adding user-selected subtitle " + file);
- mService.addSubtitleTrack(file);
- }
- }
-
- // Set user playback speed
- mService.setRate(mSettings.getFloat(PreferencesActivity.VIDEO_SPEED, 1));
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@@ -762,30 +782,12 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
mPlaybackStarted = false;
mService.removeCallback(this);
+
+ mHandler.removeCallbacksAndMessages(null);
final IVLCVout vlcVout = mService.getVLCVout();
vlcVout.removeCallback(this);
if (mSurfacesAttached)
vlcVout.detachViews();
- mSurfaceView.setKeepScreenOn(false);
-
- mHandler.removeCallbacksAndMessages(null);
-
- if (mDetector != null) {
- mDetector.setOnDoubleTapListener(null);
- mDetector = null;
- }
-
- /* Stop listening for changes to media routes. */
- if (mMediaRouter != null)
- mediaRouterAddCallback(false);
-
- if (AndroidUtil.isHoneycombOrLater() && mOnLayoutChangeListener != null)
- mSurfaceFrame.removeOnLayoutChangeListener(mOnLayoutChangeListener);
-
- if (AndroidUtil.isICSOrLater())
- getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(null);
-
- mActionBarView.setOnTouchListener(null);
if(mSwitchingView && mService != null) {
Log.d(TAG, "mLocation = \"" + mUri + "\"");
@@ -793,6 +795,8 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
return;
}
+ cleanUI();
+
final boolean isPaused = !mService.isPlaying();
long time = getTime();
long length = mService.getLength();
@@ -801,7 +805,8 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
time = 0;
else
time -= 2000; // go back 2 seconds, to compensate loading time
- mService.stop();
+ if (mForceStop)
+ mService.stop();
SharedPreferences.Editor editor = mSettings.edit();
// Save position
@@ -843,6 +848,28 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
Util.commitPreferences(editor);
}
+ private void cleanUI() {
+
+ mSurfaceView.setKeepScreenOn(false);
+
+ if (mDetector != null) {
+ mDetector.setOnDoubleTapListener(null);
+ mDetector = null;
+ }
+
+ /* Stop listening for changes to media routes. */
+ if (mMediaRouter != null)
+ mediaRouterAddCallback(false);
+
+ if (mSurfaceFrame != null && AndroidUtil.isHoneycombOrLater() && mOnLayoutChangeListener != null)
+ mSurfaceFrame.removeOnLayoutChangeListener(mOnLayoutChangeListener);
+
+ if (AndroidUtil.isICSOrLater())
+ getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(null);
+
+ mActionBarView.setOnTouchListener(null);
+ }
+
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(data == null) return;
@@ -866,22 +893,38 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
public static void start(Context context, Uri uri, String title) {
start(context, uri, title, false, -1);
}
- public static void startOpened(Context context, int openedPosition) {
- start(context, null, null, false, openedPosition);
+ public static void startOpened(Context context, Uri uri, int openedPosition) {
+ start(context, uri, null, false, openedPosition);
}
private static void start(Context context, Uri uri, String title, boolean fromStart, int openedPosition) {
+ Intent intent = getIntent(context, uri, title, fromStart, openedPosition);
+
+ context.startActivity(intent);
+ }
+
+ public static Intent getIntent(String action, MediaWrapper mw, boolean fromStart, int openedPosition) {
+ return getIntent(action, VLCApplication.getAppContext(), mw.getUri(), mw.getTitle(), fromStart, openedPosition);
+ }
+
+ @NonNull
+ public static Intent getIntent(Context context, Uri uri, String title, boolean fromStart, int openedPosition) {
+ return getIntent(PLAY_FROM_VIDEOGRID, context, uri, title, fromStart, openedPosition);
+ }
+
+ @NonNull
+ public static Intent getIntent(String action, Context context, Uri uri, String title, boolean fromStart, int openedPosition) {
Intent intent = new Intent(context, VideoPlayerActivity.class);
intent.setAction(PLAY_FROM_VIDEOGRID);
intent.putExtra(PLAY_EXTRA_ITEM_LOCATION, uri);
intent.putExtra(PLAY_EXTRA_ITEM_TITLE, title);
intent.putExtra(PLAY_EXTRA_FROM_START, fromStart);
- intent.putExtra(PLAY_EXTRA_OPENED_POSITION, openedPosition);
- if (openedPosition != -1)
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
-
- context.startActivity(intent);
+ if (openedPosition != -1) {
+ intent.putExtra(PLAY_EXTRA_OPENED_POSITION, openedPosition);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ }
+ return intent;
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver()
@@ -992,8 +1035,11 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
endDelaySetting();
} else if (BuildConfig.tv && mShowing && !mIsLocked) {
hideOverlay(true);
- } else
+ } else {
+ mForceStop = true;
exitOK();
+ super.onBackPressed();
+ }
}
@Override
@@ -1012,13 +1058,13 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
showOverlayTimeout(OVERLAY_TIMEOUT);
switch (keyCode) {
case KeyEvent.KEYCODE_F:
+// case KeyEvent.KEYCODE_MEDIA_NEXT:
case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
- case KeyEvent.KEYCODE_MEDIA_NEXT:
seekDelta(10000);
return true;
case KeyEvent.KEYCODE_R:
+ case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
case KeyEvent.KEYCODE_MEDIA_REWIND:
- case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
seekDelta(-10000);
return true;
case KeyEvent.KEYCODE_BUTTON_R1:
@@ -1209,7 +1255,6 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
}
public void delaySubs(long delta){
- Log.d(TAG, "delaySubs " + delta);
long delay = mService.getSpuDelay()+delta;
mService.setSpuDelay(delay);
mInfo.setText(getString(R.string.spu_delay) + "\n" + (delay / 1000l) + " ms");
@@ -1490,10 +1535,6 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
loadMedia();
}
});
- } else {
- /* Exit player when reaching the end */
- mEndReached = true;
- exitOK();
}
}
@@ -2814,6 +2855,7 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
if (itemTitle != null)
title = itemTitle;
mTitle.setText(title);
+
}
@SuppressWarnings("deprecation")
@@ -3154,4 +3196,14 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
public void onSurfacesDestroyed(IVLCVout vlcVout) {
mSurfacesAttached = false;
}
+
+ private BroadcastReceiver mServiceReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (TextUtils.equals(intent.getAction(), PLAY_FROM_SERVICE))
+ onNewIntent(intent);
+ else if (TextUtils.equals(intent.getAction(), EXIT_PLAYER))
+ exitOK();
+ }
+ };
}
--
2.5.0
More information about the Android
mailing list