This commit is contained in:
vfsfitvnm 2022-10-09 15:06:02 +02:00
parent e9a6156b12
commit c00a079715
6 changed files with 33 additions and 7 deletions

View file

@ -7,3 +7,5 @@ class PlayableFormatNotFoundException : PlaybackException(null, null, ERROR_CODE
class UnplayableException : PlaybackException(null, null, ERROR_CODE_REMOTE_ERROR) class UnplayableException : PlaybackException(null, null, ERROR_CODE_REMOTE_ERROR)
class LoginRequiredException : PlaybackException(null, null, ERROR_CODE_REMOTE_ERROR) class LoginRequiredException : PlaybackException(null, null, ERROR_CODE_REMOTE_ERROR)
class VideoIdMismatchException : PlaybackException(null, null, ERROR_CODE_REMOTE_ERROR)

View file

@ -650,6 +650,10 @@ class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListene
val urlResult = runBlocking(Dispatchers.IO) { val urlResult = runBlocking(Dispatchers.IO) {
Innertube.player(PlayerBody(videoId = videoId)) Innertube.player(PlayerBody(videoId = videoId))
}?.mapCatching { body -> }?.mapCatching { body ->
if (body.videoDetails?.videoId != videoId) {
throw VideoIdMismatchException()
}
when (val status = body.playabilityStatus?.status) { when (val status = body.playabilityStatus?.status) {
"OK" -> body.streamingData?.adaptiveFormats?.findLast { format -> "OK" -> body.streamingData?.adaptiveFormats?.findLast { format ->
format.itag == 251 || format.itag == 140 format.itag == 251 || format.itag == 140

View file

@ -31,6 +31,7 @@ import it.vfsfitvnm.vimusic.query
import it.vfsfitvnm.vimusic.service.LoginRequiredException import it.vfsfitvnm.vimusic.service.LoginRequiredException
import it.vfsfitvnm.vimusic.service.PlayableFormatNotFoundException import it.vfsfitvnm.vimusic.service.PlayableFormatNotFoundException
import it.vfsfitvnm.vimusic.service.UnplayableException import it.vfsfitvnm.vimusic.service.UnplayableException
import it.vfsfitvnm.vimusic.service.VideoIdMismatchException
import it.vfsfitvnm.vimusic.ui.styling.Dimensions import it.vfsfitvnm.vimusic.ui.styling.Dimensions
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.px import it.vfsfitvnm.vimusic.ui.styling.px
@ -159,6 +160,7 @@ fun Thumbnail(
is PlayableFormatNotFoundException -> "Couldn't find a playable audio format" is PlayableFormatNotFoundException -> "Couldn't find a playable audio format"
is UnplayableException -> "The original video source of this song has been deleted" is UnplayableException -> "The original video source of this song has been deleted"
is LoginRequiredException -> "This song cannot be played due to server restrictions" is LoginRequiredException -> "This song cannot be played due to server restrictions"
is VideoIdMismatchException -> "The returned video id didn't match the requested one"
else -> "An unknown playback error has occurred" else -> "An unknown playback error has occurred"
} }
}, },

View file

@ -11,8 +11,10 @@ data class Context(
data class Client( data class Client(
val clientName: String, val clientName: String,
val clientVersion: String, val clientVersion: String,
val visitorData: String?, val platform: String,
val hl: String = "en", val hl: String = "en",
val visitorData: String? = null,
val androidSdkVersion: Int? = null
) )
@Serializable @Serializable
@ -24,7 +26,8 @@ data class Context(
val DefaultWeb = Context( val DefaultWeb = Context(
client = Client( client = Client(
clientName = "WEB_REMIX", clientName = "WEB_REMIX",
clientVersion = "1.20220328.01.00", clientVersion = "1.20220918",
platform = "DESKTOP",
visitorData = "CgtsZG1ySnZiQWtSbyiMjuGSBg%3D%3D" visitorData = "CgtsZG1ySnZiQWtSbyiMjuGSBg%3D%3D"
) )
) )
@ -32,8 +35,9 @@ data class Context(
val DefaultAndroid = Context( val DefaultAndroid = Context(
client = Client( client = Client(
clientName = "ANDROID", clientName = "ANDROID",
clientVersion = "16.50", clientVersion = "17.36.4",
visitorData = null, platform = "MOBILE",
androidSdkVersion = 31,
) )
) )
@ -41,6 +45,7 @@ data class Context(
client = Client( client = Client(
clientName = "TVHTML5_SIMPLY_EMBEDDED_PLAYER", clientName = "TVHTML5_SIMPLY_EMBEDDED_PLAYER",
clientVersion = "2.0", clientVersion = "2.0",
platform = "TV",
visitorData = null, visitorData = null,
) )
) )

View file

@ -7,6 +7,7 @@ data class PlayerResponse(
val playabilityStatus: PlayabilityStatus?, val playabilityStatus: PlayabilityStatus?,
val playerConfig: PlayerConfig?, val playerConfig: PlayerConfig?,
val streamingData: StreamingData?, val streamingData: StreamingData?,
val videoDetails: VideoDetails?,
) { ) {
@Serializable @Serializable
data class PlayabilityStatus( data class PlayabilityStatus(
@ -19,8 +20,7 @@ data class PlayerResponse(
) { ) {
@Serializable @Serializable
data class AudioConfig( data class AudioConfig(
val loudnessDb: Double?, val loudnessDb: Double?
val perceptualLoudnessDb: Double?
) )
} }
@ -43,4 +43,9 @@ data class PlayerResponse(
val url: String?, val url: String?,
) )
} }
@Serializable
data class VideoDetails(
val videoId: String?
)
} }

View file

@ -34,7 +34,15 @@ suspend fun Innertube.player(body: PlayerBody) = runCatchingNonCancellable {
) )
val safePlayerResponse = client.post(player) { val safePlayerResponse = client.post(player) {
setBody(body.copy(context = Context.DefaultAgeRestrictionBypass)) 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") mask("playabilityStatus.status,playerConfig.audioConfig,streamingData.adaptiveFormats")
}.body<PlayerResponse>() }.body<PlayerResponse>()