Update MediaSession metadata for car Bluetooth display (#1008)

* Update MediaSession metadata for car Bluetooth display

* Implement `upMediaMetadata` in `BaseReadAloudService` to sync book details and cover art to `MediaSessionCompat`.
* Map book name to title, chapter name to artist, and author to album metadata keys.
* Support displaying current reading content as a subtitle/lyric string.
* Trigger metadata updates across `HttpReadAloudService` and `TTSReadAloudService` during playback and navigation.

* Apply suggestions from code review

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

---------

Co-authored-by: zuohl <zuohldev@gmail.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
zuohl
2026-05-10 04:39:21 +08:00
committed by GitHub
co-authored by gemini-code-assist[bot] zuohl
parent 64f7de8120
commit f4ba9eeee0
3 changed files with 27 additions and 0 deletions
@@ -14,6 +14,7 @@ import android.media.AudioManager
import android.net.wifi.WifiManager
import android.os.Bundle
import android.os.PowerManager
import android.support.v4.media.MediaMetadataCompat
import android.support.v4.media.session.MediaSessionCompat
import android.support.v4.media.session.PlaybackStateCompat
import android.telephony.PhoneStateListener
@@ -162,6 +163,7 @@ abstract class BaseReadAloudService : BaseService(),
}.onSuccess {
if (it.width > 16 && it.height > 16) {
cover = it
upMediaMetadata()
upReadAloudNotification()
}
}
@@ -265,6 +267,7 @@ abstract class BaseReadAloudService : BaseService(),
}
paragraphStartPos = pos
launch(Main) {
upMediaMetadata()
if (play) play() else pageChanged = true
}
}.onError {
@@ -345,6 +348,7 @@ abstract class BaseReadAloudService : BaseService(),
}
}
upTtsProgress(readAloudNumber + 1)
upMediaMetadata(showContent = true)
play()
} else {
toLast = true
@@ -371,6 +375,7 @@ abstract class BaseReadAloudService : BaseService(),
}
}
upTtsProgress(readAloudNumber + 1)
upMediaMetadata(showContent = true)
play()
} else {
nextChapter()
@@ -462,6 +467,26 @@ abstract class BaseReadAloudService : BaseService(),
)
}
/**
* 更新媒体元数据, 用于车机蓝牙显示
* @param showContent 是否显示当前朗读内容作为歌词
*/
internal fun upMediaMetadata(showContent: Boolean = false) {
val currentContent = if (showContent && nowSpeak in contentList.indices) {
contentList[nowSpeak]
} else {
null
}
val metadata = MediaMetadataCompat.Builder()
.putBitmap(MediaMetadataCompat.METADATA_KEY_ART, cover)
.putText(MediaMetadataCompat.METADATA_KEY_TITLE, ReadBook.book?.name ?: "")
.putText(MediaMetadataCompat.METADATA_KEY_ARTIST, textChapter?.title ?: "")
.putText(MediaMetadataCompat.METADATA_KEY_ALBUM, ReadBook.book?.author ?: "")
.putText(MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, currentContent ?: "")
.build()
mediaSessionCompat.setMetadata(metadata)
}
/**
* 初始化MediaSession, 注册多媒体按钮
*/
@@ -626,6 +626,7 @@ class HttpReadAloudService : BaseReadAloudService(),
}
updateNextPos()
upPlayPos()
upMediaMetadata(showContent = true)
}
override fun onPlayerError(error: PlaybackException) {
@@ -202,6 +202,7 @@ class TTSReadAloudService : BaseReadAloudService(), TextToSpeech.OnInitListener
ReadBook.moveToNextPage()
}
upTtsProgress(readAloudNumber + 1)
upMediaMetadata(showContent = true)
}
}