お気持ちの表明

思考を雑に外出していきます

ExoPlayerでMediaSessionをいい感じに扱う

概要

ExoPlayerを使って音楽再生しようとしてた
んで、MediaSessionを使っていき〜〜〜〜というふうになっていた

「色々書いてくの、めんどくさいな〜〜〜〜」と思っていたところ、そこらへんをよしなにしてくれるextensionがあると知った

他のブログとか特に見つからず、公式ブログを読んでも、パッと理解できなかったので、動作確認できたコードを残しておく

ExoPlayerのExtensionを使っていいかんじにやっていく

例にあげたコードは以下を元にしています

Before

public class MediaPlaybackService extends MediaBrowserServiceCompat {
    private static final String MY_MEDIA_ROOT_ID = "media_root_id";
    private static final String MY_EMPTY_MEDIA_ROOT_ID = "empty_root_id";

    private MediaSessionCompat mMediaSession;
    private PlaybackStateCompat.Builder mStateBuilder;

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

        // Create a MediaSessionCompat
        mMediaSession = new MediaSessionCompat(context, LOG_TAG);

        // Enable callbacks from MediaButtons and TransportControls
        mMediaSession.setFlags(
              MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
              MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);

        // Set an initial PlaybackState with ACTION_PLAY, so media buttons can start the player
        mStateBuilder = new PlaybackStateCompat.Builder()
                            .setActions(
                                PlaybackStateCompat.ACTION_PLAY |
                                PlaybackStateCompat.ACTION_PLAY_PAUSE);
        mMediaSession.setPlaybackState(mStateBuilder.build());

        // MySessionCallback() has methods that handle callbacks from a media controller
        mMediaSession.setCallback(new MySessionCallback());

        // Set the session's token so that client activities can communicate with it.
        setSessionToken(mMediaSession.getSessionToken());
        
        // MediaSession to active.
        mMediaSession.setActive(true);
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        MediaButtonReceiver.handleIntent(mMediaSession, intent);

        return START_NOT_STICKY;
    }
}

After

こんな感じでPlaybackStateCompat.BuilderMySessionCallbackがいらなくなる

public class MediaPlaybackService extends MediaBrowserServiceCompat {
    private static final String MY_MEDIA_ROOT_ID = "media_root_id";
    private static final String MY_EMPTY_MEDIA_ROOT_ID = "empty_root_id";

    private MediaSessionCompat mMediaSession;
    private PlaybackStateCompat.Builder mStateBuilder;
    private SimpleExoPlayer mPlayer;

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

        mPlayer = ExoPlayerFactory.newSimpleInstance(this, new DefaultTrackSelector());

        setBroadcastReceiver();
        mAudioPlayer = new AudioPlayer(this);
        mAudioPlayerNotification = new AudioPlayerNotification(this);

        // Create a MediaSessionCompat
        mMediaSession = new MediaSessionCompat(this, LOG_TAG);

        // Enable callbacks from MediaButtons and TransportControls
        mMediaSession.setFlags(
                MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
                MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);

        // Set the session's token so that client activities can communicate with it.
        setSessionToken(mMediaSession.getSessionToken());

        // Used MediaSession extension
        MediaSessionConnector mediaSessionConnector = new MediaSessionConnector(mMediaSession);
        mediaSessionConnector.setPlayer(mPlayer, null);
        
        // MediaSession to active.
        mMediaSession.setActive(true);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        MediaButtonReceiver.handleIntent(mMediaSession, intent);

        return START_NOT_STICKY;
    }
}

補足

再生/一時停止再生一時停止秒送り をしたいときは、PlaybackControllerを自前で実装して、

mediaSessionConnector = MediaSessionConnector(MediaSessionCompat mediaSession,PlaybackController playbackController)

すればよさそう

曲送りやら、ランダム再生やらをしたいときは、QueueNavigatorを実装して

mediaSessionConnector.setQueueNavigator(QueueNavigator queueNavigator)

とすればよさそう

おわりに

ExoPlayerのドキュメント、超読みにくかったり、欲しい情報どこにあるのか謎な問題、あるとおもいます