@Override public synchronized void shuffle() { Collections.shuffle(downloadList); if (currentPlaying != null) { downloadList.remove(getCurrentPlayingIndex()); downloadList.add(0, currentPlaying); } revision++; lifecycleSupport.serializeDownloadQueue(); updateJukeboxPlaylist(); }
@Override public synchronized void clearIncomplete() { reset(); Iterator<DownloadFile> iterator = downloadList.iterator(); while (iterator.hasNext()) { DownloadFile downloadFile = iterator.next(); if (!downloadFile.isCompleteFileAvailable()) { iterator.remove(); } } lifecycleSupport.serializeDownloadQueue(); updateJukeboxPlaylist(); }
@Override public synchronized void remove(DownloadFile downloadFile) { if (downloadFile == currentDownloading) { currentDownloading.cancelDownload(); currentDownloading = null; } if (downloadFile == currentPlaying) { reset(); setCurrentPlaying(null); } downloadList.remove(downloadFile); revision++; lifecycleSupport.serializeDownloadQueue(); updateJukeboxPlaylist(); }
public synchronized void clear(boolean serialize) { reset(); downloadList.clear(); revision++; if (currentDownloading != null) { currentDownloading.cancelDownload(); currentDownloading = null; } setCurrentPlaying(null); if (serialize) { lifecycleSupport.serializeDownloadQueue(); } updateJukeboxPlaylist(); }
@Override public void onDestroy() { super.onDestroy(); lifecycleSupport.onDestroy(); mediaPlayer.release(); shufflePlayBuffer.shutdown(); if (equalizerController != null) { equalizerController.release(); } if (visualizerController != null) { visualizerController.release(); } instance = null; }
@Override public synchronized void download( List<MusicDirectory.Entry> songs, boolean save, boolean autoplay, boolean playNext) { shufflePlay = false; int offset = 1; if (songs.isEmpty()) { return; } if (save) { for (MusicDirectory.Entry song : songs) { DownloadFile downloadFile = forSong(song); downloadFile.pin(); if (!downloadFile.isWorkDone() && !downloadList.contains(downloadFile)) { downloadList.add(downloadFile); } } } else if (playNext) { if (autoplay && getCurrentPlayingIndex() >= 0) { offset = 0; } for (MusicDirectory.Entry song : songs) { DownloadFile downloadFile = new DownloadFile(this, song); downloadList.add(getCurrentPlayingIndex() + offset, downloadFile); offset++; } } else { for (MusicDirectory.Entry song : songs) { DownloadFile downloadFile = new DownloadFile(this, song); downloadList.add(downloadFile); } } revision++; updateJukeboxPlaylist(); if (autoplay) { play(0); } else { if (currentPlaying == null) { currentPlaying = downloadList.get(0); } checkDownloads(); } lifecycleSupport.serializeDownloadQueue(); }
synchronized void setPlayerState(PlayerState playerState) { LOG.info(this.playerState.name() + " -> " + playerState.name() + " (" + currentPlaying + ")"); if (playerState == PAUSED) { lifecycleSupport.serializeDownloadQueue(); } Util.broadcastPlaybackStatusChange(this, playerState); this.playerState = playerState; if (playerState == STARTED) { scrobbler.scrobble(this, currentPlaying, false); NotificationUtil.setNotificationHiddenByUser(this, false); } else if (playerState == COMPLETED) { scrobbler.scrobble(this, currentPlaying, true); } MusicDirectory.Entry song = currentPlaying == null ? null : currentPlaying.getSong(); NotificationUtil.updateNotification(this, this, handler, song, this.playerState == STARTED); }
@Override public void onCreate() { Util.setUncaughtExceptionHandler(this); super.onCreate(); mediaPlayer = new MediaPlayer(); mediaPlayer.setWakeMode(this, PowerManager.PARTIAL_WAKE_LOCK); mediaPlayer.setOnErrorListener( new MediaPlayer.OnErrorListener() { @Override public boolean onError(MediaPlayer mediaPlayer, int what, int more) { handleError(new Exception("MediaPlayer error: " + what + " (" + more + ")")); return false; } }); if (equalizerAvailable) { equalizerController = new EqualizerController(this, mediaPlayer); if (!equalizerController.isAvailable()) { equalizerController = null; } else { equalizerController.loadSettings(); } } if (visualizerAvailable) { visualizerController = new VisualizerController(this, mediaPlayer); if (!visualizerController.isAvailable()) { visualizerController = null; } } PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, this.getClass().getName()); wakeLock.setReferenceCounted(false); instance = this; lifecycleSupport.onCreate(); }
protected synchronized void checkDownloads() { if (!Util.isExternalStoragePresent() || !lifecycleSupport.isExternalStorageAvailable()) { return; } if (shufflePlay) { checkShufflePlay(); } if (jukeboxEnabled || !Util.isNetworkConnected(this)) { return; } if (downloadList.isEmpty()) { return; } // Need to download current playing? if (currentPlaying != null && currentPlaying != currentDownloading && !currentPlaying.isCompleteFileAvailable()) { // Cancel current download, if necessary. if (currentDownloading != null) { currentDownloading.cancelDownload(); } currentDownloading = currentPlaying; currentDownloading.download(); cleanupCandidates.add(currentDownloading); } // Find a suitable target for download. else if (currentDownloading == null || currentDownloading.isWorkDone() || currentDownloading.isFailed()) { int n = size(); if (n == 0) { return; } int preloaded = 0; int start = currentPlaying == null ? 0 : getCurrentPlayingIndex(); int i = start; do { DownloadFile downloadFile = downloadList.get(i); if (!downloadFile.isWorkDone()) { if (downloadFile.shouldSave() || preloaded < Util.getPreloadCount(this)) { currentDownloading = downloadFile; currentDownloading.download(); cleanupCandidates.add(currentDownloading); break; } } else if (currentPlaying != downloadFile) { preloaded++; } i = (i + 1) % n; } while (i != start); } // Delete obsolete .partial and .complete files. cleanup(); }
private synchronized void doPlay(final DownloadFile downloadFile, int position, boolean start) { try { final File file = downloadFile.isCompleteFileAvailable() ? downloadFile.getCompleteFile() : downloadFile.getPartialFile(); downloadFile.updateModificationDate(); mediaPlayer.setOnCompletionListener(null); mediaPlayer.reset(); setPlayerState(IDLE); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setDataSource(file.getPath()); setPlayerState(PREPARING); mediaPlayer.prepare(); setPlayerState(PREPARED); mediaPlayer.setOnCompletionListener( new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mediaPlayer) { // Acquire a temporary wakelock, since when we return from // this callback the MediaPlayer will release its wakelock // and allow the device to go to sleep. wakeLock.acquire(60000); setPlayerState(COMPLETED); // If COMPLETED and not playing partial file, we are *really" finished // with the song and can move on to the next. if (!file.equals(downloadFile.getPartialFile())) { onSongCompleted(); return; } // If file is not completely downloaded, restart the playback from the current // position. int pos = mediaPlayer.getCurrentPosition(); synchronized (DownloadServiceImpl.this) { // Work-around for apparent bug on certain phones: If close (less than ten seconds) // to the end // of the song, skip to the next rather than restarting it. Integer duration = downloadFile.getSong().getDuration() == null ? null : downloadFile.getSong().getDuration() * 1000; if (duration != null) { if (Math.abs(duration - pos) < 10000) { LOG.info("Skipping restart from " + pos + " of " + duration); onSongCompleted(); return; } } LOG.info("Requesting restart from " + pos + " of " + duration); reset(); bufferTask = new BufferTask(downloadFile, pos); bufferTask.start(); } } }); if (position != 0) { LOG.info("Restarting player from position " + position); mediaPlayer.seekTo(position); } if (start) { mediaPlayer.start(); setPlayerState(STARTED); } else { setPlayerState(PAUSED); } lifecycleSupport.serializeDownloadQueue(); } catch (Exception x) { handleError(x); } }
@Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); lifecycleSupport.onStart(intent); }