Created
October 22, 2016 02:46
-
-
Save evanhalley/9c4dbc796173346c897c81cbe12a6d51 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Plays media playback on the device audio output | |
* Created by evanhalley on 11/18/15. | |
*/ | |
public class LocalMediaPlayer extends MediaPlayer implements ExoPlayer.Listener, | |
ProgressUpdateListener { | |
private static final String TAG = LocalMediaPlayer.class.getSimpleName(); | |
private static final int ALLOCATION_SIZE = 65_535; | |
private static final int BUFFER_SIZE = 10 * 1_024 * 1_024; | |
private final Context mContext; | |
private final ExoPlayer mMediaPlayer; | |
private PodcastAudioRenderer mTrackRenderer; | |
private Episode mEpisode; | |
private boolean mIsStreaming; | |
private int mMediaPlayerState; | |
public LocalMediaPlayer(PremoMediaPlayerListener mediaPlayerListener, | |
ProgressUpdateListener progressUpdateListener, Context context) { | |
super(mediaPlayerListener, progressUpdateListener); | |
mContext = context; | |
mMediaPlayer = ExoPlayer.Factory.newInstance(1); | |
mMediaPlayer.addListener(this); | |
mMediaPlayerState = MediaPlayerState.STATE_IDLE; | |
} | |
@Override | |
public int getState() { | |
return mMediaPlayerState; | |
} | |
@Override | |
public long getCurrentPosition() { | |
return mMediaPlayer.getCurrentPosition(); | |
} | |
@Override | |
public long getDuration() { | |
return mMediaPlayer.getDuration(); | |
} | |
@Override | |
public long getBufferedPosition() { | |
return mMediaPlayer.getBufferedPosition(); | |
} | |
@Override | |
public boolean isStreaming() { | |
return mIsStreaming; | |
} | |
@Override | |
public void loadEpisode(Episode episode) { | |
mEpisode = episode; | |
} | |
@Override | |
public void startPlayback(boolean playImmediately) { | |
if (mEpisode.getProgress() > -1) { | |
mMediaPlayer.seekTo(mEpisode.getProgress()); | |
} else { | |
mMediaPlayer.seekTo(0); | |
} | |
mTrackRenderer = buildAudioRenderer(); | |
mMediaPlayer.prepare(mTrackRenderer); | |
mMediaPlayer.setPlayWhenReady(playImmediately); | |
} | |
@Override | |
public void resumePlayback() { | |
mMediaPlayer.setPlayWhenReady(true); | |
} | |
@Override | |
public void pausePlayback() { | |
mMediaPlayer.setPlayWhenReady(false); | |
} | |
@Override | |
public void stopPlayback() { | |
mMediaPlayer.stop(); | |
mIsStreaming = false; | |
mEpisode = null; | |
} | |
@Override | |
public void seekTo(long position) { | |
mMediaPlayer.seekTo(position); | |
} | |
@Override | |
public void tearDown() { | |
Log.d(TAG, "Tearing down"); | |
super.tearDown(); | |
mMediaPlayer.release(); | |
mMediaPlayer.removeListener(this); | |
} | |
@Override | |
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { | |
String playbackStateStr; | |
switch (playbackState) { | |
case ExoPlayer.STATE_BUFFERING: | |
mMediaPlayerState = MediaPlayerState.STATE_CONNECTING; | |
playbackStateStr = "Buffering"; | |
break; | |
case ExoPlayer.STATE_ENDED: | |
mMediaPlayerState = MediaPlayerState.STATE_ENDED; | |
playbackStateStr = "Ended"; | |
break; | |
case ExoPlayer.STATE_IDLE: | |
mMediaPlayerState = MediaPlayerState.STATE_IDLE; | |
playbackStateStr = "Idle"; | |
break; | |
case ExoPlayer.STATE_PREPARING: | |
mMediaPlayerState = MediaPlayerState.STATE_CONNECTING; | |
playbackStateStr = "Preparing"; | |
break; | |
case ExoPlayer.STATE_READY: | |
mMediaPlayerState = playWhenReady ? MediaPlayerState.STATE_PLAYING : | |
MediaPlayerState.STATE_PAUSED; | |
playbackStateStr = "Ready"; | |
break; | |
default: | |
mMediaPlayerState = MediaPlayerState.STATE_IDLE; | |
playbackStateStr = "Unknown"; | |
break; | |
} | |
mMediaPlayerListener.onStateChanged(mMediaPlayerState); | |
Log.d(TAG, String.format("ExoPlayer state changed: %s, Play When Ready: %s", | |
playbackStateStr, | |
String.valueOf(playWhenReady))); | |
} | |
@Override | |
public void onPlayWhenReadyCommitted() { | |
Log.d(TAG, "PlayWhenReadyCommitted"); | |
} | |
@Override | |
public void onPlayerError(ExoPlaybackException error) { | |
Log.w(TAG, "Player error encountered", error); | |
stopPlayback(); | |
} | |
@Override | |
public void onProgressUpdate(long progress, long bufferedProgress, long duration) { | |
mProgressUpdateListener.onProgressUpdate(progress, | |
isStreaming() ? bufferedProgress : duration, duration); | |
} | |
@TargetApi(Build.VERSION_CODES.M) | |
@Override | |
public void setPlaybackSpeed(float speed) { | |
if (mTrackRenderer != null) { | |
if (mTrackRenderer instanceof PodcastAudioRendererV21) { | |
((PodcastAudioRendererV21) mTrackRenderer).setSpeed(speed); | |
} else { | |
mMediaPlayer.sendMessage(mTrackRenderer, | |
MediaCodecAudioTrackRenderer.MSG_SET_PLAYBACK_PARAMS, | |
new PlaybackParams().setSpeed(speed)); | |
} | |
} | |
} | |
private PodcastAudioRenderer buildAudioRenderer() { | |
PodcastAudioRenderer trackRenderer = null; | |
Uri uri = null; | |
// return the uri to play | |
switch (mEpisode.getDownloadStatus()) { | |
case DownloadStatus.DOWNLOADED: | |
uri = Uri.parse(mEpisode.getLocalMediaUrl()); | |
mIsStreaming = false; | |
break; | |
case DownloadStatus.DOWNLOADING: | |
case DownloadStatus.NOT_DOWNLOADED: | |
uri = Uri.parse(mEpisode.getRemoteMediaUrl()); | |
mIsStreaming = true; | |
break; | |
} | |
if (uri != null) { | |
Log.d(TAG, "Playing from URI " + uri); | |
Allocator allocator = new DefaultAllocator(ALLOCATION_SIZE); | |
DataSource dataSource = new DefaultUriDataSource(mContext, null, | |
String.format(mContext.getString(R.string.user_agent), | |
PremoApp.getVersionName()), true); | |
ExtractorSampleSource sampleSource = new ExtractorSampleSource( | |
uri, dataSource, allocator, BUFFER_SIZE, | |
new Mp3Extractor(), | |
new Mp4Extractor()); | |
if (Util.SDK_INT >= Build.VERSION_CODES.M) { | |
trackRenderer = new PodcastAudioRenderer(sampleSource); | |
} else { | |
trackRenderer = new PodcastAudioRendererV21(sampleSource); | |
} | |
trackRenderer.setProgressUpdateListener(this); | |
} else { | |
Log.w(TAG, "Uri is null"); | |
} | |
return trackRenderer; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment