All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.internal.util.YouTubeUtils.kt Maven / Gradle / Ivy

package dev.schlaubi.lyrics.internal.util

import dev.schlaubi.lyrics.LyricsNotFoundException
import dev.schlaubi.lyrics.protocol.Lyrics
import dev.schlaubi.lyrics.protocol.TimedLyrics
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonObject

internal val JsonObject.browseEndpoint: String?
    get() = getJsonObject("contents")
        ?.getJsonObject("singleColumnMusicWatchNextResultsRenderer")
        ?.getJsonObject("tabbedRenderer")
        ?.getJsonObject("watchNextTabbedResultsRenderer")
        ?.getJsonArray("tabs")
        ?.getJsonObject(1)
        ?.getJsonObject("tabRenderer")
        ?.getJsonObject("endpoint")
        ?.getJsonObject("browseEndpoint")
        ?.getString("browseId")

internal val JsonObject.lyricsData: JsonObject?
    get() = getJsonObject("contents")
        ?.getJsonObject("elementRenderer")
        ?.getJsonObject("newElement")
        ?.getJsonObject("type")
        ?.getJsonObject("componentType")
        ?.getJsonObject("model")
        ?.getJsonObject("timedLyricsModel")
        ?.getJsonObject("lyricsData")

internal fun JsonObject.getTracks(albumArt: List): Lyrics.Track {
    val lockScreen = getJsonObject("lockScreen")?.getJsonObject("lockScreenRenderer")
        ?: notFound()

    val title = lockScreen.getRunningText("title") ?: notFound()
    val author = lockScreen.getRunningText("shortBylineText") ?: notFound()
    val album = lockScreen.getRunningText("albumText") ?: notFound()

    return Lyrics.Track(title, author, album, albumArt)
}

internal val JsonObject.source: String
    get() = getString("sourceMessage")?.substringAfter(": ") ?: notFound()

internal val JsonObject.musicDescriptionShelfRenderer
    get() = getJsonObject("contents")
        ?.getJsonObject("sectionListRenderer")
        ?.getJsonArray("contents")
        ?.getJsonObject(0)
        ?.getJsonObject("musicDescriptionShelfRenderer")

internal val JsonObject.thumbnails: JsonArray?
    get() = getJsonObject("contents")
        ?.getJsonObject("singleColumnMusicWatchNextResultsRenderer")
        ?.getJsonObject("tabbedRenderer")
        ?.getJsonObject("watchNextTabbedResultsRenderer")
        ?.getJsonArray("tabs")
        ?.getJsonObject(0)
        ?.getJsonObject("tabRenderer")
        ?.getJsonObject("content")
        ?.getJsonObject("musicQueueRenderer")
        ?.getJsonObject("content")
        ?.getJsonObject("playlistPanelRenderer")
        ?.getJsonArray("contents")
        ?.getJsonObject(0)
        ?.getJsonObject("playlistPanelVideoRenderer")
        ?.getJsonObject("thumbnail")
        ?.getJsonArray("thumbnails")

internal fun JsonObject.toAlbumArt(): Lyrics.Track.AlbumArt {
    val url = getString("url")!!
    val height = getInt("height")!!
    val width = getInt("width")!!

    return Lyrics.Track.AlbumArt(url, height, width)
}

internal val JsonObject.lines: List
    get() {
        val linesData = getJsonArray("timedLyricsData") ?: notFound()

        return linesData.map {
            val json = it.jsonObject
            val line = json.getString("lyricLine")!!
            val range = json.getJsonObject("cueRange")?.let { range ->
                val start = range.getLong("startTimeMilliseconds") ?: return@let null
                val end = range.getLong("endTimeMilliseconds") ?: return@let null
                start..end
            } ?: error("Could not calculate range")

            TimedLyrics.Line(line, range)
        }
    }

internal fun notFound(): Nothing = throw LyricsNotFoundException()




© 2015 - 2024 Weber Informatics LLC | Privacy Policy