Antoine POPINEAU
4 years ago
5 changed files with 140 additions and 82 deletions
@ -0,0 +1,103 @@ |
|||||||
|
package com.github.apognu.otter.playback |
||||||
|
|
||||||
|
import android.content.Context |
||||||
|
import android.content.Intent |
||||||
|
import android.os.Bundle |
||||||
|
import android.os.ResultReceiver |
||||||
|
import android.support.v4.media.session.MediaSessionCompat |
||||||
|
import android.support.v4.media.session.PlaybackStateCompat |
||||||
|
import android.view.KeyEvent |
||||||
|
import com.github.apognu.otter.Otter |
||||||
|
import com.github.apognu.otter.utils.Command |
||||||
|
import com.github.apognu.otter.utils.CommandBus |
||||||
|
import com.google.android.exoplayer2.ControlDispatcher |
||||||
|
import com.google.android.exoplayer2.Player |
||||||
|
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector |
||||||
|
|
||||||
|
class MediaSession(private val context: Context) { |
||||||
|
var active: Boolean = false |
||||||
|
|
||||||
|
private val playbackStateBuilder = PlaybackStateCompat.Builder().apply { |
||||||
|
setActions( |
||||||
|
PlaybackStateCompat.ACTION_PLAY_PAUSE or |
||||||
|
PlaybackStateCompat.ACTION_PLAY or |
||||||
|
PlaybackStateCompat.ACTION_PAUSE or |
||||||
|
PlaybackStateCompat.ACTION_SKIP_TO_NEXT or |
||||||
|
PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS or |
||||||
|
PlaybackStateCompat.ACTION_SEEK_TO or |
||||||
|
PlaybackStateCompat.ACTION_SKIP_TO_QUEUE_ITEM |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
val session: MediaSessionCompat by lazy { |
||||||
|
active = true |
||||||
|
|
||||||
|
MediaSessionCompat(context, context.packageName).apply { |
||||||
|
setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS or MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS) |
||||||
|
setPlaybackState(playbackStateBuilder.build()) |
||||||
|
|
||||||
|
isActive = true |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val connector: MediaSessionConnector by lazy { |
||||||
|
MediaSessionConnector(Otter.get().mediaSession.session).also { |
||||||
|
it.setQueueNavigator(OtterQueueNavigator()) |
||||||
|
|
||||||
|
it.setMediaButtonEventHandler { _, _, event -> |
||||||
|
if (!active) { |
||||||
|
event.extras?.getParcelable<KeyEvent>(Intent.EXTRA_KEY_EVENT)?.let { key -> |
||||||
|
if (key.action == KeyEvent.ACTION_UP) { |
||||||
|
val command = when (key.keyCode) { |
||||||
|
KeyEvent.KEYCODE_MEDIA_PLAY -> Command.ToggleState |
||||||
|
KeyEvent.KEYCODE_MEDIA_PAUSE -> Command.ToggleState |
||||||
|
KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE -> Command.ToggleState |
||||||
|
KeyEvent.KEYCODE_MEDIA_NEXT -> Command.NextTrack |
||||||
|
KeyEvent.KEYCODE_MEDIA_PREVIOUS -> Command.PreviousTrack |
||||||
|
else -> null |
||||||
|
} |
||||||
|
|
||||||
|
command?.let { |
||||||
|
CommandBus.send(command) |
||||||
|
CommandBus.send(Command.StartService(command)) |
||||||
|
|
||||||
|
return@setMediaButtonEventHandler true |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
false |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class OtterQueueNavigator : MediaSessionConnector.QueueNavigator { |
||||||
|
override fun onSkipToQueueItem(player: Player, controlDispatcher: ControlDispatcher, id: Long) { |
||||||
|
CommandBus.send(Command.PlayTrack(id.toInt())) |
||||||
|
} |
||||||
|
|
||||||
|
override fun onCurrentWindowIndexChanged(player: Player) {} |
||||||
|
|
||||||
|
override fun onCommand(player: Player, controlDispatcher: ControlDispatcher, command: String, extras: Bundle?, cb: ResultReceiver?) = true |
||||||
|
|
||||||
|
override fun getSupportedQueueNavigatorActions(player: Player): Long { |
||||||
|
return PlaybackStateCompat.ACTION_PLAY_PAUSE or |
||||||
|
PlaybackStateCompat.ACTION_SKIP_TO_NEXT or |
||||||
|
PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS or |
||||||
|
PlaybackStateCompat.ACTION_SKIP_TO_QUEUE_ITEM |
||||||
|
} |
||||||
|
|
||||||
|
override fun onSkipToNext(player: Player, controlDispatcher: ControlDispatcher) { |
||||||
|
CommandBus.send(Command.NextTrack) |
||||||
|
} |
||||||
|
|
||||||
|
override fun getActiveQueueItemId(player: Player?) = 0L |
||||||
|
|
||||||
|
override fun onSkipToPrevious(player: Player, controlDispatcher: ControlDispatcher) { |
||||||
|
CommandBus.send(Command.PreviousTrack) |
||||||
|
} |
||||||
|
|
||||||
|
override fun onTimelineChanged(player: Player) {} |
||||||
|
} |
Loading…
Reference in new issue