mirror of
https://github.com/hexated/cloudstream-extensions-hexated.git
synced 2024-08-15 00:03:22 +00:00
[Sora] fixed missing anime in zoro and crunchy
This commit is contained in:
parent
95b2dbfe9a
commit
b6ffffa34b
4 changed files with 119 additions and 185 deletions
|
@ -1,5 +1,5 @@
|
||||||
// use an integer for version numbers
|
// use an integer for version numbers
|
||||||
version = 60
|
version = 61
|
||||||
|
|
||||||
|
|
||||||
cloudstream {
|
cloudstream {
|
||||||
|
|
|
@ -80,8 +80,7 @@ object SoraExtractor : SoraStream() {
|
||||||
document.select(".dropdown-menu a[data-id]").map { it.attr("data-id") }.apmap { serverID ->
|
document.select(".dropdown-menu a[data-id]").map { it.attr("data-id") }.apmap { serverID ->
|
||||||
val token = APIHolder.getCaptchaToken(url, captchaKey)
|
val token = APIHolder.getCaptchaToken(url, captchaKey)
|
||||||
app.get(
|
app.get(
|
||||||
"$twoEmbedAPI/ajax/embed/play?id=$serverID&_token=$token",
|
"$twoEmbedAPI/ajax/embed/play?id=$serverID&_token=$token", referer = url
|
||||||
referer = url
|
|
||||||
).parsedSafe<EmbedJson>()?.let { source ->
|
).parsedSafe<EmbedJson>()?.let { source ->
|
||||||
val link = source.link ?: return@let
|
val link = source.link ?: return@let
|
||||||
if (link.contains("rabbitstream")) {
|
if (link.contains("rabbitstream")) {
|
||||||
|
@ -92,17 +91,13 @@ object SoraExtractor : SoraStream() {
|
||||||
).parsedSafe<RabbitSources>()?.tracks?.map { sub ->
|
).parsedSafe<RabbitSources>()?.tracks?.map { sub ->
|
||||||
subtitleCallback.invoke(
|
subtitleCallback.invoke(
|
||||||
SubtitleFile(
|
SubtitleFile(
|
||||||
sub.label.toString(),
|
sub.label.toString(), sub.file ?: return@map null
|
||||||
sub.file ?: return@map null
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
loadExtractor(
|
loadExtractor(
|
||||||
link,
|
link, twoEmbedAPI, subtitleCallback, callback
|
||||||
twoEmbedAPI,
|
|
||||||
subtitleCallback,
|
|
||||||
callback
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,8 +139,7 @@ object SoraExtractor : SoraStream() {
|
||||||
episode: Int? = null,
|
episode: Int? = null,
|
||||||
callback: (ExtractorLink) -> Unit
|
callback: (ExtractorLink) -> Unit
|
||||||
) {
|
) {
|
||||||
val url =
|
val url = "$olgplyAPI/${id}${season?.let { "/$it" } ?: ""}${episode?.let { "/$it" } ?: ""}"
|
||||||
"$olgplyAPI/${id}${season?.let { "/$it" } ?: ""}${episode?.let { "/$it" } ?: ""}"
|
|
||||||
loadLinksWithWebView(url, callback)
|
loadLinksWithWebView(url, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,13 +161,11 @@ object SoraExtractor : SoraStream() {
|
||||||
val doc = app.get("$dbgoAPI/tv-imdb.php?id=$id&s=$season").document
|
val doc = app.get("$dbgoAPI/tv-imdb.php?id=$id&s=$season").document
|
||||||
iframeDbgo = doc.select("div.myvideo iframe").attr("src")
|
iframeDbgo = doc.select("div.myvideo iframe").attr("src")
|
||||||
val token = app.get(
|
val token = app.get(
|
||||||
iframeDbgo,
|
iframeDbgo, referer = "$dbgoAPI/"
|
||||||
referer = "$dbgoAPI/"
|
|
||||||
).document.selectFirst("select#translator-name option")?.attr("data-token")
|
).document.selectFirst("select#translator-name option")?.attr("data-token")
|
||||||
app.get("https://voidboost.net/serial/$token/iframe?s=$season&e=$episode&h=dbgo.fun").document.select(
|
app.get("https://voidboost.net/serial/$token/iframe?s=$season&e=$episode&h=dbgo.fun").document.select(
|
||||||
"script"
|
"script"
|
||||||
)
|
).find { it.data().contains("CDNplayerConfig =") }?.data()
|
||||||
.find { it.data().contains("CDNplayerConfig =") }?.data()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val source =
|
val source =
|
||||||
|
@ -189,8 +181,7 @@ object SoraExtractor : SoraStream() {
|
||||||
decryptStreamUrl(source).split(",").map { links ->
|
decryptStreamUrl(source).split(",").map { links ->
|
||||||
val quality =
|
val quality =
|
||||||
Regex("\\[([0-9]*p.*?)]").find(links)?.groupValues?.getOrNull(1).toString().trim()
|
Regex("\\[([0-9]*p.*?)]").find(links)?.groupValues?.getOrNull(1).toString().trim()
|
||||||
links.replace("[$quality]", "").split(" or ").map { it.trim() }
|
links.replace("[$quality]", "").split(" or ").map { it.trim() }.map { link ->
|
||||||
.map { link ->
|
|
||||||
val name = if (link.contains(".m3u8")) "Dbgo (Main)" else "Dbgo (Backup)"
|
val name = if (link.contains(".m3u8")) "Dbgo (Main)" else "Dbgo (Backup)"
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
|
@ -209,14 +200,11 @@ object SoraExtractor : SoraStream() {
|
||||||
}
|
}
|
||||||
|
|
||||||
subtitle?.split(",")?.map { sub ->
|
subtitle?.split(",")?.map { sub ->
|
||||||
val language =
|
val language = Regex("\\[(.*)]").find(sub)?.groupValues?.getOrNull(1).toString()
|
||||||
Regex("\\[(.*)]").find(sub)?.groupValues?.getOrNull(1)
|
|
||||||
.toString()
|
|
||||||
val link = sub.replace("[$language]", "").trim()
|
val link = sub.replace("[$language]", "").trim()
|
||||||
subtitleCallback.invoke(
|
subtitleCallback.invoke(
|
||||||
SubtitleFile(
|
SubtitleFile(
|
||||||
language,
|
language, link
|
||||||
link
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -250,10 +238,7 @@ object SoraExtractor : SoraStream() {
|
||||||
}
|
}
|
||||||
}.apmap { link ->
|
}.apmap { link ->
|
||||||
loadExtractor(
|
loadExtractor(
|
||||||
link,
|
link, "https://123moviesjr.cc/", subtitleCallback, callback
|
||||||
"https://123moviesjr.cc/",
|
|
||||||
subtitleCallback,
|
|
||||||
callback
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -282,10 +267,7 @@ object SoraExtractor : SoraStream() {
|
||||||
headers = mapOf("X-Requested-With" to "XMLHttpRequest")
|
headers = mapOf("X-Requested-With" to "XMLHttpRequest")
|
||||||
).parsedSafe<MovieHabRes>()?.data?.let { res ->
|
).parsedSafe<MovieHabRes>()?.data?.let { res ->
|
||||||
loadExtractor(
|
loadExtractor(
|
||||||
res.link ?: return@let null,
|
res.link ?: return@let null, movieHabAPI, subtitleCallback, callback
|
||||||
movieHabAPI,
|
|
||||||
subtitleCallback,
|
|
||||||
callback
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -387,8 +369,7 @@ object SoraExtractor : SoraStream() {
|
||||||
?.attr("src")
|
?.attr("src")
|
||||||
|
|
||||||
val script = app.get(
|
val script = app.get(
|
||||||
iframe ?: return,
|
iframe ?: return, referer = "$hdMovieBoxAPI/"
|
||||||
referer = "$hdMovieBoxAPI/"
|
|
||||||
).document.selectFirst("script:containsData(var vhash =)")?.data()
|
).document.selectFirst("script:containsData(var vhash =)")?.data()
|
||||||
?.substringAfter("vhash, {")?.substringBefore("}, false")
|
?.substringAfter("vhash, {")?.substringBefore("}, false")
|
||||||
|
|
||||||
|
@ -399,8 +380,7 @@ object SoraExtractor : SoraStream() {
|
||||||
base64Encode(source.videoDisk.toString().toByteArray())
|
base64Encode(source.videoDisk.toString().toByteArray())
|
||||||
}
|
}
|
||||||
val link = getBaseUrl(iframe) + source?.videoUrl?.replace(
|
val link = getBaseUrl(iframe) + source?.videoUrl?.replace(
|
||||||
"\\",
|
"\\", ""
|
||||||
""
|
|
||||||
) + "?s=${source?.videoServer}&d=$disk"
|
) + "?s=${source?.videoServer}&d=$disk"
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
|
@ -485,15 +465,9 @@ object SoraExtractor : SoraStream() {
|
||||||
it.attr("data-nume")
|
it.attr("data-nume")
|
||||||
}.apmap { nume ->
|
}.apmap { nume ->
|
||||||
val source = app.post(
|
val source = app.post(
|
||||||
url = "$referer/wp-admin/admin-ajax.php",
|
url = "$referer/wp-admin/admin-ajax.php", data = mapOf(
|
||||||
data = mapOf(
|
"action" to "doo_player_ajax", "post" to id, "nume" to nume, "type" to type
|
||||||
"action" to "doo_player_ajax",
|
), headers = mapOf("X-Requested-With" to "XMLHttpRequest"), referer = url
|
||||||
"post" to id,
|
|
||||||
"nume" to nume,
|
|
||||||
"type" to type
|
|
||||||
),
|
|
||||||
headers = mapOf("X-Requested-With" to "XMLHttpRequest"),
|
|
||||||
referer = url
|
|
||||||
).parsed<ResponseHash>().embed_url
|
).parsed<ResponseHash>().embed_url
|
||||||
|
|
||||||
if (!source.contains("youtube")) {
|
if (!source.contains("youtube")) {
|
||||||
|
@ -525,15 +499,9 @@ object SoraExtractor : SoraStream() {
|
||||||
val id = el.attr("data-post")
|
val id = el.attr("data-post")
|
||||||
val nume = el.attr("data-nume")
|
val nume = el.attr("data-nume")
|
||||||
val source = app.post(
|
val source = app.post(
|
||||||
url = "$uniqueStreamAPI/wp-admin/admin-ajax.php",
|
url = "$uniqueStreamAPI/wp-admin/admin-ajax.php", data = mapOf(
|
||||||
data = mapOf(
|
"action" to "doo_player_ajax", "post" to id, "nume" to nume, "type" to type
|
||||||
"action" to "doo_player_ajax",
|
), headers = mapOf("X-Requested-With" to "XMLHttpRequest"), referer = url
|
||||||
"post" to id,
|
|
||||||
"nume" to nume,
|
|
||||||
"type" to type
|
|
||||||
),
|
|
||||||
headers = mapOf("X-Requested-With" to "XMLHttpRequest"),
|
|
||||||
referer = url
|
|
||||||
).parsed<ResponseHash>().embed_url.let { fixUrl(it) }
|
).parsed<ResponseHash>().embed_url.let { fixUrl(it) }
|
||||||
|
|
||||||
when {
|
when {
|
||||||
|
@ -569,10 +537,7 @@ object SoraExtractor : SoraStream() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
!source.contains("youtube") -> loadExtractor(
|
!source.contains("youtube") -> loadExtractor(
|
||||||
source,
|
source, "$uniqueStreamAPI/", subtitleCallback, callback
|
||||||
"$uniqueStreamAPI/",
|
|
||||||
subtitleCallback,
|
|
||||||
callback
|
|
||||||
)
|
)
|
||||||
else -> {
|
else -> {
|
||||||
// pass
|
// pass
|
||||||
|
@ -602,8 +567,7 @@ object SoraExtractor : SoraStream() {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
doc.select("table.table-striped tbody tr")
|
doc.select("table.table-striped tbody tr")
|
||||||
.find { it.text().contains("Episode $episode") }
|
.find { it.text().contains("Episode $episode") }?.select("td")?.map {
|
||||||
?.select("td")?.map {
|
|
||||||
it.select("a").attr("href") to it.select("a").text()
|
it.select("a").attr("href") to it.select("a").text()
|
||||||
}
|
}
|
||||||
} ?: return
|
} ?: return
|
||||||
|
@ -771,9 +735,7 @@ object SoraExtractor : SoraStream() {
|
||||||
callback: (ExtractorLink) -> Unit
|
callback: (ExtractorLink) -> Unit
|
||||||
) {
|
) {
|
||||||
val headers = mapOf(
|
val headers = mapOf(
|
||||||
"lang" to "en",
|
"lang" to "en", "versioncode" to "11", "clienttype" to "ios_jike_default"
|
||||||
"versioncode" to "11",
|
|
||||||
"clienttype" to "ios_jike_default"
|
|
||||||
)
|
)
|
||||||
val vipAPI =
|
val vipAPI =
|
||||||
base64DecodeAPI("cA==YXA=cy8=Y20=di8=LnQ=b2s=a2w=bG8=aS4=YXA=ZS0=aWw=b2I=LW0=Z2E=Ly8=czo=dHA=aHQ=")
|
base64DecodeAPI("cA==YXA=cy8=Y20=di8=LnQ=b2s=a2w=bG8=aS4=YXA=ZS0=aWw=b2I=LW0=Z2E=Ly8=czo=dHA=aHQ=")
|
||||||
|
@ -786,8 +748,7 @@ object SoraExtractor : SoraStream() {
|
||||||
val scriptData = doc.select("div.search-list div.search-video-card").map {
|
val scriptData = doc.select("div.search-list div.search-video-card").map {
|
||||||
Triple(
|
Triple(
|
||||||
it.selectFirst("h2.title")?.text().toString(),
|
it.selectFirst("h2.title")?.text().toString(),
|
||||||
it.selectFirst("div.desc")?.text()
|
it.selectFirst("div.desc")?.text()?.substringBefore(".")?.toIntOrNull(),
|
||||||
?.substringBefore(".")?.toIntOrNull(),
|
|
||||||
it.selectFirst("a")?.attr("href")?.split("/")
|
it.selectFirst("a")?.attr("href")?.split("/")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -799,20 +760,17 @@ object SoraExtractor : SoraStream() {
|
||||||
when (season) {
|
when (season) {
|
||||||
null -> {
|
null -> {
|
||||||
it.first.equals(
|
it.first.equals(
|
||||||
title,
|
title, true
|
||||||
true
|
|
||||||
) && it.second == year
|
) && it.second == year
|
||||||
}
|
}
|
||||||
1 -> {
|
1 -> {
|
||||||
it.first.contains(
|
it.first.contains(
|
||||||
"$title",
|
"$title", true
|
||||||
true
|
|
||||||
) && (it.second == year || it.first.contains("Season $season", true))
|
) && (it.second == year || it.first.contains("Season $season", true))
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
it.first.contains(
|
it.first.contains(
|
||||||
"$title",
|
"$title", true
|
||||||
true
|
|
||||||
) && it.second == year && it.first.contains("Season $season", true)
|
) && it.second == year && it.first.contains("Season $season", true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -823,8 +781,7 @@ object SoraExtractor : SoraStream() {
|
||||||
val type = script.third?.get(2) ?: return
|
val type = script.third?.get(2) ?: return
|
||||||
|
|
||||||
val jsonResponse = app.get(
|
val jsonResponse = app.get(
|
||||||
"$vipAPI/movieDrama/get?id=${id}&category=${type}",
|
"$vipAPI/movieDrama/get?id=${id}&category=${type}", headers = headers
|
||||||
headers = headers
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!jsonResponse.isSuccessful) return
|
if (!jsonResponse.isSuccessful) return
|
||||||
|
@ -836,8 +793,7 @@ object SoraExtractor : SoraStream() {
|
||||||
json?.subtitlingList?.map { sub ->
|
json?.subtitlingList?.map { sub ->
|
||||||
subtitleCallback.invoke(
|
subtitleCallback.invoke(
|
||||||
SubtitleFile(
|
SubtitleFile(
|
||||||
sub.language ?: "",
|
sub.language ?: "", sub.subtitlingUrl ?: return@map
|
||||||
sub.subtitlingUrl ?: return@map
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -908,13 +864,11 @@ object SoraExtractor : SoraStream() {
|
||||||
callback: (ExtractorLink) -> Unit
|
callback: (ExtractorLink) -> Unit
|
||||||
) {
|
) {
|
||||||
val fixTitle = title?.replace("–", "-")
|
val fixTitle = title?.replace("–", "-")
|
||||||
val id =
|
val id = app.get("$consumetFlixhqAPI/$title")
|
||||||
app.get("$consumetFlixhqAPI/$title")
|
|
||||||
.parsedSafe<ConsumetSearchResponse>()?.results?.find {
|
.parsedSafe<ConsumetSearchResponse>()?.results?.find {
|
||||||
if (season == null) {
|
if (season == null) {
|
||||||
it.title?.equals(
|
it.title?.equals(
|
||||||
"$fixTitle",
|
"$fixTitle", true
|
||||||
true
|
|
||||||
) == true && it.releaseDate?.equals("$year") == true && it.type == "Movie"
|
) == true && it.releaseDate?.equals("$year") == true && it.type == "Movie"
|
||||||
} else {
|
} else {
|
||||||
it.title?.equals("$fixTitle", true) == true && it.type == "TV Series"
|
it.title?.equals("$fixTitle", true) == true && it.type == "TV Series"
|
||||||
|
@ -931,16 +885,12 @@ object SoraExtractor : SoraStream() {
|
||||||
} ?: return
|
} ?: return
|
||||||
|
|
||||||
listOf(
|
listOf(
|
||||||
"vidcloud",
|
"vidcloud", "upcloud"
|
||||||
"upcloud"
|
|
||||||
).apmap { server ->
|
).apmap { server ->
|
||||||
delay(1000)
|
val sources = app.get(
|
||||||
val sources =
|
|
||||||
app.get(
|
|
||||||
"$consumetFlixhqAPI/watch?episodeId=$episodeId&mediaId=$id&server=$server",
|
"$consumetFlixhqAPI/watch?episodeId=$episodeId&mediaId=$id&server=$server",
|
||||||
timeout = 120L
|
timeout = 120L
|
||||||
)
|
).parsedSafe<ConsumetSourcesResponse>()
|
||||||
.parsedSafe<ConsumetSourcesResponse>()
|
|
||||||
val name = fixTitle(server)
|
val name = fixTitle(server)
|
||||||
sources?.sources?.map {
|
sources?.sources?.map {
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
|
@ -958,8 +908,7 @@ object SoraExtractor : SoraStream() {
|
||||||
sources?.subtitles?.map {
|
sources?.subtitles?.map {
|
||||||
subtitleCallback.invoke(
|
subtitleCallback.invoke(
|
||||||
SubtitleFile(
|
SubtitleFile(
|
||||||
it.lang ?: "",
|
it.lang ?: "", it.url ?: return@map null
|
||||||
it.url ?: return@map null
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -978,8 +927,7 @@ object SoraExtractor : SoraStream() {
|
||||||
) {
|
) {
|
||||||
val fixTitle = title?.replace("–", "-")
|
val fixTitle = title?.replace("–", "-")
|
||||||
val res = app.get(
|
val res = app.get(
|
||||||
"$kissKhAPI/api/DramaList/Search?q=$title&type=0",
|
"$kissKhAPI/api/DramaList/Search?q=$title&type=0", referer = "$kissKhAPI/"
|
||||||
referer = "$kissKhAPI/"
|
|
||||||
).text.let {
|
).text.let {
|
||||||
tryParseJson<ArrayList<KisskhResults>>(it)
|
tryParseJson<ArrayList<KisskhResults>>(it)
|
||||||
} ?: return
|
} ?: return
|
||||||
|
@ -993,8 +941,7 @@ object SoraExtractor : SoraStream() {
|
||||||
} else {
|
} else {
|
||||||
val data = res.find {
|
val data = res.find {
|
||||||
it.title?.contains(
|
it.title?.contains(
|
||||||
"$fixTitle",
|
"$fixTitle", true
|
||||||
true
|
|
||||||
) == true && it.title.contains("Season $season", true)
|
) == true && it.title.contains("Season $season", true)
|
||||||
}
|
}
|
||||||
data?.id to data?.title
|
data?.id to data?.title
|
||||||
|
@ -1002,8 +949,7 @@ object SoraExtractor : SoraStream() {
|
||||||
}
|
}
|
||||||
|
|
||||||
val resDetail = app.get(
|
val resDetail = app.get(
|
||||||
"$kissKhAPI/api/DramaList/Drama/$id?isq=false",
|
"$kissKhAPI/api/DramaList/Drama/$id?isq=false", referer = "$kissKhAPI/Drama/${
|
||||||
referer = "$kissKhAPI/Drama/${
|
|
||||||
getKisskhTitle(contentTitle)
|
getKisskhTitle(contentTitle)
|
||||||
}?id=$id"
|
}?id=$id"
|
||||||
).parsedSafe<KisskhDetail>() ?: return
|
).parsedSafe<KisskhDetail>() ?: return
|
||||||
|
@ -1042,8 +988,7 @@ object SoraExtractor : SoraStream() {
|
||||||
tryParseJson<List<KisskhSubtitle>>(resSub)?.map { sub ->
|
tryParseJson<List<KisskhSubtitle>>(resSub)?.map { sub ->
|
||||||
subtitleCallback.invoke(
|
subtitleCallback.invoke(
|
||||||
SubtitleFile(
|
SubtitleFile(
|
||||||
getLanguage(sub.label ?: return@map),
|
getLanguage(sub.label ?: return@map), sub.src ?: return@map
|
||||||
sub.src ?: return@map
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1060,27 +1005,17 @@ object SoraExtractor : SoraStream() {
|
||||||
callback: (ExtractorLink) -> Unit
|
callback: (ExtractorLink) -> Unit
|
||||||
) {
|
) {
|
||||||
val malId = app.get("$tmdb2mal/?id=$id&s=$season").text.trim()
|
val malId = app.get("$tmdb2mal/?id=$id&s=$season").text.trim()
|
||||||
val (engTitle, japTitle) = app.get("https://animixplay.to/assets/mal/$malId.json")
|
val anilistId = app.post(
|
||||||
.parsedSafe<AnimixData>()?.let {
|
"https://graphql.anilist.co/", data = mapOf(
|
||||||
it.title_english to it.title
|
"query" to "{Media(idMal:$malId,type:ANIME){id}}",
|
||||||
} ?: return
|
)
|
||||||
|
).parsedSafe<DataAni>()?.data?.media?.id
|
||||||
|
|
||||||
val animeId =
|
val episodeId = app.get("$consumetAnilistAPI/info/$anilistId?provider=zoro")
|
||||||
app.get("$consumetZoroAPI/$japTitle")
|
|
||||||
.parsedSafe<ConsumetSearchResponse>()?.results?.find {
|
|
||||||
val title = it.title ?: return
|
|
||||||
(title.equals(engTitle, true) || title.equals(
|
|
||||||
japTitle,
|
|
||||||
true
|
|
||||||
)) && it.type == "TV"
|
|
||||||
}?.id ?: return
|
|
||||||
|
|
||||||
val episodeId = app.get("$consumetZoroAPI/info?id=$animeId")
|
|
||||||
.parsedSafe<ConsumetDetails>()?.episodes?.find {
|
.parsedSafe<ConsumetDetails>()?.episodes?.find {
|
||||||
it.number == episode
|
it.number == episode
|
||||||
}?.id ?: return
|
}?.id ?: return
|
||||||
|
|
||||||
delay(1000)
|
|
||||||
val sources = app.get("$consumetZoroAPI/watch?episodeId=$episodeId", timeout = 120L)
|
val sources = app.get("$consumetZoroAPI/watch?episodeId=$episodeId", timeout = 120L)
|
||||||
.parsedSafe<ConsumetSourcesResponse>() ?: return
|
.parsedSafe<ConsumetSourcesResponse>() ?: return
|
||||||
|
|
||||||
|
@ -1137,8 +1072,7 @@ object SoraExtractor : SoraStream() {
|
||||||
} else {
|
} else {
|
||||||
scriptData.find {
|
scriptData.find {
|
||||||
it.first?.contains(
|
it.first?.contains(
|
||||||
"$fixTitle",
|
"$fixTitle", true
|
||||||
true
|
|
||||||
) == true && it.second?.contains("$year") == true
|
) == true && it.second?.contains("$year") == true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1155,12 +1089,7 @@ object SoraExtractor : SoraStream() {
|
||||||
val link = Regex("((https:|http:)//.*\\.mp4)").find(source.text)?.value ?: return
|
val link = Regex("((https:|http:)//.*\\.mp4)").find(source.text)?.value ?: return
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
"Ling",
|
"Ling", "Ling", link, "$lingAPI/", Qualities.Unknown.value, headers = mapOf(
|
||||||
"Ling",
|
|
||||||
link,
|
|
||||||
"$lingAPI/",
|
|
||||||
Qualities.Unknown.value,
|
|
||||||
headers = mapOf(
|
|
||||||
"Range" to "bytes=0-"
|
"Range" to "bytes=0-"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -1203,8 +1132,7 @@ object SoraExtractor : SoraStream() {
|
||||||
val detailDoc = app.get(script?.first ?: return).document
|
val detailDoc = app.get(script?.first ?: return).document
|
||||||
|
|
||||||
val iframeList = detailDoc.select("div.entry-content p").map { it }
|
val iframeList = detailDoc.select("div.entry-content p").map { it }
|
||||||
.filter { it.text().filterIframe(season, lastSeason, year) }
|
.filter { it.text().filterIframe(season, lastSeason, year) }.mapNotNull {
|
||||||
.mapNotNull {
|
|
||||||
if (season == null) {
|
if (season == null) {
|
||||||
it.text() to it.nextElementSibling()?.select("a")?.attr("href")
|
it.text() to it.nextElementSibling()?.select("a")?.attr("href")
|
||||||
} else {
|
} else {
|
||||||
|
@ -1215,8 +1143,7 @@ object SoraExtractor : SoraStream() {
|
||||||
|
|
||||||
val iframe = if (iframeList.any { it.first.contains("2160p", true) }) iframeList.filter {
|
val iframe = if (iframeList.any { it.first.contains("2160p", true) }) iframeList.filter {
|
||||||
it.first.contains(
|
it.first.contains(
|
||||||
"2160p",
|
"2160p", true
|
||||||
true
|
|
||||||
)
|
)
|
||||||
} else iframeList.filter { it.first.contains("1080p", true) }
|
} else iframeList.filter { it.first.contains("1080p", true) }
|
||||||
|
|
||||||
|
@ -1270,8 +1197,7 @@ object SoraExtractor : SoraStream() {
|
||||||
) {
|
) {
|
||||||
val request = app.get("$fwatayakoAPI/IAF0wWTdNYZm?imdb_id=$imdbId")
|
val request = app.get("$fwatayakoAPI/IAF0wWTdNYZm?imdb_id=$imdbId")
|
||||||
if (!request.isSuccessful) return
|
if (!request.isSuccessful) return
|
||||||
val files = request.document.selectFirst("input#files")?.attr("value")
|
val files = request.document.selectFirst("input#files")?.attr("value").let {
|
||||||
.let {
|
|
||||||
if (season == null) {
|
if (season == null) {
|
||||||
it?.replace("\"381\"", "\"movie\"")
|
it?.replace("\"381\"", "\"movie\"")
|
||||||
} else {
|
} else {
|
||||||
|
@ -1332,8 +1258,7 @@ object SoraExtractor : SoraStream() {
|
||||||
}
|
}
|
||||||
})?.filter {
|
})?.filter {
|
||||||
it.first.contains("gdtot") && (it.second.contains(
|
it.first.contains("gdtot") && (it.second.contains(
|
||||||
"1080p",
|
"1080p", true
|
||||||
true
|
|
||||||
) || it.second.contains("4k", true))
|
) || it.second.contains("4k", true))
|
||||||
} ?: return
|
} ?: return
|
||||||
|
|
||||||
|
@ -1380,8 +1305,7 @@ object SoraExtractor : SoraStream() {
|
||||||
)
|
)
|
||||||
}.filter {
|
}.filter {
|
||||||
(it.quality.contains("1080p", true) || it.quality.contains(
|
(it.quality.contains("1080p", true) || it.quality.contains(
|
||||||
"4k",
|
"4k", true
|
||||||
true
|
|
||||||
)) && (it.type.contains("gdtot") || it.type.contains("oiya"))
|
)) && (it.type.contains("gdtot") || it.type.contains("oiya"))
|
||||||
}
|
}
|
||||||
Log.i("hexated", "$iframe")
|
Log.i("hexated", "$iframe")
|
||||||
|
@ -1436,8 +1360,7 @@ object SoraExtractor : SoraStream() {
|
||||||
} else {
|
} else {
|
||||||
scriptData.find {
|
scriptData.find {
|
||||||
it.first?.contains(
|
it.first?.contains(
|
||||||
"Watch Free ${title?.replace(":", "")}",
|
"Watch Free ${title?.replace(":", "")}", true
|
||||||
true
|
|
||||||
) == true && (it.first?.contains("$year") == true || it.second?.contains(
|
) == true && (it.first?.contains("$year") == true || it.second?.contains(
|
||||||
"$year"
|
"$year"
|
||||||
) == true)
|
) == true)
|
||||||
|
@ -1464,16 +1387,11 @@ object SoraExtractor : SoraStream() {
|
||||||
?: return
|
?: return
|
||||||
val idepisode = episodeData.select("button").attr("idepisode") ?: return
|
val idepisode = episodeData.select("button").attr("idepisode") ?: return
|
||||||
val requestEmbed = app.post(
|
val requestEmbed = app.post(
|
||||||
"$m4uhdAPI/ajaxtv",
|
"$m4uhdAPI/ajaxtv", data = mapOf(
|
||||||
data = mapOf(
|
"idepisode" to idepisode, "_token" to "$token"
|
||||||
"idepisode" to idepisode,
|
), referer = link, headers = mapOf(
|
||||||
"_token" to "$token"
|
|
||||||
),
|
|
||||||
referer = link,
|
|
||||||
headers = mapOf(
|
|
||||||
"X-Requested-With" to "XMLHttpRequest",
|
"X-Requested-With" to "XMLHttpRequest",
|
||||||
),
|
), cookies = mapOf(
|
||||||
cookies = mapOf(
|
|
||||||
"laravel_session" to "$session",
|
"laravel_session" to "$session",
|
||||||
"XSRF-TOKEN" to "$xsrf",
|
"XSRF-TOKEN" to "$xsrf",
|
||||||
)
|
)
|
||||||
|
@ -1491,8 +1409,7 @@ object SoraExtractor : SoraStream() {
|
||||||
val iframe = app.post(
|
val iframe = app.post(
|
||||||
"$m4uhdAPI/ajax",
|
"$m4uhdAPI/ajax",
|
||||||
data = mapOf(
|
data = mapOf(
|
||||||
"m4u" to m4uData,
|
"m4u" to m4uData, "_token" to "$token"
|
||||||
"_token" to "$token"
|
|
||||||
),
|
),
|
||||||
referer = link,
|
referer = link,
|
||||||
headers = mapOf(
|
headers = mapOf(
|
||||||
|
@ -1525,7 +1442,8 @@ object SoraExtractor : SoraStream() {
|
||||||
|
|
||||||
val server = getTvMoviesServer(url, season, episode) ?: return
|
val server = getTvMoviesServer(url, season, episode) ?: return
|
||||||
val videoData = extractCovyn(server.second ?: return)
|
val videoData = extractCovyn(server.second ?: return)
|
||||||
val quality = Regex("([0-9]{3,4})p").find(server.first)?.groupValues?.getOrNull(1)?.toIntOrNull()
|
val quality =
|
||||||
|
Regex("([0-9]{3,4})p").find(server.first)?.groupValues?.getOrNull(1)?.toIntOrNull()
|
||||||
|
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
|
@ -1543,24 +1461,30 @@ object SoraExtractor : SoraStream() {
|
||||||
suspend fun invokeCrunchyroll(
|
suspend fun invokeCrunchyroll(
|
||||||
title: String? = null,
|
title: String? = null,
|
||||||
epsTitle: String? = null,
|
epsTitle: String? = null,
|
||||||
|
season: Int? = null,
|
||||||
|
episode: Int? = null,
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
callback: (ExtractorLink) -> Unit
|
callback: (ExtractorLink) -> Unit
|
||||||
) {
|
) {
|
||||||
val id = app.get("$consumetCrunchyrollAPI/$title")
|
val id = app.get("$consumetCrunchyrollAPI/$title")
|
||||||
.parsedSafe<ConsumetSearchResponse>()?.results?.find {
|
.parsedSafe<ConsumetSearchResponse>()?.results?.find {
|
||||||
it.title.equals(
|
it.title.equals(
|
||||||
title,
|
title, true
|
||||||
true
|
|
||||||
) && it.type.equals("series")
|
) && it.type.equals("series")
|
||||||
} ?: return
|
} ?: return
|
||||||
|
|
||||||
val detail = app.get("$consumetCrunchyrollAPI/info?id=${id.id}&mediaType=series").text
|
val detail = app.get("$consumetCrunchyrollAPI/info?id=${id.id}&mediaType=series").text
|
||||||
val episodeId = tryParseJson<ConsumetDetails>(detail)?.episodes?.filter {
|
val episodeId = tryParseJson<ConsumetDetails>(detail)?.episodes?.filter {
|
||||||
it.title.equals(epsTitle, true) && (it.type == "Subbed" || it.type == "English Dub")
|
(if (season == 1) {
|
||||||
|
it.title.equals(
|
||||||
|
epsTitle, true
|
||||||
|
) || it.number == episode
|
||||||
|
} else {
|
||||||
|
it.title.equals(epsTitle, true)
|
||||||
|
}) && (it.type == "Subbed" || it.type == "English Dub")
|
||||||
}?.map { it.id to it.type } ?: return
|
}?.map { it.id to it.type } ?: return
|
||||||
|
|
||||||
episodeId.apmap { (id, type) ->
|
episodeId.apmap { (id, type) ->
|
||||||
delay(1000)
|
|
||||||
val json = app.get("$consumetCrunchyrollAPI/watch?episodeId=$id&format=srt")
|
val json = app.get("$consumetCrunchyrollAPI/watch?episodeId=$id&format=srt")
|
||||||
.parsedSafe<ConsumetSourcesResponse>()
|
.parsedSafe<ConsumetSourcesResponse>()
|
||||||
|
|
||||||
|
@ -1759,3 +1683,15 @@ data class PreviewVideos(
|
||||||
@JsonProperty("mediaUrl") val mediaUrl: String? = null,
|
@JsonProperty("mediaUrl") val mediaUrl: String? = null,
|
||||||
@JsonProperty("currentDefinition") val currentDefinition: String? = null,
|
@JsonProperty("currentDefinition") val currentDefinition: String? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
data class IdAni(
|
||||||
|
@JsonProperty("id") val id: String? = null,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class MediaAni(
|
||||||
|
@JsonProperty("Media") val media: IdAni? = null,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class DataAni(
|
||||||
|
@JsonProperty("data") val data: MediaAni? = null,
|
||||||
|
)
|
|
@ -54,6 +54,7 @@ open class SoraStream : TmdbProvider() {
|
||||||
base64DecodeAPI("ZTM=NTg=MjM=MjM=ODc=MzI=OGQ=MmE=Nzk=Nzk=ZjI=NTA=NDY=NDA=MzA=YjA=") // PLEASE DON'T STEAL
|
base64DecodeAPI("ZTM=NTg=MjM=MjM=ODc=MzI=OGQ=MmE=Nzk=Nzk=ZjI=NTA=NDY=NDA=MzA=YjA=") // PLEASE DON'T STEAL
|
||||||
const val tmdb2mal = "https://tmdb2mal.slidemovies.org"
|
const val tmdb2mal = "https://tmdb2mal.slidemovies.org"
|
||||||
const val gdbot = "https://gdbot.xyz"
|
const val gdbot = "https://gdbot.xyz"
|
||||||
|
const val consumetAnilistAPI = "https://api.consumet.org/meta/anilist"
|
||||||
|
|
||||||
private val mainAPI =
|
private val mainAPI =
|
||||||
base64DecodeAPI("cHA=LmE=ZWw=cmM=dmU=aC4=dGM=d2E=eHA=Ly8=czo=dHA=aHQ=")
|
base64DecodeAPI("cHA=LmE=ZWw=cmM=dmU=aC4=dGM=d2E=eHA=Ly8=czo=dHA=aHQ=")
|
||||||
|
@ -79,7 +80,7 @@ open class SoraStream : TmdbProvider() {
|
||||||
const val consumetCrunchyrollAPI = "https://api.consumet.org/anime/crunchyroll"
|
const val consumetCrunchyrollAPI = "https://api.consumet.org/anime/crunchyroll"
|
||||||
const val kissKhAPI = "https://kisskh.me"
|
const val kissKhAPI = "https://kisskh.me"
|
||||||
const val lingAPI = "https://ling-online.net"
|
const val lingAPI = "https://ling-online.net"
|
||||||
const val uhdmoviesAPI = "https://uhdmovies.site"
|
const val uhdmoviesAPI = "https://uhdmovies.org.in"
|
||||||
const val fwatayakoAPI = "https://5100.svetacdn.in"
|
const val fwatayakoAPI = "https://5100.svetacdn.in"
|
||||||
const val gMoviesAPI = "https://gdrivemovies.xyz"
|
const val gMoviesAPI = "https://gdrivemovies.xyz"
|
||||||
const val fdMoviesAPI = "https://freedrivemovie.com"
|
const val fdMoviesAPI = "https://freedrivemovie.com"
|
||||||
|
@ -162,18 +163,13 @@ open class SoraStream : TmdbProvider() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun search(query: String): List<SearchResponse> {
|
override suspend fun search(query: String): List<SearchResponse>? {
|
||||||
val searchResponse = mutableListOf<SearchResponse>()
|
return app.get(
|
||||||
|
|
||||||
val mainResponse = app.get(
|
|
||||||
"$tmdbAPI/search/multi?api_key=$apiKey&language=en-US&query=$query&page=1&include_adult=${settingsForProvider.enableAdult}",
|
"$tmdbAPI/search/multi?api_key=$apiKey&language=en-US&query=$query&page=1&include_adult=${settingsForProvider.enableAdult}",
|
||||||
referer = "$mainAPI/"
|
referer = "$mainAPI/"
|
||||||
).parsedSafe<Results>()?.results?.mapNotNull { media ->
|
).parsedSafe<Results>()?.results?.mapNotNull { media ->
|
||||||
media.toSearchResponse()
|
media.toSearchResponse()
|
||||||
}
|
}
|
||||||
if (mainResponse?.isNotEmpty() == true) searchResponse.addAll(mainResponse)
|
|
||||||
|
|
||||||
return searchResponse
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun load(url: String): LoadResponse? {
|
override suspend fun load(url: String): LoadResponse? {
|
||||||
|
@ -246,7 +242,7 @@ open class SoraStream : TmdbProvider() {
|
||||||
newTvSeriesLoadResponse(
|
newTvSeriesLoadResponse(
|
||||||
title,
|
title,
|
||||||
url,
|
url,
|
||||||
TvType.TvSeries,
|
if(isAnime) TvType.Anime else TvType.TvSeries,
|
||||||
episodes
|
episodes
|
||||||
) {
|
) {
|
||||||
this.posterUrl = poster
|
this.posterUrl = poster
|
||||||
|
@ -355,6 +351,8 @@ open class SoraStream : TmdbProvider() {
|
||||||
if (res.season != null && res.isAnime) invokeCrunchyroll(
|
if (res.season != null && res.isAnime) invokeCrunchyroll(
|
||||||
res.title,
|
res.title,
|
||||||
res.epsTitle,
|
res.epsTitle,
|
||||||
|
res.season,
|
||||||
|
res.episode,
|
||||||
subtitleCallback,
|
subtitleCallback,
|
||||||
callback
|
callback
|
||||||
)
|
)
|
||||||
|
|
|
@ -174,7 +174,7 @@ suspend fun extractGdflix(url: String): String? {
|
||||||
?.attr("href") ?: return null
|
?.attr("href") ?: return null
|
||||||
val base = getBaseUrl(iframeGdflix)
|
val base = getBaseUrl(iframeGdflix)
|
||||||
|
|
||||||
val gdfDoc = app.get(iframeGdflix).document.selectFirst("script")?.data()?.substringAfter("replace(\"")
|
val gdfDoc = app.get(iframeGdflix).document.selectFirst("script:containsData(replace)")?.data()?.substringAfter("replace(\"")
|
||||||
?.substringBefore("\")")?.let {
|
?.substringBefore("\")")?.let {
|
||||||
app.get(fixUrl(it, base)).document
|
app.get(fixUrl(it, base)).document
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue