Java tutorial
/* == This file is part of Tomahawk Player - <http://tomahawk-player.org> === * * Copyright 2016, Enno Gottschalk <mrmaffen@googlemail.com> * Copyright 2016, Anton Romanov * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Tomahawk 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Tomahawk. If not, see <http://www.gnu.org/licenses/>. */ package org.runbuddy.tomahawk.mediaplayers; import android.media.AudioManager; import android.media.MediaPlayer; import android.support.v4.media.session.PlaybackStateCompat; import android.util.Log; import org.jdeferred.DoneCallback; import org.runbuddy.libtomahawk.resolver.Query; import org.runbuddy.tomahawk.utils.ThreadManager; import java.io.IOException; public class AndroidMediaPlayer extends TomahawkMediaPlayer { private static final String TAG = AndroidMediaPlayer.class.getSimpleName(); private static MediaPlayer sMediaPlayer = null; private Query mPreparedQuery; private Query mPreparingQuery; private int mPlayState = PlaybackStateCompat.STATE_NONE; private TomahawkMediaPlayerCallback mMediaPlayerCallback; private class CompletionListener implements MediaPlayer.OnCompletionListener { public void onCompletion(MediaPlayer mp) { Runnable r = new Runnable() { @Override public void run() { Log.d(TAG, "onCompletion()"); if (mMediaPlayerCallback != null) { mMediaPlayerCallback.onCompletion(AndroidMediaPlayer.this, mPreparedQuery); } else { Log.e(TAG, "Wasn't able to call onCompletion because callback object is null"); } } }; ThreadManager.get().executePlayback(AndroidMediaPlayer.this, r); } } @Override public void play() { mPlayState = PlaybackStateCompat.STATE_PLAYING; handlePlayState(); } @Override public void pause() { mPlayState = PlaybackStateCompat.STATE_PAUSED; handlePlayState(); } @Override public void seekTo(long msec) { if (sMediaPlayer != null) { try { sMediaPlayer.seekTo((int) msec); } catch (IllegalStateException e) { //ignored } } } @Override public void prepare(final Query query, final TomahawkMediaPlayerCallback callback) { Log.d(TAG, "prepare() query: " + query); mMediaPlayerCallback = callback; mPreparedQuery = null; mPreparingQuery = query; if (sMediaPlayer != null) { try { sMediaPlayer.stop(); } catch (IllegalStateException e) { //ignored } } getStreamUrl(query.getPreferredTrackResult()).done(new DoneCallback<String>() { @Override public void onDone(String url) { Log.d(TAG, "Received stream url: " + url + " for query: " + query); if (mPreparingQuery != null && mPreparingQuery == query) { Log.d(TAG, "Starting to prepare stream url: " + url + " for query: " + query); if (sMediaPlayer != null) { try { sMediaPlayer.stop(); } catch (IllegalStateException e) { //ignored } sMediaPlayer.release(); } sMediaPlayer = new MediaPlayer(); sMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); try { sMediaPlayer.setDataSource(url); sMediaPlayer.prepare(); } catch (IOException | IllegalStateException e) { Log.e(TAG, "prepare - ", e); callback.onError(AndroidMediaPlayer.this, "MediaPlayerEncounteredError"); } sMediaPlayer.setOnCompletionListener(new CompletionListener()); mPreparedQuery = mPreparingQuery; mPreparingQuery = null; handlePlayState(); callback.onPrepared(AndroidMediaPlayer.this, mPreparedQuery); Log.d(TAG, "onPrepared() url: " + url + " for query: " + query); } else { Log.d(TAG, "Ignoring stream url: " + url + " for query: " + query + ", because preparing query is: " + mPreparingQuery); } } }); } @Override public void release() { Log.d(TAG, "release"); mPreparedQuery = null; mPreparingQuery = null; if (sMediaPlayer != null) { try { sMediaPlayer.stop(); } catch (IllegalStateException e) { //ignored } sMediaPlayer.release(); } mMediaPlayerCallback = null; } @Override public long getPosition() { if (sMediaPlayer != null) { try { return sMediaPlayer.getCurrentPosition(); } catch (IllegalStateException e) { //ignored } } return 0; } @Override public void setBitrate(int mode) { } @Override public boolean isPlaying(Query query) { try { return sMediaPlayer != null && sMediaPlayer.isPlaying(); } catch (IllegalStateException e) { //ignored } return false; } @Override public boolean isPreparing(Query query) { return mPreparingQuery != null && mPreparingQuery == query; } @Override public boolean isPrepared(Query query) { return mPreparedQuery != null && mPreparedQuery == query; } private void handlePlayState() { if (sMediaPlayer != null && mPreparedQuery != null) { try { if (mPlayState == PlaybackStateCompat.STATE_PAUSED && sMediaPlayer.isPlaying()) { sMediaPlayer.pause(); } else if (mPlayState == PlaybackStateCompat.STATE_PLAYING && !sMediaPlayer.isPlaying()) { sMediaPlayer.start(); } } catch (IllegalStateException e) { //ignored } } } }