Move player into INITIALIZED state in some cases to save bandwidth

This commit is contained in:
daniel oeh 2012-10-11 12:09:29 +02:00
parent 59e5a9ddb8
commit 1f214573e9
6 changed files with 67 additions and 18 deletions

View File

@ -25,7 +25,7 @@
<application <application
android:name="de.danoeh.antennapod.PodcastApp" android:name="de.danoeh.antennapod.PodcastApp"
android:debuggable="false" android:debuggable="true"
android:icon="@drawable/ic_launcher" android:icon="@drawable/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:logo="@drawable/ic_launcher" android:logo="@drawable/ic_launcher"

View File

@ -52,7 +52,7 @@ public abstract class MediaplayerActivity extends SherlockFragmentActivity
public MediaplayerActivity() { public MediaplayerActivity() {
super(); super();
controller = new PlaybackController(this) { controller = new PlaybackController(this, false) {
@Override @Override
public void setupGUI() { public void setupGUI() {
@ -151,6 +151,7 @@ public abstract class MediaplayerActivity extends SherlockFragmentActivity
@Override @Override
protected void onPause() { protected void onPause() {
super.onPause(); super.onPause();
controller.reinitServiceIfPaused();
controller.pause(); controller.pause();
} }

View File

@ -133,6 +133,7 @@ public class FeedManager {
startWhenPrepared); startWhenPrepared);
launchIntent launchIntent
.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, shouldStream); .putExtra(PlaybackService.EXTRA_SHOULD_STREAM, shouldStream);
launchIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY, true);
context.startService(launchIntent); context.startService(launchIntent);
if (showPlayer) { if (showPlayer) {
// Launch Mediaplayer // Launch Mediaplayer

View File

@ -78,7 +78,7 @@ public class ExternalPlayerFragment extends SherlockFragment {
} }
private PlaybackController setupPlaybackController() { private PlaybackController setupPlaybackController() {
return new PlaybackController(getActivity()) { return new PlaybackController(getActivity(), true) {
@Override @Override
public void setupGUI() { public void setupGUI() {

View File

@ -337,7 +337,7 @@ public class PlaybackService extends Service {
case AudioManager.AUDIOFOCUS_LOSS: case AudioManager.AUDIOFOCUS_LOSS:
if (AppConfig.DEBUG) if (AppConfig.DEBUG)
Log.d(TAG, "Lost audio focus"); Log.d(TAG, "Lost audio focus");
pause(true); pause(true, true);
stopSelf(); stopSelf();
break; break;
case AudioManager.AUDIOFOCUS_GAIN: case AudioManager.AUDIOFOCUS_GAIN:
@ -362,7 +362,7 @@ public class PlaybackService extends Service {
if (status == PlayerStatus.PLAYING) { if (status == PlayerStatus.PLAYING) {
if (AppConfig.DEBUG) if (AppConfig.DEBUG)
Log.d(TAG, "Lost audio focus temporarily. Pausing..."); Log.d(TAG, "Lost audio focus temporarily. Pausing...");
pause(false); pause(false, false);
pausedBecauseOfTransientAudiofocusLoss = true; pausedBecauseOfTransientAudiofocusLoss = true;
} }
} }
@ -394,7 +394,7 @@ public class PlaybackService extends Service {
// check if already playing and playbackType is the same // check if already playing and playbackType is the same
} else if (media == null || mediaId != media.getId() } else if (media == null || mediaId != media.getId()
|| playbackType != shouldStream) { || playbackType != shouldStream) {
pause(true); pause(true, false);
player.reset(); player.reset();
sendNotificationBroadcast(NOTIFICATION_TYPE_RELOAD, 0); sendNotificationBroadcast(NOTIFICATION_TYPE_RELOAD, 0);
if (media == null || mediaId != media.getId()) { if (media == null || mediaId != media.getId()) {
@ -406,7 +406,8 @@ public class PlaybackService extends Service {
shouldStream = playbackType; shouldStream = playbackType;
startWhenPrepared = intent.getBooleanExtra( startWhenPrepared = intent.getBooleanExtra(
EXTRA_START_WHEN_PREPARED, false); EXTRA_START_WHEN_PREPARED, false);
prepareImmediately = intent.getBooleanExtra(EXTRA_PREPARE_IMMEDIATELY, false); prepareImmediately = intent.getBooleanExtra(
EXTRA_PREPARE_IMMEDIATELY, false);
initMediaplayer(); initMediaplayer();
} else { } else {
@ -435,21 +436,27 @@ public class PlaybackService extends Service {
case KeyEvent.KEYCODE_HEADSETHOOK: case KeyEvent.KEYCODE_HEADSETHOOK:
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
if (status == PlayerStatus.PLAYING) { if (status == PlayerStatus.PLAYING) {
pause(false); pause(false, true);
} else if (status == PlayerStatus.PAUSED) { } else if (status == PlayerStatus.PAUSED) {
play(); play();
} else if (status == PlayerStatus.PREPARING) { } else if (status == PlayerStatus.PREPARING) {
setStartWhenPrepared(!startWhenPrepared); setStartWhenPrepared(!startWhenPrepared);
} else if (status == PlayerStatus.INITIALIZED) {
startWhenPrepared = true;
prepare();
} }
break; break;
case KeyEvent.KEYCODE_MEDIA_PLAY: case KeyEvent.KEYCODE_MEDIA_PLAY:
if (status == PlayerStatus.PAUSED) { if (status == PlayerStatus.PAUSED) {
play(); play();
} else if (status == PlayerStatus.INITIALIZED) {
startWhenPrepared = true;
prepare();
} }
break; break;
case KeyEvent.KEYCODE_MEDIA_PAUSE: case KeyEvent.KEYCODE_MEDIA_PAUSE:
if (status == PlayerStatus.PLAYING) { if (status == PlayerStatus.PLAYING) {
pause(false); pause(false, true);
} }
break; break;
} }
@ -647,7 +654,7 @@ public class PlaybackService extends Service {
public boolean onError(MediaPlayer mp, int what, int extra) { public boolean onError(MediaPlayer mp, int what, int extra) {
Log.w(TAG, "An error has occured: " + what); Log.w(TAG, "An error has occured: " + what);
if (mp.isPlaying()) { if (mp.isPlaying()) {
pause(true); pause(true, true);
} }
sendNotificationBroadcast(NOTIFICATION_TYPE_ERROR, what); sendNotificationBroadcast(NOTIFICATION_TYPE_ERROR, what);
stopSelf(); stopSelf();
@ -699,12 +706,12 @@ public class PlaybackService extends Service {
media = nextItem.getMedia(); media = nextItem.getMedia();
feed = nextItem.getFeed(); feed = nextItem.getFeed();
shouldStream = !media.isDownloaded(); shouldStream = !media.isDownloaded();
startWhenPrepared = true; prepareImmediately = startWhenPrepared = true;
} else { } else {
if (AppConfig.DEBUG) if (AppConfig.DEBUG)
Log.d(TAG, Log.d(TAG,
"No more episodes available to play; Reloading current episode"); "No more episodes available to play; Reloading current episode");
startWhenPrepared = false; prepareImmediately = startWhenPrepared = false;
stopForeground(true); stopForeground(true);
stopWidgetUpdater(); stopWidgetUpdater();
} }
@ -758,8 +765,10 @@ public class PlaybackService extends Service {
* *
* @param abandonFocus * @param abandonFocus
* is true if the service should release audio focus * is true if the service should release audio focus
* @param reset
* is true if service should reinit after pausing if the media file is being streamed
*/ */
public void pause(boolean abandonFocus) { public void pause(boolean abandonFocus, boolean reinit) {
if (player.isPlaying()) { if (player.isPlaying()) {
if (AppConfig.DEBUG) if (AppConfig.DEBUG)
Log.d(TAG, "Pausing playback."); Log.d(TAG, "Pausing playback.");
@ -773,6 +782,9 @@ public class PlaybackService extends Service {
setStatus(PlayerStatus.PAUSED); setStatus(PlayerStatus.PAUSED);
stopWidgetUpdater(); stopWidgetUpdater();
stopForeground(true); stopForeground(true);
if (shouldStream && reinit) {
reinit();
}
} }
} }
@ -1001,6 +1013,7 @@ public class PlaybackService extends Service {
.setPlaybackState(RemoteControlClient.PLAYSTATE_PLAYING); .setPlaybackState(RemoteControlClient.PLAYSTATE_PLAYING);
break; break;
case PAUSED: case PAUSED:
case INITIALIZED:
remoteControlClient remoteControlClient
.setPlaybackState(RemoteControlClient.PLAYSTATE_PAUSED); .setPlaybackState(RemoteControlClient.PLAYSTATE_PAUSED);
break; break;
@ -1062,7 +1075,7 @@ public class PlaybackService extends Service {
if (AppConfig.DEBUG) if (AppConfig.DEBUG)
Log.d(TAG, Log.d(TAG,
"Pausing playback because headset was disconnected"); "Pausing playback because headset was disconnected");
pause(false); pause(false, true);
} }
} else { } else {
Log.e(TAG, "Received invalid ACTION_HEADSET_PLUG intent"); Log.e(TAG, "Received invalid ACTION_HEADSET_PLUG intent");
@ -1145,7 +1158,7 @@ public class PlaybackService extends Service {
if (status == PlayerStatus.PLAYING) { if (status == PlayerStatus.PLAYING) {
if (AppConfig.DEBUG) if (AppConfig.DEBUG)
Log.d(TAG, "Pausing playback"); Log.d(TAG, "Pausing playback");
pause(true); pause(true, true);
} }
postExecute(); postExecute();
} }

View File

@ -57,8 +57,15 @@ public abstract class PlaybackController {
private boolean mediaInfoLoaded = false; private boolean mediaInfoLoaded = false;
private boolean released = false; private boolean released = false;
public PlaybackController(Activity activity) { /**
* True if controller should reinit playback service if 'pause' button is
* pressed.
*/
private boolean reinitOnPause;
public PlaybackController(Activity activity, boolean reinitOnPause) {
this.activity = activity; this.activity = activity;
this.reinitOnPause = reinitOnPause;
schedExecutor = new ScheduledThreadPoolExecutor(SCHED_EX_POOLSIZE, schedExecutor = new ScheduledThreadPoolExecutor(SCHED_EX_POOLSIZE,
new ThreadFactory() { new ThreadFactory() {
@ -134,7 +141,7 @@ public abstract class PlaybackController {
public void pause() { public void pause() {
mediaInfoLoaded = false; mediaInfoLoaded = false;
if (playbackService != null && playbackService.isPlayingVideo()) { if (playbackService != null && playbackService.isPlayingVideo()) {
playbackService.pause(true); playbackService.pause(true, true);
} }
} }
@ -186,6 +193,8 @@ public abstract class PlaybackController {
serviceIntent.putExtra(PlaybackService.EXTRA_MEDIA_ID, mediaId); serviceIntent.putExtra(PlaybackService.EXTRA_MEDIA_ID, mediaId);
serviceIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED, serviceIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED,
false); false);
serviceIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY,
false);
serviceIntent serviceIntent
.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, prefs .putExtra(PlaybackService.EXTRA_SHOULD_STREAM, prefs
.getBoolean(PlaybackService.PREF_LAST_IS_STREAM, .getBoolean(PlaybackService.PREF_LAST_IS_STREAM,
@ -388,6 +397,11 @@ public abstract class PlaybackController {
case AWAITING_VIDEO_SURFACE: case AWAITING_VIDEO_SURFACE:
onAwaitingVideoSurface(); onAwaitingVideoSurface();
break; break;
case INITIALIZED:
checkMediaInfoLoaded();
clearStatusMsg();
updatePlayButtonAppearance(R.drawable.av_play);
break;
} }
} }
@ -488,7 +502,7 @@ public abstract class PlaybackController {
if (playbackService != null) { if (playbackService != null) {
switch (status) { switch (status) {
case PLAYING: case PLAYING:
playbackService.pause(true); playbackService.pause(true, reinitOnPause);
break; break;
case PAUSED: case PAUSED:
case PREPARED: case PREPARED:
@ -497,6 +511,15 @@ public abstract class PlaybackController {
case PREPARING: case PREPARING:
playbackService.setStartWhenPrepared(!playbackService playbackService.setStartWhenPrepared(!playbackService
.isStartWhenPrepared()); .isStartWhenPrepared());
if (reinitOnPause
&& playbackService.isStartWhenPrepared() == false) {
playbackService.reinit();
}
break;
case INITIALIZED:
playbackService.setStartWhenPrepared(true);
playbackService.prepare();
break;
} }
} else { } else {
Log.w(TAG, Log.w(TAG,
@ -610,6 +633,17 @@ public abstract class PlaybackController {
} }
} }
/** Move service into INITIALIZED state if it's paused to save bandwidth */
public void reinitServiceIfPaused() {
if (playbackService != null
&& playbackService.isShouldStream()
&& (playbackService.getStatus() == PlayerStatus.PAUSED || (playbackService
.getStatus() == PlayerStatus.PREPARING && playbackService
.isStartWhenPrepared() == false))) {
playbackService.reinit();
}
}
/** Refreshes the current position of the media file that is playing. */ /** Refreshes the current position of the media file that is playing. */
public class MediaPositionObserver implements Runnable { public class MediaPositionObserver implements Runnable {