Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ dependencies {
implementation(libs.slf4j)
implementation(libs.timber)
implementation(libs.tinypinyin)
implementation(libs.superlyricapi)

debugImplementation(libs.leakcanary)

Expand Down
6 changes: 4 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android">
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
Expand Down Expand Up @@ -31,6 +31,8 @@
</intent>
</queries>

<uses-sdk tools:overrideLibrary="com.hchen.superlyricapi" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/java/remix/myplayer/data/prefs/LyricPrefs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class LyricPrefs @Inject constructor(

var desktopLyricEnabled by PrefsDelegate(sp, KEY_DESKTOP_LYRIC_ENABLED, false)
var statusBarLyricEnabled by PrefsDelegate(sp, KEY_STATUS_BAR_LYRIC_ENABLED, false)
var superLyricApiEnabled by PrefsDelegate(sp, KEY_SUPER_LYRIC_API_ENABLED, false)

var fontScale by PrefsDelegate(sp, KEY_LYRIC_FONT_SCALE, 1.0f)

Expand Down Expand Up @@ -66,6 +67,9 @@ class LyricPrefs @Inject constructor(
// StatusBar
const val KEY_STATUS_BAR_LYRIC_ENABLED: String = "status_bar_lyric_enabled"

// SuperLyricApi
const val KEY_SUPER_LYRIC_API_ENABLED: String = "super_lyric_api_enabled"

// Desktop
const val KEY_DESKTOP_LYRIC_ENABLED: String = "desktop_lyric_enabled"
const val KEY_DESKTOP_LYRIC_LOCKED: String = "desktop_lyric_locked"
Expand Down
101 changes: 98 additions & 3 deletions app/src/main/java/remix/myplayer/lyric/LyricManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ import androidx.savedstate.SavedStateRegistry
import androidx.savedstate.SavedStateRegistryController
import androidx.savedstate.SavedStateRegistryOwner
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
import com.hchen.superlyricapi.SuperLyricData
import com.hchen.superlyricapi.SuperLyricHelper
import com.hchen.superlyricapi.SuperLyricLine
import com.hchen.superlyricapi.SuperLyricWord
import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
import dagger.hilt.EntryPoint
Expand Down Expand Up @@ -195,11 +199,30 @@ class LyricManager @Inject constructor(
updateStatusBarLyric()
}

var isSuperLyricApiEnabled: Boolean
get() = lyricPrefs.superLyricApiEnabled
set(value) {
lyricPrefs.superLyricApiEnabled = value

if (SuperLyricHelper.isAvailable()) {
if (value) {
if (!SuperLyricHelper.isPublisherRegistered()) {
SuperLyricHelper.registerPublisher()
}
} else {
if (SuperLyricHelper.isPublisherRegistered()) {
SuperLyricHelper.unregisterPublisher()
}
}
}
updateSuperLyric()
}

@UiThread
private fun ensureDesktopLyric() {
val shouldShow =
isServiceAvailable && isNotifyShowing && isScreenOn && !isAppInForeground && isDesktopLyricEnabled &&
(!isDesktopLyricLocked || isPlaying)
(!isDesktopLyricLocked || isPlaying)
if (shouldShow != (desktopLyricView != null)) {
if (shouldShow) {
createDesktopLyric()
Expand Down Expand Up @@ -399,6 +422,7 @@ class LyricManager @Inject constructor(
}
}
updateStatusBarLyric()
updateSuperLyric()
ensureDesktopLyric()
}
private var progress: Long = 0
Expand All @@ -424,14 +448,15 @@ class LyricManager @Inject constructor(
}
field = value
updateStatusBarLyric()
updateSuperLyric()
}

private fun updateStatusBarLyric() {
val service = MusicServiceRemote.service ?: return
val lyricLine = currentLyricsLine
val shouldShow = isStatusBarLyricEnabled && isPlaying &&
lyricLine.isNotBlank() &&
lyricLine != LyricLine.LYRICS_LINE_NO_LRC.content
lyricLine.isNotBlank() &&
lyricLine != LyricLine.LYRICS_LINE_NO_LRC.content

if (shouldShow) {
service.updateNotificationWithLrc(lyricLine)
Expand All @@ -440,6 +465,76 @@ class LyricManager @Inject constructor(
}
}

private fun updateSuperLyric() {
if (!isSuperLyricApiEnabled) {
return
}

if (isPlaying) {
val lyricLine = currentLyricsLine
val shouldShow = lyricLine.isNotBlank() &&
lyricLine != LyricLine.LYRICS_LINE_NO_LRC.content &&
lyricLine != LyricLine.LYRICS_LINE_SEARCHING.content

if (shouldShow) {
val song = MusicStateSource.playbackUiState.value.song
val progress = MusicStateSource.progressState.value
val lyrics = currentNextLyricsLine.value
if (SuperLyricHelper.isAvailable()) {
if (lyrics.currentLine != null) {
val superLine = when (lyrics.currentLine) {
is PerWordLyricLine -> {
SuperLyricLine(
lyrics.currentLine.content,
Array(lyrics.currentLine.words.size) { index ->
val word = lyrics.currentLine.words[index]
if (index != lyrics.currentLine.words.size - 1) {
val nextWord = lyrics.currentLine.words[index + 1]
SuperLyricWord(
word.content,
word.time,
nextWord.time
)
} else {
SuperLyricWord(
word.content,
word.time,
lyrics.nextLine?.time ?: (progress.duration + offset)
)
}
},
lyrics.currentLine.time,
lyrics.nextLine?.time ?: (progress.duration + offset)
)
}

else -> {
SuperLyricLine(
lyrics.currentLine.content,
lyrics.currentLine.time,
lyrics.nextLine?.time ?: (progress.duration + offset)
)
}
}

SuperLyricHelper.sendLyric(
SuperLyricData()
.setTitle(song.title)
.setArtist(song.artist)
.setAlbum(song.album)
.setLyric(superLine)
.setTranslation(SuperLyricLine(lyrics.currentLine.translation ?: ""))
)
}
}
}
} else {
SuperLyricHelper.sendStop(
SuperLyricData()
)
}
}

private val updateMutex = Mutex()
private var updateLyricsJob: Job? = null
private var updateProgressJob: Job? = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import remix.myplayer.ui.screen.setting.logic.library.LibraryLogic
import remix.myplayer.ui.screen.setting.logic.lyric.DesktopLyricLogic
import remix.myplayer.ui.screen.setting.logic.lyric.LyricPriorityLogic
import remix.myplayer.ui.screen.setting.logic.lyric.StatusBarLyricLogic
import remix.myplayer.ui.screen.setting.logic.lyric.SuperLyricApiLogic
import remix.myplayer.ui.screen.setting.logic.notification.ClassicNotifyLogic
import remix.myplayer.ui.screen.setting.logic.notification.NotifyBackgroundLogic
import remix.myplayer.ui.screen.setting.logic.other.ClearCacheLogic
Expand Down Expand Up @@ -262,6 +263,8 @@ private fun LyricPreferenceItems() {

StatusBarLyricLogic()

SuperLyricApiLogic()

LyricPriorityLogic()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package remix.myplayer.ui.screen.setting.logic.lyric

import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.hchen.superlyricapi.SuperLyricHelper
import remix.myplayer.ui.screen.setting.SwitchPreference
import remix.myplayer.viewmodel.settingViewModel

@Composable
fun SuperLyricApiLogic() {
if (!SuperLyricHelper.isAvailable()) {
return
}

val settingVM = settingViewModel
val settingState by settingVM.settingsState.collectAsStateWithLifecycle()

SwitchPreference(
title = "SuperLyricApi",
content = "API version: ${SuperLyricHelper.getApiVersion()}",
checked = settingState.lyric.superLyricApiEnabled
) {
settingVM.setSuperLyricApiEnabled(it)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ data class CoverSettings(
data class LyricSettings(
val desktopLyricEnabled: Boolean,
val statusBarLyricEnabled: Boolean,
val superLyricApiEnabled: Boolean,
val fontScale: Float,
val generalLyricOrder: List<LyricOrder>,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ class SettingViewModel @Inject constructor(
lyric = LyricSettings(
desktopLyricEnabled = lyricPrefs.desktopLyricEnabled,
statusBarLyricEnabled = lyricPrefs.statusBarLyricEnabled,
superLyricApiEnabled = lyricPrefs.superLyricApiEnabled,
fontScale = lyricPrefs.fontScale,
generalLyricOrder = lyricPrefs.generalLyricOrderList
),
Expand Down Expand Up @@ -358,6 +359,11 @@ class SettingViewModel @Inject constructor(
_settingsState.update { it.copy(lyric = it.lyric.copy(statusBarLyricEnabled = enabled)) }
}

fun setSuperLyricApiEnabled(enabled: Boolean) {
lyricManager.isSuperLyricApiEnabled = enabled
_settingsState.update { it.copy(lyric = it.lyric.copy(superLyricApiEnabled = enabled)) }
}

fun setLyricFontScale(scale: Float) {
lyricPrefs.fontScale = scale
_settingsState.update { it.copy(lyric = it.lyric.copy(fontScale = scale)) }
Expand Down
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ glideCompose = "1.0.0-beta01"
retrofit = "3.0.0"
retrofitKotlinxSerialization = "1.0.0"
room = "2.7.2"
superlyricapi = "3.3"
xxpermissions = "21.2"
workRuntimeKtx = "2.10.4"
activityCompose = "1.10.1"
Expand Down Expand Up @@ -102,6 +103,7 @@ image-cropper = { module = "com.vanniktech:android-image-cropper", version.ref =
bugly = { group = "com.tencent.bugly", name = "crashreport", version.ref = "bugly" }
leakcanary = { group = "com.squareup.leakcanary", name = "leakcanary-android", version.ref = "leakcanary" }
logback-android = { group = "com.github.tony19", name = "logback-android", version.ref = "logbackAndroid" }
superlyricapi = { module = "com.github.HChenX:SuperLyricApi", version.ref = "superlyricapi" }
xxpermissions = { module = "com.github.getActivity:XXPermissions", version.ref = "xxpermissions" }
sardine-android = { group = "com.github.thegrizzlylabs", name = "sardine-android", version.ref = "sardineAndroid" }
smbj = { group = "com.hierynomus", name = "smbj", version.ref = "smbj" }
Expand Down