Introduction

The android media viewer mediaplayer MediaSessionCompat tutorial series describes how to set up the MediaSession and its callback. Which will receive requests from the the MediaController and then pass them onto the MediaPlayer.

Get Code

The code can be found on github from the following instructions below

https://github.com/mobapptuts/media-thumbnail-viewer.git Tag

media-viewer-mediasession

or you can run this command

git clone https://github.com/mobapptuts/media-thumbnail-viewer.git –branch

media-viewer-mediasession

This video describes how to import the code from github using android studio and also how to use git tags

Steps

Create the members to support the MediaSession callback

Now is a good time to add the TAG which normally gets done at the start

private static final String TAG = "VideoPlayActivity";

 Add the PlaybackStateCompat & MediaSessionCompat members

private PlaybackStateCompat.Builder mPBuilder;
private MediaSessionCompat mSession;

 Create the MediaSession callback class

All of the previous code that calls directly to the MediaPlayer will be moved into the MediaSession callback. Note a new method for releasing the MediaSession and MediaPlayer resources is implemented.

And the SurfaceHolder implementation is also relocated inside the MediaSession callback class because it is required for the creation of the MediaPlayer

All references to the UI are replaced by updating the MediaSession of the media player’s state.

And the audio focus implementation is also relocated to the media session callback.

 

private class MediaSessionCallback extends MediaSessionCompat.Callback implements SurfaceHolder.Callback, MediaPlayer.OnCompletionListener,
           AudioManager.OnAudioFocusChangeListener {

       private Context mContext;
       private AudioManager mAudioManager;
       private IntentFilter mNoisyIntentFilter;
       private AudioBecommingNoisy mAudioBecommingNoisy;

       public MediaSessionCallback(Context context) {
           super();

           mContext = context;
           mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
           mAudioBecommingNoisy = new AudioBecommingNoisy();
           mNoisyIntentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
           mSurfaceView.getHolder().addCallback(this);
       }

       private class AudioBecommingNoisy extends BroadcastReceiver {
           @Override
           public void onReceive(Context context, Intent intent) {
               mediaPause();
           }
       }

       @Override
       public void onPlay() {
           super.onPlay();

           mediaPlay();
       }

       @Override
       public void onPause() {
           super.onPause();

           mediaPause();
       }

       @Override
       public void onStop() {
           super.onStop();

           releaseResources();
       }

       private void releaseResources() {
           mSession.setActive(false);
           if(mMediaPlayer != null) {
               mMediaPlayer.stop();
               mMediaPlayer.reset();
               mMediaPlayer.release();
               mMediaPlayer = null;
           }
       }

       private void mediaPlay() {
           registerReceiver(mAudioBecommingNoisy, mNoisyIntentFilter);
           int requestAudioFocusResult = mAudioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
           if(requestAudioFocusResult == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
               mSession.setActive(true);
               mPBuilder.setActions(PlaybackStateCompat.ACTION_PAUSE | PlaybackStateCompat.ACTION_STOP);
               mPBuilder.setState(PlaybackStateCompat.STATE_PLAYING,
                       mMediaPlayer.getCurrentPosition(), 1.0f, SystemClock.elapsedRealtime());
               mSession.setPlaybackState(mPBuilder.build());
               mMediaPlayer.start();
           }
       }

       private void mediaPause() {
           mMediaPlayer.pause();
           mPBuilder.setActions(PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_STOP);
           mPBuilder.setState(PlaybackStateCompat.STATE_PAUSED,
                   mMediaPlayer.getCurrentPosition(), 1.0f, SystemClock.elapsedRealtime());
           mSession.setPlaybackState(mPBuilder.build());
           mAudioManager.abandonAudioFocus(this);
           unregisterReceiver(mAudioBecommingNoisy);
       }

       @Override
       public void surfaceCreated(SurfaceHolder surfaceHolder) {
           mMediaPlayer = MediaPlayer.create(mContext, mVideoUri, surfaceHolder);
           mMediaPlayer.setOnCompletionListener(this);
       }

       @Override
       public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {

       }

       @Override
       public void surfaceDestroyed(SurfaceHolder surfaceHolder) {

       }

       @Override
       public void onCompletion(MediaPlayer mediaPlayer) {
           mPBuilder.setActions(PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_STOP);
           mPBuilder.setState(PlaybackStateCompat.STATE_STOPPED,
                   mMediaPlayer.getCurrentPosition(), 1.0f, SystemClock.elapsedRealtime());
           mSession.setPlaybackState(mPBuilder.build());
       }

       @Override
       public void onAudioFocusChange(int audioFocusChanged) {
           switch (audioFocusChanged) {
               case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                   mediaPause();
                   break;
               case AudioManager.AUDIOFOCUS_GAIN:
                   mediaPlay();
                   break;
               case AudioManager.AUDIOFOCUS_LOSS:
                   mediaPause();
                   break;
           }
       }
   }

Initialise the PlaybackStateCompat & MediaSessionCompat members in onCreate

@Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_video_play);

       mPlayPauseButton = (ImageButton) findViewById(R.id.videoPlayPauseButton);
       mSurfaceView = (SurfaceView) findViewById(R.id.videoSurfaceView);

       Intent callingIntent = this.getIntent();
       if(callingIntent != null) {
           mVideoUri = callingIntent.getData();
       }

       mSession = new MediaSessionCompat(this, TAG);
       mSession.setCallback(new MediaSessionCallback(this));
       mSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
       mPBuilder = new PlaybackStateCompat.Builder();

   }

 Remove all references to the media player in the activity methods

This is because the activity methods are directly related to the application UI. Therefore should not be calling the media player directly.

public void playPauseClick(View view) {

   }

   @Override
   protected void onStop() {


       super.onStop();
   }

   @Override
   protected void onPause() {
       super.onPause();

   }

 

Android media viewer mediaplayer MediaSessionCompat summary

In the android media viewer mediaplayer MediaSessionCompat tutorial we focused to the MediaSessionCompat and it’s callback. All the MediaPlayer calls are referred to from the MediaSessionCompat. And all the UI calls were required to be moved across to the MediaControllerCompat callback.

By extracting the media player calls from the UI allows the application to now support any number of media players.

The following tutorial will focus on the implementation of the MediaController callback.

 

Android media viewer mediaplayer MediaSessionCompat

About The Author
-

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>