mirror of
https://github.com/hexated/cloudstream-extensions-hexated.git
synced 2024-08-15 00:03:22 +00:00
sora: fix crunchy
This commit is contained in:
parent
1e2f746676
commit
aada4b49fe
6 changed files with 56 additions and 34 deletions
|
@ -1,5 +1,5 @@
|
|||
// use an integer for version numbers
|
||||
version = 18
|
||||
version = 19
|
||||
|
||||
|
||||
cloudstream {
|
||||
|
|
|
@ -217,9 +217,10 @@ class Samehadaku : MainAPI() {
|
|||
}
|
||||
|
||||
private fun String.fixQuality() : Int {
|
||||
return when(this) {
|
||||
"MP4HD" -> Qualities.P720.value
|
||||
return when(this.uppercase()) {
|
||||
"4K" -> Qualities.P2160.value
|
||||
"FULLHD" -> Qualities.P1080.value
|
||||
"MP4HD" -> Qualities.P720.value
|
||||
else -> this.filter { it.isDigit() }.toIntOrNull() ?: Qualities.Unknown.value
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import org.jetbrains.kotlin.konan.properties.Properties
|
||||
|
||||
// use an integer for version numbers
|
||||
version = 210
|
||||
version = 211
|
||||
|
||||
android {
|
||||
defaultConfig {
|
||||
|
|
|
@ -1505,7 +1505,8 @@ object SoraExtractor : SoraStream() {
|
|||
"en-US",
|
||||
"zh-CN",
|
||||
)
|
||||
val headers = getCrunchyrollToken()
|
||||
val token = getCrunchyrollToken()
|
||||
val headers = mapOf("Authorization" to "${token.tokenType} ${token.accessToken}")
|
||||
val seasonIdData = app.get(
|
||||
"$crunchyrollAPI/content/v2/cms/series/${id ?: return}/seasons", headers = headers
|
||||
).parsedSafe<CrunchyrollResponses>()?.data?.let { s ->
|
||||
|
@ -1532,17 +1533,18 @@ object SoraExtractor : SoraStream() {
|
|||
it.title.equals(epsTitle, true) || it.slug_title.equals(
|
||||
epsTitle.createSlug(), true
|
||||
) || it.episode_number == episode
|
||||
}?.streams_link
|
||||
val sources =
|
||||
app.get(fixUrl(streamsLink ?: return@apmap, crunchyrollAPI), headers = headers)
|
||||
.parsedSafe<CrunchyrollSourcesResponses>()
|
||||
}?.streams_link?.substringAfter("/videos/")?.substringBefore("/streams") ?: return@apmap
|
||||
val sources = app.get(
|
||||
"$crunchyrollAPI/cms/v2${token.bucket}/videos/$streamsLink/streams?Policy=${token.policy}&Signature=${token.signature}&Key-Pair-Id=${token.key_pair_id}",
|
||||
headers = headers
|
||||
).parsedSafe<CrunchyrollSourcesResponses>()
|
||||
|
||||
listOf(
|
||||
"adaptive_hls", "vo_adaptive_hls"
|
||||
).map { hls ->
|
||||
val name = if (hls == "adaptive_hls") "Crunchyroll" else "Vrv"
|
||||
val audio = if (audioL == "en-US") "English Dub" else "Raw"
|
||||
val source = sources?.data?.firstOrNull()?.let {
|
||||
val source = sources?.streams?.let {
|
||||
if (hls == "adaptive_hls") it.adaptive_hls else it.vo_adaptive_hls
|
||||
}
|
||||
M3u8Helper.generateM3u8(
|
||||
|
@ -1552,7 +1554,7 @@ object SoraExtractor : SoraStream() {
|
|||
).forEach(callback)
|
||||
}
|
||||
|
||||
sources?.meta?.subtitles?.map { sub ->
|
||||
sources?.subtitles?.map { sub ->
|
||||
subtitleCallback.invoke(
|
||||
SubtitleFile(
|
||||
"${fixCrunchyrollLang(sub.key) ?: sub.key} [ass]",
|
||||
|
@ -1560,8 +1562,6 @@ object SoraExtractor : SoraStream() {
|
|||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2135,7 +2135,7 @@ object SoraExtractor : SoraStream() {
|
|||
media.third.substringAfterLast("/") to iframe.substringAfterLast("/")
|
||||
.substringBefore("-")
|
||||
}
|
||||
val res = app.get(fixUrl(iframe, api))
|
||||
val res = app.get(fixUrl(iframe, api), verify = false)
|
||||
delay(2000)
|
||||
val serverUrl = res.document.selectFirst("script:containsData(pushState)")?.data()?.let {
|
||||
""",\s*'([^']+)""".toRegex().find(it)?.groupValues?.get(1)
|
||||
|
|
|
@ -2,6 +2,15 @@ package com.hexated
|
|||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
|
||||
data class CrunchyrollAccessToken(
|
||||
val accessToken: String? = null,
|
||||
val tokenType: String? = null,
|
||||
val bucket: String? = null,
|
||||
val policy: String? = null,
|
||||
val signature: String? = null,
|
||||
val key_pair_id: String? = null,
|
||||
)
|
||||
|
||||
data class ShowboxMedia(
|
||||
val url: String,
|
||||
val title: String,
|
||||
|
@ -208,11 +217,16 @@ data class AnilistResponses(
|
|||
|
||||
data class CrunchyrollToken(
|
||||
@JsonProperty("access_token") val accessToken: String? = null,
|
||||
@JsonProperty("expires_in") val expiresIn: Int? = null,
|
||||
@JsonProperty("token_type") val tokenType: String? = null,
|
||||
@JsonProperty("scope") val scope: String? = null,
|
||||
@JsonProperty("country") val country: String? = null
|
||||
@JsonProperty("cms") val cms: Cms? = null,
|
||||
) {
|
||||
data class Cms(
|
||||
@JsonProperty("bucket") var bucket: String? = null,
|
||||
@JsonProperty("policy") var policy: String? = null,
|
||||
@JsonProperty("signature") var signature: String? = null,
|
||||
@JsonProperty("key_pair_id") var key_pair_id: String? = null,
|
||||
)
|
||||
}
|
||||
|
||||
data class CrunchyrollVersions(
|
||||
@JsonProperty("audio_locale") val audio_locale: String? = null,
|
||||
|
@ -227,22 +241,21 @@ data class CrunchyrollData(
|
|||
@JsonProperty("episode_number") val episode_number: Int? = null,
|
||||
@JsonProperty("versions") val versions: ArrayList<CrunchyrollVersions>? = null,
|
||||
@JsonProperty("streams_link") val streams_link: String? = null,
|
||||
@JsonProperty("adaptive_hls") val adaptive_hls: HashMap<String, HashMap<String, String>>? = hashMapOf(),
|
||||
@JsonProperty("vo_adaptive_hls") val vo_adaptive_hls: HashMap<String, HashMap<String, String>>? = hashMapOf(),
|
||||
)
|
||||
|
||||
data class CrunchyrollResponses(
|
||||
@JsonProperty("data") val data: ArrayList<CrunchyrollData>? = arrayListOf(),
|
||||
)
|
||||
|
||||
data class CrunchyrollMeta(
|
||||
@JsonProperty("subtitles") val subtitles: HashMap<String, HashMap<String, String>>? = hashMapOf(),
|
||||
)
|
||||
|
||||
data class CrunchyrollSourcesResponses(
|
||||
@JsonProperty("data") val data: ArrayList<CrunchyrollData>? = arrayListOf(),
|
||||
@JsonProperty("meta") val meta: CrunchyrollMeta? = null,
|
||||
@JsonProperty("streams") val streams: Streams? = Streams(),
|
||||
@JsonProperty("subtitles") val subtitles: HashMap<String, HashMap<String, String>>? = hashMapOf(),
|
||||
) {
|
||||
data class Streams(
|
||||
@JsonProperty("adaptive_hls") val adaptive_hls: HashMap<String, HashMap<String, String>>? = hashMapOf(),
|
||||
@JsonProperty("vo_adaptive_hls") val vo_adaptive_hls: HashMap<String, HashMap<String, String>>? = hashMapOf(),
|
||||
)
|
||||
}
|
||||
|
||||
data class MALSyncSites(
|
||||
@JsonProperty("Zoro") val zoro: HashMap<String?, HashMap<String, String?>>? = hashMapOf(),
|
||||
|
|
|
@ -734,7 +734,7 @@ fun Document.findTvMoviesIframe(): String? {
|
|||
}
|
||||
|
||||
//modified code from https://github.com/jmir1/aniyomi-extensions/blob/master/src/all/kamyroll/src/eu/kanade/tachiyomi/animeextension/all/kamyroll/AccessTokenInterceptor.kt
|
||||
suspend fun getCrunchyrollToken(): Map<String, String> {
|
||||
suspend fun getCrunchyrollToken(): CrunchyrollAccessToken {
|
||||
val client = app.baseClient.newBuilder()
|
||||
.proxy(Proxy(Proxy.Type.SOCKS, InetSocketAddress("cr-unblocker.us.to", 1080)))
|
||||
.build()
|
||||
|
@ -760,9 +760,17 @@ suspend fun getCrunchyrollToken(): Map<String, String> {
|
|||
)
|
||||
)
|
||||
|
||||
val response = tryParseJson<CrunchyrollToken>(client.newCall(request).execute().body.string())
|
||||
return mapOf("Authorization" to "${response?.tokenType} ${response?.accessToken}")
|
||||
|
||||
val token = tryParseJson<CrunchyrollToken>(client.newCall(request).execute().body.string())
|
||||
val headers = mapOf("Authorization" to "${token?.tokenType} ${token?.accessToken}")
|
||||
val cms = app.get("$crunchyrollAPI/index/v2", headers = headers).parsedSafe<CrunchyrollToken>()?.cms
|
||||
return CrunchyrollAccessToken(
|
||||
token?.accessToken,
|
||||
token?.tokenType,
|
||||
cms?.bucket,
|
||||
cms?.policy,
|
||||
cms?.signature,
|
||||
cms?.key_pair_id,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun getCrunchyrollId(aniId: String?): String? {
|
||||
|
@ -796,7 +804,7 @@ suspend fun getCrunchyrollId(aniId: String?): String? {
|
|||
|
||||
return (externalLinks?.find { it.site == "VRV" }
|
||||
?: externalLinks?.find { it.site == "Crunchyroll" })?.url?.let {
|
||||
Regex("series/(\\w+)/?").find(it)?.groupValues?.get(1)
|
||||
app.get(it).url.substringAfter("/series/").substringBefore("/")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue