Skip to content

Commit

Permalink
feat: Added support for control with bluetooth pause/play buttons (#118)
Browse files Browse the repository at this point in the history
* Added support for control with bluetooth pause/play buttons

* Added a settings item to disable MediaSession control (default:ON)

* Added noisy receiver to catch audio sudden change
  • Loading branch information
Anthonyy232 authored Oct 17, 2024
1 parent 560c544 commit 16bc363
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,6 @@ class PlayerPreferences(

val allowGesturesInPanels = preferenceStore.getBoolean("allow_gestures_in_panels")
val showSystemStatusBar = preferenceStore.getBoolean("show_system_status_bar")

val allowHeadsetControl = preferenceStore.getBoolean("allow_headset_control", true)
}
60 changes: 60 additions & 0 deletions app/src/main/java/live/mehiz/mpvkt/ui/player/PlayerActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import android.content.pm.ActivityInfo
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.media.AudioManager
import android.media.session.MediaSession
import android.media.session.PlaybackState
import android.net.Uri
import android.os.Build
import android.os.Bundle
Expand Down Expand Up @@ -68,6 +70,7 @@ class PlayerActivity : AppCompatActivity() {
val player by lazy { binding.player }
val windowInsetsController by lazy { WindowCompat.getInsetsController(window, window.decorView) }
val audioManager by lazy { getSystemService(Context.AUDIO_SERVICE) as AudioManager }
private var mediaSession: MediaSession? = null
private val playerPreferences: PlayerPreferences by inject()
private val audioPreferences: AudioPreferences by inject()
private val subtitlesPreferences: SubtitlesPreferences by inject()
Expand All @@ -89,13 +92,24 @@ class PlayerActivity : AppCompatActivity() {
}
private var pipReceiver: BroadcastReceiver? = null

private val noisyReceiver = object : BroadcastReceiver() {
var initialized = false
override fun onReceive(context: Context?, intent: Intent?) {
if (intent?.action == AudioManager.ACTION_AUDIO_BECOMING_NOISY) {
viewModel.pause()
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
}
}

override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState)
setContentView(binding.root)

setupMPV()
setupAudio()
setupMediaSession()
getPlayableUri(intent)?.let { player.playFile(it) }
setIntentExtras(intent.extras)
setOrientation()
Expand Down Expand Up @@ -123,6 +137,11 @@ class PlayerActivity : AppCompatActivity() {
AudioManagerCompat.abandonAudioFocusRequest(audioManager, it)
}
audioFocusRequest = null
mediaSession?.release()
if (noisyReceiver.initialized) {
unregisterReceiver(noisyReceiver)
noisyReceiver.initialized = false
}

unloadKoinModules(viewModelModule)
MPVLib.removeObserver(playerObserver)
Expand Down Expand Up @@ -663,6 +682,47 @@ class PlayerActivity : AppCompatActivity() {
if (player.onKey(event!!)) return true
return super.onKeyUp(keyCode, event)
}

private fun setupMediaSession() {
val allowHeadsetControl = playerPreferences.allowHeadsetControl.get()
if (allowHeadsetControl) {
mediaSession = MediaSession(this, "PlayerActivity").apply {
setCallback(object : MediaSession.Callback() {
override fun onPlay() {
super.onPlay()
viewModel.unpause()
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}

override fun onPause() {
super.onPause()
viewModel.pause()
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}

override fun onStop() {
super.onStop()
isActive = false
this@PlayerActivity.onStop()
}
})
setPlaybackState(
PlaybackState.Builder()
.setActions(
PlaybackState.ACTION_PLAY or
PlaybackState.ACTION_PAUSE or
PlaybackState.ACTION_STOP
)
.build()
)
isActive = true
}

val filter = IntentFilter().apply { addAction(AudioManager.ACTION_AUDIO_BECOMING_NOISY) }
registerReceiver(noisyReceiver, filter)
noisyReceiver.initialized = true
}
}
}

const val TAG = "mpvKt"
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,12 @@ object PlayerPreferencesScreen : Screen() {
onValueChange = preferences.showSystemStatusBar::set,
title = { Text(stringResource(R.string.pref_player_controls_show_status_bar)) },
)
val allowHeadsetControl by preferences.allowHeadsetControl.collectAsState()
SwitchPreference(
value = allowHeadsetControl,
onValueChange = preferences.allowHeadsetControl::set,
title = { Text(stringResource(R.string.control_player_with_media_buttons)) },
)
}
}
}
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@
<string name="value_percentage_float" translatable="false">%.2f\%%</string>

<string name="github_repo_url" translatable="false">https://github.com/abdallahmehiz/mpvKt</string>
<string name="control_player_with_media_buttons">Control player with media buttons</string>
<string name="swap_the_volume_and_brightness_slider">Swap volume and brightness slider</string>

<plurals name="plural_items">
Expand Down

0 comments on commit 16bc363

Please sign in to comment.