org.runbuddy.tomahawk.mediaplayers.VLCMediaPlayer.java Source code

Java tutorial

Introduction

Here is the source code for org.runbuddy.tomahawk.mediaplayers.VLCMediaPlayer.java

Source

/* == This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
 *
 *   Copyright 2014, Enno Gottschalk <mrmaffen@googlemail.com>
 *
 *   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.support.v4.media.session.PlaybackStateCompat;
import android.util.Log;

import org.jdeferred.DoneCallback;
import org.runbuddy.libtomahawk.resolver.Query;
import org.runbuddy.tomahawk.app.TomahawkApp;
import org.runbuddy.tomahawk.utils.PreferenceUtils;
import org.runbuddy.tomahawk.utils.ThreadManager;
import org.videolan.libvlc.LibVLC;
import org.videolan.libvlc.Media;
import org.videolan.libvlc.MediaPlayer;
import org.videolan.libvlc.util.AndroidUtil;

import java.util.ArrayList;

/**
 * This class wraps a libvlc mediaplayer instance.
 */
public class VLCMediaPlayer extends TomahawkMediaPlayer {

    private static final String TAG = VLCMediaPlayer.class.getSimpleName();

    private static MediaPlayer sMediaPlayer;

    private static LibVLC sLibVLC;

    static {
        ArrayList<String> options = new ArrayList<>();
        options.add("--http-reconnect");
        options.add("--network-caching=2000");
        sLibVLC = new LibVLC(options);
        sMediaPlayer = new MediaPlayer(sLibVLC);
    }

    private TomahawkMediaPlayerCallback mMediaPlayerCallback;

    private Query mPreparedQuery;

    private Query mPreparingQuery;

    private int mPlayState = PlaybackStateCompat.STATE_NONE;

    private class MediaPlayerListener implements MediaPlayer.EventListener {

        @Override
        public void onEvent(final MediaPlayer.Event event) {
            Runnable r = new Runnable() {
                @Override
                public void run() {
                    switch (event.type) {
                    case MediaPlayer.Event.EncounteredError:
                        Log.d(TAG, "MediaPlayer.Event.EncounteredError");
                        mPreparedQuery = null;
                        mPreparingQuery = null;
                        if (mMediaPlayerCallback != null) {
                            mMediaPlayerCallback.onError(VLCMediaPlayer.this, "LibVLC encountered an error");
                        } else {
                            Log.e(TAG, "Wasn't able to call onError because callback" + " object is null");
                        }
                        break;
                    case MediaPlayer.Event.EndReached:
                        Log.d(TAG, "MediaPlayer.Event.EndReached");
                        if (mMediaPlayerCallback != null) {
                            mMediaPlayerCallback.onCompletion(VLCMediaPlayer.this, mPreparedQuery);
                        } else {
                            Log.e(TAG, "Wasn't able to call onCompletion because callback" + " object is null");
                        }
                        break;
                    }
                }
            };
            ThreadManager.get().executePlayback(VLCMediaPlayer.this, r);
        }
    }

    public VLCMediaPlayer() {
        sMediaPlayer = new MediaPlayer(sLibVLC);
        if (PreferenceUtils.getBoolean(PreferenceUtils.EQUALIZER_ENABLED)) {
            MediaPlayer.Equalizer equalizer = MediaPlayer.Equalizer.create();
            float[] bands = PreferenceUtils.getFloatArray(PreferenceUtils.EQUALIZER_VALUES);
            equalizer.setPreAmp(bands[0]);
            for (int i = 0; i < MediaPlayer.Equalizer.getBandCount(); i++) {
                equalizer.setAmp(i, bands[i + 1]);
            }
            sMediaPlayer.setEqualizer(equalizer);
        }
        sMediaPlayer.setEventListener(new MediaPlayerListener());
    }

    public static LibVLC getLibVlcInstance() {
        return sLibVLC;
    }

    public static MediaPlayer getMediaPlayerInstance() {
        return sMediaPlayer;
    }

    /**
     * Start playing the previously prepared {@link org.runbuddy.libtomahawk.collection.Track}
     */
    @Override
    public void play() throws IllegalStateException {
        Log.d(TAG, "play()");
        mPlayState = PlaybackStateCompat.STATE_PLAYING;
        handlePlayState();
    }

    /**
     * Pause playing the current {@link org.runbuddy.libtomahawk.collection.Track}
     */
    @Override
    public void pause() throws IllegalStateException {
        Log.d(TAG, "pause()");
        mPlayState = PlaybackStateCompat.STATE_PAUSED;
        handlePlayState();
    }

    /**
     * Seek to the given playback position (in ms)
     */
    @Override
    public void seekTo(long msec) throws IllegalStateException {
        Log.d(TAG, "seekTo()");
        if (mPreparedQuery != null && !TomahawkApp.PLUGINNAME_BEATSMUSIC
                .equals(mPreparedQuery.getPreferredTrackResult().getResolvedBy().getId())) {
            getMediaPlayerInstance().setTime(msec);
        }
    }

    /**
     * Prepare the given url
     */
    @Override
    public void prepare(final Query query, TomahawkMediaPlayerCallback callback) {
        Log.d(TAG, "prepare() query: " + query);
        mMediaPlayerCallback = callback;
        getMediaPlayerInstance().stop();
        mPreparedQuery = null;
        mPreparingQuery = query;
        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);
                    Media media = new Media(sLibVLC, AndroidUtil.LocationToUri(url));
                    getMediaPlayerInstance().setMedia(media);
                    mPreparedQuery = mPreparingQuery;
                    mPreparingQuery = null;
                    mMediaPlayerCallback.onPrepared(VLCMediaPlayer.this, mPreparedQuery);
                    handlePlayState();
                    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;
        getMediaPlayerInstance().stop();
        mMediaPlayerCallback = null;
    }

    /**
     * @return the current track position
     */
    @Override
    public long getPosition() {
        if (mPreparedQuery != null) {
            return getMediaPlayerInstance().getTime();
        } else {
            return 0L;
        }
    }

    @Override
    public void setBitrate(int bitrateMode) {
    }

    @Override
    public boolean isPlaying(Query query) {
        return isPrepared(query) && getMediaPlayerInstance().isPlaying();
    }

    @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 (mPreparedQuery != null) {
            if (mPlayState == PlaybackStateCompat.STATE_PAUSED && getMediaPlayerInstance().isPlaying()) {
                getMediaPlayerInstance().pause();
            } else if (mPlayState == PlaybackStateCompat.STATE_PLAYING && !getMediaPlayerInstance().isPlaying()) {
                getMediaPlayerInstance().play();
            }
        }
    }
}