Play age restricted videos (#119)
This commit is contained in:
@@ -125,6 +125,7 @@ object YouTube {
|
|||||||
visitorData = "CgtsZG1ySnZiQWtSbyiMjuGSBg%3D%3D"
|
visitorData = "CgtsZG1ySnZiQWtSbyiMjuGSBg%3D%3D"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
val DefaultAndroid = Context(
|
val DefaultAndroid = Context(
|
||||||
client = Client(
|
client = Client(
|
||||||
clientName = "ANDROID",
|
clientName = "ANDROID",
|
||||||
@@ -132,6 +133,14 @@ object YouTube {
|
|||||||
visitorData = null,
|
visitorData = null,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val DefaultAgeRestrictionBypass = Context(
|
||||||
|
client = Client(
|
||||||
|
clientName = "TVHTML5_SIMPLY_EMBEDDED_PLAYER",
|
||||||
|
clientVersion = "2.0",
|
||||||
|
visitorData = null,
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -457,7 +466,7 @@ object YouTube {
|
|||||||
|
|
||||||
suspend fun player(videoId: String, playlistId: String? = null): Result<PlayerResponse>? {
|
suspend fun player(videoId: String, playlistId: String? = null): Result<PlayerResponse>? {
|
||||||
return runCatching {
|
return runCatching {
|
||||||
client.post("/youtubei/v1/player") {
|
val playerResponse = client.post("/youtubei/v1/player") {
|
||||||
contentType(ContentType.Application.Json)
|
contentType(ContentType.Application.Json)
|
||||||
setBody(
|
setBody(
|
||||||
PlayerBody(
|
PlayerBody(
|
||||||
@@ -469,6 +478,52 @@ object YouTube {
|
|||||||
parameter("key", Key)
|
parameter("key", Key)
|
||||||
parameter("prettyPrint", false)
|
parameter("prettyPrint", false)
|
||||||
}.body<PlayerResponse>()
|
}.body<PlayerResponse>()
|
||||||
|
|
||||||
|
if (playerResponse.playabilityStatus.status == "OK") {
|
||||||
|
playerResponse
|
||||||
|
} else {
|
||||||
|
@Serializable
|
||||||
|
data class AudioStream(
|
||||||
|
val url: String,
|
||||||
|
val bitrate: Long
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class PipedResponse(
|
||||||
|
val audioStreams: List<AudioStream>
|
||||||
|
)
|
||||||
|
|
||||||
|
val safePlayerResponse = client.post("/youtubei/v1/player") {
|
||||||
|
contentType(ContentType.Application.Json)
|
||||||
|
setBody(
|
||||||
|
PlayerBody(
|
||||||
|
context = Context.DefaultAgeRestrictionBypass,
|
||||||
|
videoId = videoId,
|
||||||
|
playlistId = playlistId,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
parameter("key", Key)
|
||||||
|
parameter("prettyPrint", false)
|
||||||
|
}.body<PlayerResponse>()
|
||||||
|
|
||||||
|
if (safePlayerResponse.playabilityStatus.status != "OK") {
|
||||||
|
return@runCatching playerResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
val audioStreams = client.get("https://pipedapi.kavin.rocks/streams/$videoId") {
|
||||||
|
contentType(ContentType.Application.Json)
|
||||||
|
}.body<PipedResponse>().audioStreams
|
||||||
|
|
||||||
|
safePlayerResponse.copy(
|
||||||
|
streamingData = safePlayerResponse.streamingData?.copy(
|
||||||
|
adaptiveFormats = safePlayerResponse.streamingData.adaptiveFormats.map { adaptiveFormat ->
|
||||||
|
adaptiveFormat.copy(
|
||||||
|
url = audioStreams.find { it.bitrate == adaptiveFormat.bitrate }?.url
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}.recoverIfCancelled()
|
}.recoverIfCancelled()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ data class PlayerResponse(
|
|||||||
val lastModified: Long?,
|
val lastModified: Long?,
|
||||||
val loudnessDb: Double?,
|
val loudnessDb: Double?,
|
||||||
val audioSampleRate: Int?,
|
val audioSampleRate: Int?,
|
||||||
val url: String,
|
val url: String?,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user