From 75901f858cc4cdf2798165625ec1da42f0c681ff Mon Sep 17 00:00:00 2001 From: ghhccghk <2137610394@qq.com> Date: Sun, 21 Jun 2026 21:03:52 +0800 Subject: [PATCH 1/5] feat: integrate SuperLyric API for enhanced lyric synchronization and translation support --- app/build.gradle.kts | 2 + .../neriplayer/core/lyricon/LyriconManager.kt | 90 +++++++++++++++++++ .../core/player/AudioPlayerService.kt | 8 +- .../data/settings/AutoSettingsSchema.kt | 4 +- app/src/main/res/values-en/strings.xml | 4 +- app/src/main/res/values/strings.xml | 4 +- gradle/libs.versions.toml | 2 + 7 files changed, 105 insertions(+), 9 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 7521d14d..aca9bba2 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -270,4 +270,6 @@ dependencies { // 取主题色 implementation(libs.androidx.palette.ktx) + + implementation(libs.superlyricapi) } diff --git a/app/src/main/java/moe/ouom/neriplayer/core/lyricon/LyriconManager.kt b/app/src/main/java/moe/ouom/neriplayer/core/lyricon/LyriconManager.kt index 8e2d4f86..cab94c05 100644 --- a/app/src/main/java/moe/ouom/neriplayer/core/lyricon/LyriconManager.kt +++ b/app/src/main/java/moe/ouom/neriplayer/core/lyricon/LyriconManager.kt @@ -1,6 +1,10 @@ package moe.ouom.neriplayer.core.lyricon import android.content.Context +import com.hchen.superlyricapi.SuperLyricData +import com.hchen.superlyricapi.SuperLyricHelper +import com.hchen.superlyricapi.SuperLyricLine +import com.hchen.superlyricapi.SuperLyricWord import io.github.proify.lyricon.provider.LyriconFactory import io.github.proify.lyricon.provider.LyriconProvider import io.github.proify.lyricon.lyric.model.LyricWord @@ -10,15 +14,21 @@ import io.github.proify.lyricon.provider.service.addConnectionListener import moe.ouom.neriplayer.ui.component.LyricEntry import moe.ouom.neriplayer.ui.viewmodel.playlist.SongItem import moe.ouom.neriplayer.util.NPLogger +import kotlin.collections.getOrNull object LyriconManager { private var provider: LyriconProvider? = null @Volatile private var enabled: Boolean = false + private var lastLyricIndex: Int = -1 + private var lyrics : List? = null + private var translatedLyrics :List? = null + private var currentSong: SongItem? = null fun initialize(context: Context) { if (provider != null) return try { + if (SuperLyricHelper.isAvailable()) { SuperLyricHelper.registerPublisher(); } provider = LyriconFactory.createProvider(context) provider?.register() @@ -28,6 +38,7 @@ object LyriconManager { onDisconnected { NPLogger.d("LyriconManager", "Disconnected") } onConnectTimeout { NPLogger.d("LyriconManager", "ConnectTimeout") } } + } catch (e: Exception) { NPLogger.e("LyriconManager", "Failed to initialize LyriconProvider", e) } @@ -55,6 +66,7 @@ object LyriconManager { if (!enabled) return try { provider?.player?.setPosition(positionMs) + updateSuperLyric(positionMs) } catch (e: Exception) { // NPLogger.e("LyriconManager", "setPosition failed", e) } @@ -64,6 +76,9 @@ object LyriconManager { if (!enabled) return try { val translationToleranceMs = 1_500L + LyriconManager.lyrics = lyrics + LyriconManager.translatedLyrics = translatedLyrics + currentSong = song val lyriconLyrics = lyrics?.map { entry -> val words = if (entry.words != null) { var currentIndex = 0 @@ -110,4 +125,79 @@ object LyriconManager { NPLogger.e("LyriconManager", "updateSong failed", e) } } + + + private fun updateSuperLyric(positionMs: Long) { + + try { + if (!SuperLyricHelper.isAvailable()) return + + val lyricList = lyrics ?: return + val song = currentSong ?: return + + val index = lyricList.indexOfLast { + it.startTimeMs <= positionMs + } + + // 没有匹配歌词 + if (index < 0) return + + // 避免重复发送 + if (index == lastLyricIndex) return + + lastLyricIndex = index + + val line = lyricList.getOrNull(index) ?: return + + + val translation = translatedLyrics + ?.firstOrNull { + kotlin.math.abs( + it.startTimeMs - line.startTimeMs + ) <= 1500 + } + + var currentIndex = 0 + val words = line.words + ?.mapNotNull { wordTiming -> + if (currentIndex + wordTiming.charCount <= line.text.length) { + val wordText = + line.text.substring(currentIndex, currentIndex + wordTiming.charCount) + currentIndex += wordTiming.charCount + SuperLyricWord( + wordText, + wordTiming.startTimeMs, + wordTiming.endTimeMs + ) + } else { + null + } + } + ?: emptyList() + + + val data = SuperLyricData() + .setTitle(song.name) + .setArtist(song.artist) + .setAlbum(song.album) + .setLyric( + SuperLyricLine( + line.text, + words.toTypedArray(), + line.startTimeMs, + line.endTimeMs + ) + ) + .setTranslation( + SuperLyricLine( + translation?.text ?: "" + ) + ) + + + SuperLyricHelper.sendLyric(data) + } catch (e: Exception) { + NPLogger.e("LyriconManager", "updateSuperLyric failed", e) + } + } } diff --git a/app/src/main/java/moe/ouom/neriplayer/core/player/AudioPlayerService.kt b/app/src/main/java/moe/ouom/neriplayer/core/player/AudioPlayerService.kt index 273482fe..876f99ab 100644 --- a/app/src/main/java/moe/ouom/neriplayer/core/player/AudioPlayerService.kt +++ b/app/src/main/java/moe/ouom/neriplayer/core/player/AudioPlayerService.kt @@ -906,9 +906,6 @@ class AudioPlayerService : Service() { ) .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, duration) .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, currentLargeIcon) - .putBitmap(MediaMetadataCompat.METADATA_KEY_ART, currentLargeIcon) - .putBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, currentLargeIcon) - // Do not set local URIs to METADATA_KEY_ALBUM_ART_URI, as it may prompt the System UI // to attempt loading them directly (which can fail due to permission issues) and // override the bitmap we already provided via METADATA_KEY_ALBUM_ART @@ -1010,6 +1007,11 @@ class AudioPlayerService : Service() { updateNotification() } } + + NPLogger.d( + "NERI-APS", + "cover bitmap=${bmp.width}x${bmp.height}, bytes=${bmp.byteCount / 1024 / 1024}MB" + ) } catch (e: Exception) { NPLogger.d("NERI-APS", "Cover load failed: ${e.message}") } diff --git a/app/src/main/java/moe/ouom/neriplayer/data/settings/AutoSettingsSchema.kt b/app/src/main/java/moe/ouom/neriplayer/data/settings/AutoSettingsSchema.kt index f9175369..50c5bd2d 100644 --- a/app/src/main/java/moe/ouom/neriplayer/data/settings/AutoSettingsSchema.kt +++ b/app/src/main/java/moe/ouom/neriplayer/data/settings/AutoSettingsSchema.kt @@ -655,8 +655,8 @@ object AutoSettingsSchema { ui = SettingUiType.Switch ) val lyriconEnabled = autoSetting( - titleRes = R.string.settings_lyricon_enabled, - descriptionRes = R.string.settings_lyricon_enabled_desc, + titleRes = R.string.settings_lyric_api_enabled, + descriptionRes = R.string.settings_lyric_api_enabled_desc, iconRes = R.drawable.ic_lyricon ) diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml index 6c2b9161..9574bc20 100644 --- a/app/src/main/res/values-en/strings.xml +++ b/app/src/main/res/values-en/strings.xml @@ -967,8 +967,8 @@ Collapse Motion Settings Customize motion effects - Lyricon Integration - Provide Lyricon with the current song, playback state, position, word-level lyrics, and translations + Lyricon Integration + Provide Lyricon with the current song, playback state, position, word-level lyrics, and translations External Bluetooth Lyrics When a Bluetooth device is connected, sync the current lyric line to the device song info area Lyrics Settings diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0e225e0d..7ae00cdc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -967,8 +967,8 @@ 收起 动效设置 展开以调整动效表现 - 词幕适配 - 向 Lyricon 提供当前歌曲、播放状态、进度、逐字歌词和翻译 + 第三方歌词API适配 + 向 Lyricon & SuperLyric 提供当前歌曲、播放状态、进度、逐字歌词和翻译 外接设备蓝牙歌词 连接蓝牙设备时,将当前歌词行同步到外接设备的歌曲信息区域 歌词设置 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c6e007d7..9e453daa 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -38,6 +38,7 @@ paletteKtx = "1.0.0" reorderable = "0.9.6" foundationLayout = "1.9.0" securityCrypto = "1.1.0" +superlyricapi = "3.4" taglib = "1.0.5" uiGraphics = "1.9.0" workRuntimeKtx = "2.11.0" @@ -60,6 +61,7 @@ androidx-media3-exoplayer = { module = "androidx.media3:media3-exoplayer", versi androidx-media3-exoplayer-hls = { module = "androidx.media3:media3-exoplayer-hls", version.ref = "media3ExoplayerHls" } androidx-palette-ktx = { module = "androidx.palette:palette-ktx", version.ref = "paletteKtx" } androidx-security-crypto = { module = "androidx.security:security-crypto", version.ref = "securityCrypto" } +superlyricapi = { module = "com.github.HChenX:SuperLyricApi", version.ref = "superlyricapi" } taglib = { module = "io.github.kyant0:taglib", version.ref = "taglib" } androidx-ui-graphics = { module = "androidx.compose.ui:ui-graphics", version.ref = "uiGraphics" } androidx-work-runtime-ktx = { module = "androidx.work:work-runtime-ktx", version.ref = "workRuntimeKtx" } From ff009b8fa84aad04060ad0112d44efae9be8d9b0 Mon Sep 17 00:00:00 2001 From: ghhccghk <2137610394@qq.com> Date: Sun, 21 Jun 2026 21:09:50 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E5=9B=9E=E9=80=80=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E7=9A=84=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/moe/ouom/neriplayer/core/player/AudioPlayerService.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/java/moe/ouom/neriplayer/core/player/AudioPlayerService.kt b/app/src/main/java/moe/ouom/neriplayer/core/player/AudioPlayerService.kt index 876f99ab..0c5682bd 100644 --- a/app/src/main/java/moe/ouom/neriplayer/core/player/AudioPlayerService.kt +++ b/app/src/main/java/moe/ouom/neriplayer/core/player/AudioPlayerService.kt @@ -906,6 +906,9 @@ class AudioPlayerService : Service() { ) .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, duration) .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, currentLargeIcon) + .putBitmap(MediaMetadataCompat.METADATA_KEY_ART, currentLargeIcon) + .putBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, currentLargeIcon) + // Do not set local URIs to METADATA_KEY_ALBUM_ART_URI, as it may prompt the System UI // to attempt loading them directly (which can fail due to permission issues) and // override the bitmap we already provided via METADATA_KEY_ALBUM_ART From 2f60e4e95bb573e080ffbe5ab587c93ccb4978da Mon Sep 17 00:00:00 2001 From: ghhccghk <2137610394@qq.com> Date: Sun, 21 Jun 2026 23:34:26 +0800 Subject: [PATCH 3/5] feat: add status bar lyrics support for Meizu devices --- app/proguard-rules.pro | 3 +++ .../core/player/AudioPlayerService.kt | 21 +++++++++++++++++-- .../neriplayer/core/player/PlayerManager.kt | 1 + .../PlayerManagerLifecycleExtensions.kt | 5 +++++ .../data/settings/AutoSettingsSchema.kt | 13 ++++++++++++ .../data/settings/SettingsRepository.kt | 3 +++ app/src/main/res/values-en/strings.xml | 2 ++ app/src/main/res/values/strings.xml | 3 ++- .../settings/AutoSettingsGeneratedTest.kt | 4 ++++ 9 files changed, 52 insertions(+), 3 deletions(-) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index f656d2cc..7d04017a 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -110,3 +110,6 @@ -dontwarn java.beans.** -dontwarn javax.script.** -dontwarn org.mozilla.javascript.** + + +-keep class com.hchen.superlyricapi.* {*;} \ No newline at end of file diff --git a/app/src/main/java/moe/ouom/neriplayer/core/player/AudioPlayerService.kt b/app/src/main/java/moe/ouom/neriplayer/core/player/AudioPlayerService.kt index 0c5682bd..985bda07 100644 --- a/app/src/main/java/moe/ouom/neriplayer/core/player/AudioPlayerService.kt +++ b/app/src/main/java/moe/ouom/neriplayer/core/player/AudioPlayerService.kt @@ -73,6 +73,9 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import moe.ouom.neriplayer.R import moe.ouom.neriplayer.activity.MainActivity +import moe.ouom.neriplayer.core.player.PlayerManager.externalBluetoothLyricLineFlow +import moe.ouom.neriplayer.core.player.PlayerManager.externalBluetoothLyrics +import moe.ouom.neriplayer.core.player.PlayerManager.statusBarLyricsEnable import moe.ouom.neriplayer.core.player.metadata.resolveExternalBluetoothMetadataText import moe.ouom.neriplayer.core.player.metadata.shouldUseExternalBluetoothLyrics import moe.ouom.neriplayer.data.local.media.LocalSongSupport @@ -731,6 +734,10 @@ class AudioPlayerService : Service() { builder.addAction(R.drawable.round_skip_next_24, getString(R.string.player_next), nextIntent) builder.setContentTitle(song?.displayName() ?: "NeriPlayer") + //魅族状态栏歌词设置这个 + if (statusBarLyricsEnable) { + builder.setTicker(externalBluetoothLyricLineFlow.value.toString()) + } val timerState = PlayerManager.sleepTimerManager.timerState.value val contentText = if (timerState.isActive) { @@ -753,7 +760,17 @@ class AudioPlayerService : Service() { currentLargeIcon?.let { builder.setLargeIcon(it) } - return builder.build() + return builder.build().apply { + if (statusBarLyricsEnable) { + val FLAG_ALWAYS_SHOW_TICKER = 0x01000000 + val FLAG_ONLY_UPDATE_TICKER = 0x02000000 + // Keep the status bar lyrics scrolling + flags = flags.or(FLAG_ALWAYS_SHOW_TICKER) + // Only update the ticker (lyrics), and do not update other properties + flags = flags.or(FLAG_ONLY_UPDATE_TICKER) + } + } + } private fun buildBootstrapNotification(): Notification { @@ -801,7 +818,7 @@ class AudioPlayerService : Service() { updateNotification() } - /** 鏋勫缓鎸囧悜鏈?Service 鐨?PendingIntent */ + /** 构建指向本 Service 的 PendingIntent */ private fun servicePendingIntent(action: String, requestCode: Int): PendingIntent { return PendingIntent.getService( this, diff --git a/app/src/main/java/moe/ouom/neriplayer/core/player/PlayerManager.kt b/app/src/main/java/moe/ouom/neriplayer/core/player/PlayerManager.kt index 1dbc0b99..221d7373 100644 --- a/app/src/main/java/moe/ouom/neriplayer/core/player/PlayerManager.kt +++ b/app/src/main/java/moe/ouom/neriplayer/core/player/PlayerManager.kt @@ -187,6 +187,7 @@ object PlayerManager { internal var playbackCrossfadeOutDurationMs = DEFAULT_FADE_DURATION_MS internal var playbackSoundConfig = PlaybackSoundConfig() internal var lyriconEnabled = false + internal var statusBarLyricsEnable = false internal var externalBluetoothLyricsEnabled = false internal var cloudMusicLyricDefaultOffsetMs = DEFAULT_CLOUD_MUSIC_LYRIC_OFFSET_MS internal var qqMusicLyricDefaultOffsetMs = DEFAULT_QQ_MUSIC_LYRIC_OFFSET_MS diff --git a/app/src/main/java/moe/ouom/neriplayer/core/player/PlayerManagerLifecycleExtensions.kt b/app/src/main/java/moe/ouom/neriplayer/core/player/PlayerManagerLifecycleExtensions.kt index 170cb677..c20cf1a0 100644 --- a/app/src/main/java/moe/ouom/neriplayer/core/player/PlayerManagerLifecycleExtensions.kt +++ b/app/src/main/java/moe/ouom/neriplayer/core/player/PlayerManagerLifecycleExtensions.kt @@ -452,6 +452,11 @@ internal fun PlayerManager.initializeImpl( } } } + ioScope.launch { + settingsRepo.statusBarLyricsEnabledFlow.collect { enabled -> + statusBarLyricsEnable = enabled + } + } ioScope.launch { settingsRepo.externalBluetoothLyricsEnabledFlow.collect { enabled -> externalBluetoothLyricsEnabled = enabled diff --git a/app/src/main/java/moe/ouom/neriplayer/data/settings/AutoSettingsSchema.kt b/app/src/main/java/moe/ouom/neriplayer/data/settings/AutoSettingsSchema.kt index 50c5bd2d..093ab601 100644 --- a/app/src/main/java/moe/ouom/neriplayer/data/settings/AutoSettingsSchema.kt +++ b/app/src/main/java/moe/ouom/neriplayer/data/settings/AutoSettingsSchema.kt @@ -660,6 +660,19 @@ object AutoSettingsSchema { iconRes = R.drawable.ic_lyricon ) + @AutoSetting( + key = "status_bar_lyrics_enabled", + type = SettingValueType.Boolean, + defaultBoolean = false, + order = 13, + ui = SettingUiType.Switch + ) + val statusBarLyrics = autoSetting( + titleRes = R.string.settings_status_bar_lyrics_title, + descriptionRes = R.string.settings_status_bar_lyrics_summary, + iconRes = R.drawable.ic_lyricon + ) + @AutoSetting( key = "external_bluetooth_lyrics_enabled", type = SettingValueType.Boolean, diff --git a/app/src/main/java/moe/ouom/neriplayer/data/settings/SettingsRepository.kt b/app/src/main/java/moe/ouom/neriplayer/data/settings/SettingsRepository.kt index b4187b4f..2f02a014 100644 --- a/app/src/main/java/moe/ouom/neriplayer/data/settings/SettingsRepository.kt +++ b/app/src/main/java/moe/ouom/neriplayer/data/settings/SettingsRepository.kt @@ -138,6 +138,9 @@ class SettingsRepository(private val context: Context) { val lyriconEnabledFlow: Flow = autoSettingsRepository.lyriconEnabledFlow + val statusBarLyricsEnabledFlow : Flow = + autoSettingsRepository.statusBarLyricsFlow + val externalBluetoothLyricsEnabledFlow: Flow = autoSettingsRepository.externalBluetoothLyricsEnabledFlow diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml index 9574bc20..9d9f5a79 100644 --- a/app/src/main/res/values-en/strings.xml +++ b/app/src/main/res/values-en/strings.xml @@ -978,6 +978,8 @@ QQ Music default offset Default offset applied when loading QQ Music lyrics Current offset: %1$s ms + Status Bar Lyrics + Enable Meizu status bar lyrics (for select devices only) No Playback diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7ae00cdc..686e187c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -978,7 +978,8 @@ QQ 音乐默认歌词偏移 设置加载 QQ 音乐歌词时的基础偏移 当前偏移:%1$s ms - + 状态栏歌词 + 启用魅族状态栏歌词(仅适用于部分设备) 暂无播放 diff --git a/app/src/test/java/moe/ouom/neriplayer/data/settings/AutoSettingsGeneratedTest.kt b/app/src/test/java/moe/ouom/neriplayer/data/settings/AutoSettingsGeneratedTest.kt index 41b21f20..1a7ec0b8 100644 --- a/app/src/test/java/moe/ouom/neriplayer/data/settings/AutoSettingsGeneratedTest.kt +++ b/app/src/test/java/moe/ouom/neriplayer/data/settings/AutoSettingsGeneratedTest.kt @@ -191,6 +191,10 @@ class AutoSettingsGeneratedTest { R.drawable.ic_lyricon, AutoSettingsSchema.lyrics.lyriconEnabled.iconRes ) + assertEquals( + R.drawable.ic_lyricon, + AutoSettingsSchema.lyrics.statusBarLyrics.iconRes + ) assertEquals( AutoSettingIcon.BluetoothAudio, AutoSettingsSchema.lyrics.externalBluetoothLyricsEnabled.icon From 5cc8b1b3e44590bd4b430c7adc6378374fd21d44 Mon Sep 17 00:00:00 2001 From: ghhccghk <2137610394@qq.com> Date: Mon, 22 Jun 2026 21:58:50 +0800 Subject: [PATCH 4/5] feat: update ProGuard rules to prevent compilation and runtime errors --- app/proguard-rules.pro | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 7d04017a..6e67bf0a 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -111,5 +111,9 @@ -dontwarn javax.script.** -dontwarn org.mozilla.javascript.** +# 防止编译及运行错误 +-keep class com.hchen.superlyricapi.** { *;} +-dontwarn android.os.ServiceManager --keep class com.hchen.superlyricapi.* {*;} \ No newline at end of file +# 避免 kotlin.reflect 内部反射崩溃 +-keepattributes *Annotation* \ No newline at end of file From 55a1fd964ea0bb48ef005f40b7a494df421c40d7 Mon Sep 17 00:00:00 2001 From: ghhccghk <2137610394@qq.com> Date: Mon, 22 Jun 2026 22:31:15 +0800 Subject: [PATCH 5/5] =?UTF-8?q?fix=EF=BC=9A=E4=BF=AE=E5=A4=8D=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E6=A0=8F=E6=AD=8C=E8=AF=8D=E6=97=A0=E6=B3=95=E6=AD=A3?= =?UTF-8?q?=E5=B8=B8=E6=9B=B4=E6=96=B0=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../neriplayer/core/player/AudioPlayerService.kt | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/moe/ouom/neriplayer/core/player/AudioPlayerService.kt b/app/src/main/java/moe/ouom/neriplayer/core/player/AudioPlayerService.kt index 985bda07..5cfa5500 100644 --- a/app/src/main/java/moe/ouom/neriplayer/core/player/AudioPlayerService.kt +++ b/app/src/main/java/moe/ouom/neriplayer/core/player/AudioPlayerService.kt @@ -68,7 +68,10 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.filterNotNull +import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import moe.ouom.neriplayer.R @@ -516,6 +519,13 @@ class AudioPlayerService : Service() { } } + externalBluetoothLyricLineFlow + .filterNotNull() + .onEach { lyric -> + if (statusBarLyricsEnable && PlayerManager.handleAudioBecomingNoisy()) { updateNotification() } + } + .launchIn(serviceScope) + becomingNoisyReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { if (intent.action == AudioManager.ACTION_AUDIO_BECOMING_NOISY) { @@ -736,7 +746,9 @@ class AudioPlayerService : Service() { builder.setContentTitle(song?.displayName() ?: "NeriPlayer") //魅族状态栏歌词设置这个 if (statusBarLyricsEnable) { - builder.setTicker(externalBluetoothLyricLineFlow.value.toString()) + if (externalBluetoothLyricLineFlow.value != "" && externalBluetoothLyricLineFlow.value != null && externalBluetoothLyricLineFlow.value != "null") { + builder.setTicker(externalBluetoothLyricLineFlow.value.toString()) + } } val timerState = PlayerManager.sleepTimerManager.timerState.value