Skip to content

Commit

Permalink
sora: fix crunchy
Browse files Browse the repository at this point in the history
  • Loading branch information
alex committed Jan 1, 2024
1 parent 1e2f746 commit aada4b4
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 34 deletions.
2 changes: 1 addition & 1 deletion Samehadaku/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// use an integer for version numbers
version = 18
version = 19


cloudstream {
Expand Down
5 changes: 3 additions & 2 deletions Samehadaku/src/main/kotlin/com/hexated/Samehadaku.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Expand Down
2 changes: 1 addition & 1 deletion SoraStream/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import org.jetbrains.kotlin.konan.properties.Properties

// use an integer for version numbers
version = 210
version = 211

android {
defaultConfig {
Expand Down
20 changes: 10 additions & 10 deletions SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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 ->
Expand All @@ -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(
Expand All @@ -1552,16 +1554,14 @@ object SoraExtractor : SoraStream() {
).forEach(callback)
}

sources?.meta?.subtitles?.map { sub ->
sources?.subtitles?.map { sub ->
subtitleCallback.invoke(
SubtitleFile(
"${fixCrunchyrollLang(sub.key) ?: sub.key} [ass]",
sub.value["url"] ?: return@map null
)
)
}


}
}

Expand Down Expand Up @@ -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)
Expand Down
43 changes: 28 additions & 15 deletions SoraStream/src/main/kotlin/com/hexated/SoraParser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -207,12 +216,17 @@ 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("access_token") val accessToken: String? = null,
@JsonProperty("token_type") val tokenType: 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,
Expand All @@ -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(),
Expand Down
18 changes: 13 additions & 5 deletions SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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? {
Expand Down Expand Up @@ -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("/")
}
}

Expand Down

0 comments on commit aada4b4

Please sign in to comment.