package it.vfsfitvnm.youtubemusic.requests import io.ktor.client.call.body import io.ktor.client.request.get import io.ktor.client.request.post import io.ktor.client.request.setBody import io.ktor.http.ContentType import io.ktor.http.contentType import io.ktor.http.userAgent import it.vfsfitvnm.youtubemusic.Innertube import it.vfsfitvnm.youtubemusic.models.Context import it.vfsfitvnm.youtubemusic.models.PlayerResponse import it.vfsfitvnm.youtubemusic.models.bodies.PlayerBody import it.vfsfitvnm.youtubemusic.utils.runCatchingNonCancellable import kotlinx.serialization.Serializable suspend fun Innertube.player(body: PlayerBody) = runCatchingNonCancellable { val response = client.post(player) { setBody(body) body.context.client.userAgent?.let(::userAgent) mask("playabilityStatus.status,playerConfig.audioConfig,streamingData.adaptiveFormats,videoDetails.videoId") }.body() if (response.playabilityStatus?.status == "OK") { response } else { @Serializable data class AudioStream( val url: String, val bitrate: Long ) @Serializable data class PipedResponse( val audioStreams: List ) val safePlayerResponse = client.post(player) { setBody( body.copy( context = Context.DefaultAgeRestrictionBypass.copy( thirdParty = Context.ThirdParty( embedUrl = "https://www.youtube.com/watch?v=${body.videoId}" ) ), ) ) mask("playabilityStatus.status,playerConfig.audioConfig,streamingData.adaptiveFormats,videoDetails.videoId") }.body() if (safePlayerResponse.playabilityStatus?.status != "OK") { return@runCatchingNonCancellable response } val audioStreams = client.get("https://watchapi.whatever.social/streams/${body.videoId}") { contentType(ContentType.Application.Json) }.body().audioStreams safePlayerResponse.copy( streamingData = safePlayerResponse.streamingData?.copy( adaptiveFormats = safePlayerResponse.streamingData.adaptiveFormats?.map { adaptiveFormat -> adaptiveFormat.copy( url = audioStreams.find { it.bitrate == adaptiveFormat.bitrate }?.url ) } ) ) } }