Skip to content

Commit

Permalink
Add Lyric Support
Browse files Browse the repository at this point in the history
  • Loading branch information
LuftVerbot committed Aug 24, 2024
1 parent 29e5fc3 commit 8a0205d
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 1 deletion.
27 changes: 27 additions & 0 deletions ext/src/main/java/dev/brahmkshatriya/echo/extension/DeezerApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import kotlinx.serialization.json.put
import kotlinx.serialization.json.putJsonObject
import okhttp3.Headers
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
Expand Down Expand Up @@ -648,4 +649,30 @@ class DeezerApi {
}
)
}

fun lyrics(id: String): JsonObject {
val request = Request.Builder()
.url("https://auth.deezer.com/login/arl?jo=p&rto=c&i=c")
.post("".toRequestBody())
.headers(Headers.headersOf("Cookie", "arl=$arl; sid=$sid"))
.build()
val response = clientNP.newCall(request).execute()
val jsonObject = json.decodeFromString<JsonObject>(response.body.string())

val jwt = jsonObject["jwt"]?.jsonPrimitive?.content
val params = buildJsonObject {
put("operationName", "SynchronizedTrackLyrics")
put("query", "query SynchronizedTrackLyrics(\$trackId: String!) {\n track(trackId: \$trackId) {\n id\n isExplicit\n lyrics {\n id\n copyright\n text\n writers\n synchronizedLines {\n lrcTimestamp\n line\n milliseconds\n duration\n __typename\n }\n __typename\n }\n __typename\n }\n}")
putJsonObject("variables") {
put("trackId", id)
}
}
val pipeRequest = Request.Builder()
.url("https://pipe.deezer.com/api")
.post(json.encodeToString(params).toRequestBody())
.headers(Headers.headersOf("Authorization", "Bearer $jwt", "Content-Type", "application/json"))
.build()
val pipeResponse = clientNP.newCall(pipeRequest).execute()
return json.decodeFromString<JsonObject>(pipeResponse.body.string())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import dev.brahmkshatriya.echo.common.clients.ExtensionClient
import dev.brahmkshatriya.echo.common.clients.HomeFeedClient
import dev.brahmkshatriya.echo.common.clients.LibraryClient
import dev.brahmkshatriya.echo.common.clients.LoginClient
import dev.brahmkshatriya.echo.common.clients.LyricsClient
import dev.brahmkshatriya.echo.common.clients.PlaylistClient
import dev.brahmkshatriya.echo.common.clients.SearchClient
import dev.brahmkshatriya.echo.common.clients.ShareClient
Expand All @@ -15,6 +16,8 @@ import dev.brahmkshatriya.echo.common.helpers.PagedData
import dev.brahmkshatriya.echo.common.models.Album
import dev.brahmkshatriya.echo.common.models.Artist
import dev.brahmkshatriya.echo.common.models.ClientException
import dev.brahmkshatriya.echo.common.models.Lyric
import dev.brahmkshatriya.echo.common.models.Lyrics
import dev.brahmkshatriya.echo.common.models.MediaItemsContainer
import dev.brahmkshatriya.echo.common.models.Playlist
import dev.brahmkshatriya.echo.common.models.QuickSearchItem
Expand All @@ -39,6 +42,7 @@ import kotlinx.coroutines.coroutineScope
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.int
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
Expand All @@ -47,7 +51,7 @@ import okhttp3.Request
import java.util.Locale

class DeezerExtension : ExtensionClient, HomeFeedClient, TrackClient, SearchClient, AlbumClient, ArtistClient,
PlaylistClient, ShareClient, LoginClient.WebView.Cookie, LoginClient.UsernamePassword, LoginClient.CustomTextInput,
PlaylistClient, LyricsClient, ShareClient, LoginClient.WebView.Cookie, LoginClient.UsernamePassword, LoginClient.CustomTextInput,
LibraryClient {

private val json = Json {
Expand Down Expand Up @@ -492,6 +496,26 @@ class DeezerExtension : ExtensionClient, HomeFeedClient, TrackClient, SearchClie

override fun getMediaItems(track: Track): PagedData<MediaItemsContainer> = getMediaItems(track.artists.first())

//<============= Lyrics =============>

override suspend fun loadLyrics(small: Lyrics) = small

override fun searchTrackLyrics(clientId: String, track: Track) = PagedData.Single {
val jsonObject = api.lyrics(track.id)
val dataObject = jsonObject["data"]!!.jsonObject
val trackObject = dataObject["track"]!!.jsonObject
val lyricsObject = trackObject["lyrics"]!!.jsonObject
val lyricsId = lyricsObject["id"]?.jsonPrimitive?.content ?: ""
val linesArray = lyricsObject["synchronizedLines"]!!.jsonArray
val lyrics = linesArray.map { lineObj ->
val line = lineObj.jsonObject["line"]?.jsonPrimitive?.content ?: ""
val start = lineObj.jsonObject["milliseconds"]?.jsonPrimitive?.int ?: 0
val end = lineObj.jsonObject["duration"]?.jsonPrimitive?.int ?: 0
Lyric(line, start.toLong(), start.toLong() + end.toLong() )
}
listOf(Lyrics(lyricsId, track.title, lyrics = lyrics))
}

//<============= Album =============>

override fun getMediaItems(album: Album) = getMediaItems(album.artists.first())
Expand Down

0 comments on commit 8a0205d

Please sign in to comment.