diff options
Diffstat (limited to 'subsonic-android')
-rw-r--r-- | subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java b/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java index 72198850..3f09917a 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java @@ -84,6 +84,7 @@ public class DownloadServiceImpl extends Service implements DownloadService { private final IBinder binder = new SimpleServiceBinder<DownloadService>(this); private MediaPlayer mediaPlayer; + private MediaPlayer nextMediaPlayer; private final List<DownloadFile> downloadList = new ArrayList<DownloadFile>(); private final List<DownloadFile> backgroundDownloadList = new ArrayList<DownloadFile>(); private final Handler handler = new Handler(); @@ -95,9 +96,12 @@ public class DownloadServiceImpl extends Service implements DownloadService { private final Scrobbler scrobbler = new Scrobbler(); private final JukeboxService jukeboxService = new JukeboxService(this); private DownloadFile currentPlaying; + private DownloadFile nextPlaying; private DownloadFile currentDownloading; private CancellableTask bufferTask; + private CancellableTask nextPlayingTask; private PlayerState playerState = IDLE; + private PlayerState nextPlayerState = IDLE; private boolean shufflePlay; private long revision; private static DownloadService instance; @@ -148,6 +152,17 @@ public class DownloadServiceImpl extends Service implements DownloadService { return false; } }); + + nextMediaPlayer = new MediaPlayer(); + nextMediaPlayer.setWakeMode(this, PowerManager.PARTIAL_WAKE_LOCK); + + nextMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() { + @Override + public boolean onError(MediaPlayer mediaPlayer, int what, int more) { + handleErrorNext(new Exception("MediaPlayer error: " + what + " (" + more + ")")); + return false; + } + }); Util.registerMediaButtonEventReceiver(this); @@ -208,6 +223,7 @@ public class DownloadServiceImpl extends Service implements DownloadService { } lifecycleSupport.onDestroy(); mediaPlayer.release(); + nextMediaPlayer.release(); shufflePlayBuffer.shutdown(); if (equalizerController != null) { equalizerController.release(); @@ -550,8 +566,13 @@ public class DownloadServiceImpl extends Service implements DownloadService { reset(); setCurrentPlaying(null, false); } else { + if(nextPlayingTask != null) { + nextPlayingTask.cancel(); + } setCurrentPlaying(index, start); checkDownloads(); + nextPlayingTask = new CheckCompletionTask(nextPlaying); + nextPlayingTask.start(); if (start) { if (jukeboxEnabled) { jukeboxService.skip(getCurrentPlayingIndex(), 0); @@ -771,6 +792,11 @@ public class DownloadServiceImpl extends Service implements DownloadService { } } } + + synchronized void setNextPlayerState(PlayerState playerState) { + Log.i(TAG, "Next: " + this.playerState.name() + " -> " + playerState.name() + " (" + currentPlaying + ")"); + this.nextPlayerState = playerState; + } @Override public void setSuggestedPlaylistName(String name) { @@ -922,6 +948,40 @@ public class DownloadServiceImpl extends Service implements DownloadService { } } + private synchronized void setupNext(final DownloadFile downloadFile) { + try { + final File file = downloadFile.isCompleteFileAvailable() ? downloadFile.getCompleteFile() : downloadFile.getPartialFile(); + downloadFile.updateModificationDate(); + nextMediaPlayer.setOnCompletionListener(null); + nextMediaPlayer.reset(); + setNextPlayerState(IDLE); + nextMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); + nextMediaPlayer.setDataSource(file.getPath()); + setNextPlayerState(PREPARING); + + nextMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { + public void onPrepared(MediaPlayer mediaPlayer) { + try { + setNextPlayerState(PREPARED); + } catch (Exception x) { + handleErrorNext(x); + } + } + }); + + nextMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() { + public boolean onError(MediaPlayer mediaPlayer, int what, int extra) { + Log.w(TAG, "Error on playing next " + "(" + what + ", " + extra + "): " + downloadFile); + return true; + } + }); + + nextMediaPlayer.prepareAsync(); + } catch (Exception x) { + handleErrorNext(x); + } + } + @Override public void setSleepTimerDuration(int duration){ timerDuration = duration; @@ -974,6 +1034,11 @@ public class DownloadServiceImpl extends Service implements DownloadService { mediaPlayer.reset(); setPlayerState(IDLE); } + private void handleErrorNext(Exception x) { + Log.w(TAG, "Next Media player error: " + x, x); + nextMediaPlayer.reset(); + setNextPlayerState(IDLE); + } protected synchronized void checkDownloads() { if (!Util.isExternalStoragePresent() || !lifecycleSupport.isExternalStorageAvailable()) { @@ -1020,6 +1085,9 @@ public class DownloadServiceImpl extends Service implements DownloadService { currentDownloading = downloadFile; currentDownloading.download(); cleanupCandidates.add(currentDownloading); + if(i == (start + 1)) { + setNextPlayerState(DOWNLOADING); + } break; } } else if (currentPlaying != downloadFile) { @@ -1161,4 +1229,38 @@ public class DownloadServiceImpl extends Service implements DownloadService { return "BufferTask (" + downloadFile + ")"; } } + + private class CheckCompletionTask extends CancellableTask { + private final DownloadFile downloadFile; + private final File partialFile; + + public CheckCompletionTask(DownloadFile downloadFile) { + this.downloadFile = downloadFile; + partialFile = downloadFile.getPartialFile(); + } + + @Override + public void execute() { + while (!bufferComplete()) { + Util.sleepQuietly(1000L); + if (isCancelled()) { + return; + } + } + + // Do something + setupNext(downloadFile); + } + + private boolean bufferComplete() { + boolean completeFileAvailable = downloadFile.isWorkDone(); + Log.i(TAG, "Buffering next " + partialFile + " (" + partialFile.length() + ")"); + return completeFileAvailable; + } + + @Override + public String toString() { + return "CheckCompletionTask (" + downloadFile + ")"; + } + } } |