Created
May 10, 2016 21:23
-
-
Save moagrius/f2ca1d2d5c451d8b862304e46caf69f1 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
import android.app.Service; | |
import android.content.Intent; | |
import android.media.MediaCodec; | |
import android.net.Uri; | |
import android.os.Binder; | |
import android.os.IBinder; | |
import android.util.Log; | |
import android.view.Surface; | |
import android.widget.MediaController; | |
import com.google.android.exoplayer.ExoPlaybackException; | |
import com.google.android.exoplayer.ExoPlayer; | |
import com.google.android.exoplayer.MediaCodecAudioTrackRenderer; | |
import com.google.android.exoplayer.MediaCodecSelector; | |
import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; | |
import com.google.android.exoplayer.extractor.ExtractorSampleSource; | |
import com.google.android.exoplayer.upstream.Allocator; | |
import com.google.android.exoplayer.upstream.DataSource; | |
import com.google.android.exoplayer.upstream.DefaultAllocator; | |
import com.google.android.exoplayer.upstream.DefaultUriDataSource; | |
import com.google.android.exoplayer.util.Util; | |
public class BackgroundAudioService extends Service implements ExoPlayer.Listener, MediaController.MediaPlayerControl { | |
private static final int BUFFER_SEGMENT_SIZE = 64 * 1024; | |
private static final int BUFFER_SEGMENT_COUNT = 256; | |
private static final int BUFFER_SIZE = BUFFER_SEGMENT_SIZE * BUFFER_SEGMENT_COUNT; | |
private MediaCodecVideoTrackRenderer mVideoRenderer; | |
private MediaCodecAudioTrackRenderer mAudioRenderer; | |
private ExoPlayer mExoPlayer; | |
private Surface mSurface; | |
private final IBinder mBackgroundAudioServiceBinder = new BackgroundAudioServiceBinder(); | |
public class BackgroundAudioServiceBinder extends Binder { | |
BackgroundAudioService getService() { | |
return BackgroundAudioService.this; | |
} | |
} | |
@Override | |
public IBinder onBind(Intent intent) { | |
return mBackgroundAudioServiceBinder; | |
} | |
public void playUri(Uri uri){ | |
mExoPlayer = ExoPlayer.Factory.newInstance(2); | |
mExoPlayer.addListener(this); | |
Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE); | |
String userAgent = Util.getUserAgent(this, BackgroundAudioService.class.getSimpleName()); | |
DataSource dataSource = new DefaultUriDataSource(this, null, userAgent); | |
ExtractorSampleSource sampleSource = new ExtractorSampleSource(uri, dataSource, allocator, BUFFER_SIZE); | |
mAudioRenderer = new MediaCodecAudioTrackRenderer(sampleSource, MediaCodecSelector.DEFAULT); | |
mVideoRenderer = new MediaCodecVideoTrackRenderer(getApplicationContext(), sampleSource, MediaCodecSelector.DEFAULT, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT); | |
mExoPlayer.sendMessage(mVideoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, mSurface); | |
mExoPlayer.prepare(mVideoRenderer, mAudioRenderer); | |
mExoPlayer.setPlayWhenReady(true); | |
} | |
public ExoPlayer getExoPlayer(){ | |
return mExoPlayer; | |
} | |
public void setSurface(Surface surface, boolean shouldBlock) { | |
mSurface = surface; | |
if(mExoPlayer != null) { | |
if(shouldBlock) { | |
mExoPlayer.blockingSendMessage(mVideoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface); | |
} else { | |
mExoPlayer.sendMessage(mVideoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface); | |
} | |
} | |
} | |
@Override | |
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { | |
Log.d(BackgroundAudioService.class.getSimpleName(), String.format(">>>>> Player state changed")); | |
Log.d(BackgroundAudioService.class.getSimpleName(), String.format(">>>>> %s", playbackState)); | |
} | |
@Override | |
public void onPlayWhenReadyCommitted() { | |
} | |
@Override | |
public void onPlayerError(ExoPlaybackException error) { | |
} | |
/** | |
* MediaController | |
*/ | |
@Override | |
public int getAudioSessionId() { | |
throw new UnsupportedOperationException(); | |
} | |
@Override | |
public int getBufferPercentage() { | |
if(mExoPlayer == null){ | |
return 0; | |
} | |
return mExoPlayer.getBufferedPercentage(); | |
} | |
@Override | |
public int getCurrentPosition() { | |
if(mExoPlayer == null){ | |
return 0; | |
} | |
return (int) mExoPlayer.getCurrentPosition(); | |
} | |
@Override | |
public int getDuration() { | |
if(mExoPlayer == null){ | |
return 0; | |
} | |
int duration = (int) mExoPlayer.getDuration(); | |
return duration == ExoPlayer.UNKNOWN_TIME ? 0 : duration; | |
} | |
@Override | |
public boolean isPlaying() { | |
return mExoPlayer != null && mExoPlayer.getPlayWhenReady(); | |
} | |
@Override | |
public void start() { | |
if(mExoPlayer != null) { | |
mExoPlayer.setPlayWhenReady(true); | |
} | |
} | |
@Override | |
public void pause() { | |
if(mExoPlayer != null) { | |
mExoPlayer.setPlayWhenReady(false); | |
} | |
} | |
@Override | |
public void seekTo(int timeMillis) { | |
if(mExoPlayer != null) { | |
long seekPosition = Math.min(Math.max(0, timeMillis), getDuration()); | |
mExoPlayer.seekTo(seekPosition); | |
} | |
} | |
@Override | |
public boolean canPause() { | |
return true; | |
} | |
@Override | |
public boolean canSeekBackward() { | |
return true; | |
} | |
@Override | |
public boolean canSeekForward() { | |
return true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Did you manage to make it work with a
forgroundService
mate?If so, it'll be nice if you can share the code or at least give us some tips.
Thanks.