Skip to content

Commit

Permalink
fix(audio focus): fix audio focus for 2nd and sebsequent playback
Browse files Browse the repository at this point in the history
  • Loading branch information
abdallahmehiz committed Jul 15, 2024
1 parent a58e414 commit cbf166c
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 15 deletions.
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ dependencies {
implementation(libs.androidx.compose.animation.graphics)
implementation(libs.material)
implementation(libs.androidx.preferences.ktx)
implementation(libs.mediasession)

implementation(libs.aniyomi.mpv.lib)
implementation(libs.aniyomi.ffmpeg.kit)
Expand Down
66 changes: 52 additions & 14 deletions app/src/main/java/live/mehiz/mpvkt/ui/player/PlayerActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat
import androidx.documentfile.provider.DocumentFile
import androidx.media.AudioAttributesCompat
import androidx.media.AudioFocusRequestCompat
import androidx.media.AudioManagerCompat
import `is`.xyz.mpv.MPVLib
import `is`.xyz.mpv.Utils
import kotlinx.coroutines.CoroutineScope
Expand All @@ -37,7 +40,7 @@ import java.io.File
class PlayerActivity : AppCompatActivity() {

private val viewModel: PlayerViewModel by lazy { PlayerViewModel(this) }
private val binding by lazy { PlayerLayoutBinding.inflate(this.layoutInflater) }
private val binding by lazy { PlayerLayoutBinding.inflate(layoutInflater) }
private val mpvKtDatabase: MpvKtDatabase by inject()
val player by lazy { binding.player }
val windowInsetsController by lazy { WindowCompat.getInsetsController(window, window.decorView) }
Expand All @@ -50,6 +53,7 @@ class PlayerActivity : AppCompatActivity() {

private lateinit var fileName: String

private var audioFocusRequest: AudioFocusRequestCompat? = null
private var restoreAudioFocus: () -> Unit = {}

override fun onCreate(savedInstanceState: Bundle?) {
Expand Down Expand Up @@ -80,15 +84,17 @@ class PlayerActivity : AppCompatActivity() {
}

override fun onDestroy() {
audioManager.abandonAudioFocus(audioFocusChangeListener)
audioFocusRequest?.let {
AudioManagerCompat.abandonAudioFocusRequest(audioManager, it)
}
audioFocusRequest = null
MPVLib.destroy()
super.onDestroy()
}

override fun onPause() {
super.onPause()
if (viewModel.paused.value) return
viewModel.pauseUnpause()
viewModel.pause()
}

private fun setupMPV() {
Expand Down Expand Up @@ -129,6 +135,23 @@ class PlayerActivity : AppCompatActivity() {

private fun setupAudio() {
MPVLib.setPropertyString("alang", audioPreferences.preferredLanguages.get())

val request = AudioFocusRequestCompat
.Builder(AudioManagerCompat.AUDIOFOCUS_GAIN)
.also {
it.setAudioAttributes(
AudioAttributesCompat
.Builder()
.setUsage(AudioAttributesCompat.USAGE_MEDIA)
.setContentType(AudioAttributesCompat.CONTENT_TYPE_MUSIC)
.build(),
)
it.setOnAudioFocusChangeListener(audioFocusChangeListener)
}.build()
AudioManagerCompat.requestAudioFocus(audioManager, request).let {
if (it == AudioManager.AUDIOFOCUS_REQUEST_FAILED) return@let
audioFocusRequest = request
}
}

private fun setupSubtitles() {
Expand Down Expand Up @@ -164,16 +187,22 @@ class PlayerActivity : AppCompatActivity() {
if (!wasPlayerPaused) viewModel.unpause()
}
}

AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> {
MPVLib.command(arrayOf("multiply", "volume", "0.5"))
restoreAudioFocus = {
MPVLib.command(arrayOf("multiply", "volume", "2"))
}
}

AudioManager.AUDIOFOCUS_GAIN -> {
restoreAudioFocus()
restoreAudioFocus = {}
}

AudioManager.AUDIOFOCUS_REQUEST_FAILED -> {
Log.d("PlayerActivity", "didn't get audio focus")
}
}
}

Expand Down Expand Up @@ -251,6 +280,10 @@ class PlayerActivity : AppCompatActivity() {

internal fun onObserverEvent(property: String, value: Boolean) {
when (property) {
"pause" -> {
if (value) viewModel.pause()
}

"paused-for-cache" -> {
viewModel.isLoading.update { value }
}
Expand All @@ -262,7 +295,8 @@ class PlayerActivity : AppCompatActivity() {
}

@Suppress("EmptyFunctionBlock", "UnusedParameter")
internal fun onObserverEvent(property: String, value: String) {}
internal fun onObserverEvent(property: String, value: String) {
}

internal fun event(eventId: Int) {
when (eventId) {
Expand All @@ -281,11 +315,6 @@ class PlayerActivity : AppCompatActivity() {
viewModel.loadChapters()
viewModel.loadTracks()
viewModel.getDecoder()
audioManager.requestAudioFocus(
audioFocusChangeListener,
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN
)
}

MPVLib.mpvEventId.MPV_EVENT_SEEK -> {
Expand Down Expand Up @@ -341,7 +370,8 @@ class PlayerActivity : AppCompatActivity() {
}

@Suppress("EmptyFunctionBlock", "UnusedParameter")
internal fun efEvent(err: String?) {}
internal fun efEvent(err: String?) {
}

private fun setOrientation() {
this.requestedOrientation = when (playerPreferences.orientation.get()) {
Expand All @@ -363,9 +393,17 @@ class PlayerActivity : AppCompatActivity() {

override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
when (keyCode) {
KeyEvent.KEYCODE_VOLUME_UP -> { viewModel.changeVolumeBy(1) }
KeyEvent.KEYCODE_VOLUME_DOWN -> { viewModel.changeVolumeBy(-1) }
else -> { super.onKeyDown(keyCode, event) }
KeyEvent.KEYCODE_VOLUME_UP -> {
viewModel.changeVolumeBy(1)
}

KeyEvent.KEYCODE_VOLUME_DOWN -> {
viewModel.changeVolumeBy(-1)
}

else -> {
super.onKeyDown(keyCode, event)
}
}
return true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,12 @@ class PlayerControls(private val viewModel: PlayerViewModel) {
val brightness by viewModel.currentBrightness.collectAsState()
val volume by viewModel.currentVolume.collectAsState()

LaunchedEffect(volume, brightness) {
LaunchedEffect(volume) {
delay(1000)
if (isVolumeSliderShown) viewModel.isVolumeSliderShown.update { false }
}
LaunchedEffect(brightness) {
delay(1000)
if (isBrightnessSliderShown) viewModel.isBrightnessSliderShown.update { false }
}
AnimatedVisibility(
Expand Down
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ androidx-compose-constraintlayout = { group = "androidx.constraintlayout", name
androidx-documentfile = { group = "androidx.documentfile", name = "documentfile", version = "1.0.1" }
androidx-compose-animation-graphics = { group = "androidx.compose.animation", name = "animation-graphics-android" }
androidx-preferences-ktx = { group = "androidx.preference", name = "preference-ktx", version = "1.2.1" }
mediasession = "androidx.media:media:1.7.0"

aniyomi-mpv-lib = { module = "com.github.aniyomiorg:aniyomi-mpv-lib", version = "1.15.n" }
aniyomi-ffmpeg-kit = { module = "com.github.jmir1:ffmpeg-kit", version = "1.15" }
Expand Down

0 comments on commit cbf166c

Please sign in to comment.