mirror of
https://github.com/hexated/cloudstream-extensions-hexated.git
synced 2024-08-15 00:03:22 +00:00
[Sora] fixed some sources and improvement
This commit is contained in:
parent
d12b118c7e
commit
5ac2e599f3
3 changed files with 170 additions and 94 deletions
|
@ -1,5 +1,5 @@
|
||||||
// use an integer for version numbers
|
// use an integer for version numbers
|
||||||
version = 70
|
version = 71
|
||||||
|
|
||||||
|
|
||||||
cloudstream {
|
cloudstream {
|
||||||
|
|
|
@ -520,28 +520,17 @@ object SoraExtractor : SoraStream() {
|
||||||
"Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"
|
"Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"
|
||||||
)
|
)
|
||||||
).document
|
).document
|
||||||
val srcm3u8 =
|
val srcm3u8 = resDoc.selectFirst("script:containsData(let url =)")?.data()?.let {
|
||||||
resDoc.selectFirst("script:containsData(let url =)")?.data()?.let {
|
|
||||||
Regex("['|\"](.*?.m3u8)['|\"]").find(it)?.groupValues?.getOrNull(1)
|
Regex("['|\"](.*?.m3u8)['|\"]").find(it)?.groupValues?.getOrNull(1)
|
||||||
} ?: return@apmap null
|
|
||||||
val quality = app.get(
|
|
||||||
srcm3u8, referer = source, headers = mapOf(
|
|
||||||
"Accept" to "*/*",
|
|
||||||
)
|
|
||||||
).text.let { quality ->
|
|
||||||
if (quality.contains("RESOLUTION=1920")) Qualities.P1080.value else Qualities.P720.value
|
|
||||||
}
|
}
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
"UniqueStream",
|
"UniqueStream",
|
||||||
"UniqueStream",
|
"UniqueStream",
|
||||||
srcm3u8,
|
srcm3u8 ?: return@apmap null,
|
||||||
source,
|
source,
|
||||||
quality,
|
Qualities.P1080.value,
|
||||||
true,
|
true,
|
||||||
headers = mapOf(
|
|
||||||
"Accept" to "*/*",
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -759,67 +748,71 @@ object SoraExtractor : SoraStream() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun invokeSoraVIP(
|
private suspend fun invokeNetMovies(
|
||||||
title: String? = null,
|
id: String? = null,
|
||||||
year: Int? = null,
|
type: String? = null,
|
||||||
season: Int? = null,
|
episode: Int? = null,
|
||||||
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
|
callback: (ExtractorLink) -> Unit
|
||||||
|
) {
|
||||||
|
val jsonResponse = app.get(
|
||||||
|
"$netMoviesAPI/detail?category=$type&id=$id",
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!jsonResponse.isSuccessful) return
|
||||||
|
val epsId = jsonResponse.parsedSafe<Load>()?.data?.episodeVo?.find {
|
||||||
|
it.seriesNo == (episode ?: 0)
|
||||||
|
}?.id
|
||||||
|
|
||||||
|
val sources = app.get("$netMoviesAPI/episode?category=$type&id=$id&episode=$epsId")
|
||||||
|
.parsedSafe<NetMoviesSources>()?.data ?: return
|
||||||
|
|
||||||
|
sources.subtitles?.map { sub ->
|
||||||
|
subtitleCallback.invoke(
|
||||||
|
SubtitleFile(
|
||||||
|
sub.language ?: "",
|
||||||
|
sub.url ?: return@map null
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
sources.qualities?.map { source ->
|
||||||
|
callback.invoke(
|
||||||
|
ExtractorLink(
|
||||||
|
"NetMovies",
|
||||||
|
"NetMovies",
|
||||||
|
source.url ?: return@map null,
|
||||||
|
"",
|
||||||
|
source.quality?.toIntOrNull() ?: Qualities.Unknown.value,
|
||||||
|
isM3u8 = true,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun invokeLoklok(
|
||||||
|
id: String? = null,
|
||||||
|
type: String? = null,
|
||||||
episode: Int? = null,
|
episode: Int? = null,
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
callback: (ExtractorLink) -> Unit
|
callback: (ExtractorLink) -> Unit
|
||||||
) {
|
) {
|
||||||
val headers = mapOf(
|
val headers = mapOf(
|
||||||
"lang" to "en", "versioncode" to "11", "clienttype" to "ios_jike_default"
|
"lang" to "en",
|
||||||
|
"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=")
|
||||||
val vipUrl = base64DecodeAPI("b20=LmM=b2s=a2w=bG8=Ly8=czo=dHA=aHQ=")
|
|
||||||
|
|
||||||
val doc = app.get(
|
|
||||||
"$vipUrl/search?keyword=$title",
|
|
||||||
).document
|
|
||||||
|
|
||||||
val scriptData = doc.select("div.search-list div.search-video-card").map {
|
|
||||||
Triple(
|
|
||||||
it.selectFirst("h2.title")?.text().toString(),
|
|
||||||
it.selectFirst("div.desc")?.text()?.substringBefore(".")?.toIntOrNull(),
|
|
||||||
it.selectFirst("a")?.attr("href")?.split("/")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val script = if (scriptData.size == 1) {
|
|
||||||
scriptData.firstOrNull()
|
|
||||||
} else {
|
|
||||||
scriptData.find {
|
|
||||||
when (season) {
|
|
||||||
null -> {
|
|
||||||
it.first.equals(
|
|
||||||
title, true
|
|
||||||
) && it.second == year
|
|
||||||
}
|
|
||||||
1 -> {
|
|
||||||
it.first.contains(
|
|
||||||
"$title", true
|
|
||||||
) && (it.second == year || it.first.contains("Season $season", true))
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
it.first.contains(
|
|
||||||
"$title", true
|
|
||||||
) && it.second == year && it.first.contains("Season $season", true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val id = script?.third?.last() ?: return
|
|
||||||
val type = script.third?.get(2) ?: return
|
|
||||||
|
|
||||||
val jsonResponse = app.get(
|
val jsonResponse = app.get(
|
||||||
"$vipAPI/movieDrama/get?id=${id}&category=${type}", headers = headers
|
"$vipAPI/movieDrama/get?id=${id}&category=${type}",
|
||||||
|
headers = headers
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!jsonResponse.isSuccessful) return
|
if (!jsonResponse.isSuccessful) return
|
||||||
|
val json = jsonResponse.parsedSafe<Load>()?.data?.episodeVo?.find {
|
||||||
val json = jsonResponse.parsedSafe<Load>()?.data?.episodeVo?.first {
|
|
||||||
it.seriesNo == (episode ?: 0)
|
it.seriesNo == (episode ?: 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -855,6 +848,69 @@ object SoraExtractor : SoraStream() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun invokeSoraStream(
|
||||||
|
title: String? = null,
|
||||||
|
year: Int? = null,
|
||||||
|
season: Int? = null,
|
||||||
|
episode: Int? = null,
|
||||||
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
|
callback: (ExtractorLink) -> Unit
|
||||||
|
) {
|
||||||
|
val searchUrl = base64DecodeAPI("b20=LmM=b2s=a2w=bG8=Ly8=czo=dHA=aHQ=")
|
||||||
|
val doc = app.get(
|
||||||
|
"$searchUrl/search?keyword=$title",
|
||||||
|
).document
|
||||||
|
|
||||||
|
val scriptData = doc.select("div.search-list div.search-video-card").map {
|
||||||
|
Triple(
|
||||||
|
it.selectFirst("h2.title")?.text().toString(),
|
||||||
|
it.selectFirst("div.desc")?.text()
|
||||||
|
?.substringBefore(".")?.toIntOrNull(),
|
||||||
|
it.selectFirst("a")?.attr("href")?.split("/")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val script = if (scriptData.size == 1) {
|
||||||
|
scriptData.firstOrNull()
|
||||||
|
} else {
|
||||||
|
scriptData.find {
|
||||||
|
when (season) {
|
||||||
|
null -> {
|
||||||
|
it.first.equals(
|
||||||
|
title,
|
||||||
|
true
|
||||||
|
) && it.second == year
|
||||||
|
}
|
||||||
|
1 -> {
|
||||||
|
it.first.contains(
|
||||||
|
"$title",
|
||||||
|
true
|
||||||
|
) && (it.second == year || it.first.contains("Season $season", true))
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
it.first.contains(
|
||||||
|
"$title",
|
||||||
|
true
|
||||||
|
) && it.second == year && it.first.contains("Season $season", true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val id = script?.third?.last() ?: return
|
||||||
|
val type = script.third?.get(2) ?: return
|
||||||
|
|
||||||
|
argamap(
|
||||||
|
{
|
||||||
|
invokeLoklok(id, type, episode, subtitleCallback, callback)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
invokeNetMovies(id, type, episode, subtitleCallback, callback)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun invokeXmovies(
|
suspend fun invokeXmovies(
|
||||||
title: String? = null,
|
title: String? = null,
|
||||||
year: Int? = null,
|
year: Int? = null,
|
||||||
|
@ -1060,13 +1116,7 @@ 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 anilistId = app.post(
|
val episodeId = app.get("$consumetMalAPI/info/$malId?provider=zoro")
|
||||||
"https://graphql.anilist.co/", data = mapOf(
|
|
||||||
"query" to "{Media(idMal:$malId,type:ANIME){id}}",
|
|
||||||
)
|
|
||||||
).parsedSafe<DataAni>()?.data?.media?.id
|
|
||||||
|
|
||||||
val episodeId = app.get("$consumetAnilistAPI/info/$anilistId?provider=zoro")
|
|
||||||
.parsedSafe<ConsumetDetails>()?.episodes?.find {
|
.parsedSafe<ConsumetDetails>()?.episodes?.find {
|
||||||
it.number == episode
|
it.number == episode
|
||||||
}?.id?.substringBeforeLast("$") ?: return
|
}?.id?.substringBeforeLast("$") ?: return
|
||||||
|
@ -1204,14 +1254,31 @@ object SoraExtractor : SoraStream() {
|
||||||
}
|
}
|
||||||
}.filter { it.second?.contains(Regex("(https:)|(http:)")) == true }
|
}.filter { it.second?.contains(Regex("(https:)|(http:)")) == true }
|
||||||
|
|
||||||
val iframe = if (iframeList.any { it.first.contains("2160p", true) }) iframeList.filter {
|
val sources = mutableListOf<Pair<String, String?>>()
|
||||||
|
if (iframeList.any {
|
||||||
it.first.contains(
|
it.first.contains(
|
||||||
"2160p", true
|
"2160p",
|
||||||
|
true
|
||||||
)
|
)
|
||||||
} else iframeList.filter { it.first.contains("1080p", true) }
|
}) {
|
||||||
|
sources.addAll(iframeList.filter {
|
||||||
|
it.first.contains(
|
||||||
|
"2160p",
|
||||||
|
true
|
||||||
|
)
|
||||||
|
})
|
||||||
|
sources.add(iframeList.first {
|
||||||
|
it.first.contains(
|
||||||
|
"1080p",
|
||||||
|
true
|
||||||
|
)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
sources.addAll(iframeList.filter { it.first.contains("1080p", true) })
|
||||||
|
}
|
||||||
|
|
||||||
val base = "https://drivebit.in"
|
val base = "https://drivebit.in"
|
||||||
iframe.apmap { (quality, link) ->
|
sources.apmap { (quality, link) ->
|
||||||
delay(2000)
|
delay(2000)
|
||||||
val driveLink = bypassHrefli(link ?: return@apmap null)
|
val driveLink = bypassHrefli(link ?: return@apmap null)
|
||||||
val res = app.get(driveLink ?: return@apmap null).document
|
val res = app.get(driveLink ?: return@apmap null).document
|
||||||
|
@ -1721,7 +1788,7 @@ object SoraExtractor : SoraStream() {
|
||||||
|
|
||||||
if(!app.get(url).isSuccessful) return
|
if(!app.get(url).isSuccessful) return
|
||||||
|
|
||||||
delay(5000)
|
delay(4000)
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
"RStream",
|
"RStream",
|
||||||
|
@ -1812,6 +1879,26 @@ data class Load(
|
||||||
@JsonProperty("data") val data: MediaDetail? = null,
|
@JsonProperty("data") val data: MediaDetail? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
data class NetMoviesSubtitles(
|
||||||
|
@JsonProperty("lang") val lang: String? = null,
|
||||||
|
@JsonProperty("language") val language: String? = null,
|
||||||
|
@JsonProperty("url") val url: String? = null,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class NetMoviesQualities(
|
||||||
|
@JsonProperty("quality") val quality: String? = null,
|
||||||
|
@JsonProperty("url") val url: String? = null,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class NetMoviesData(
|
||||||
|
@JsonProperty("subtitles") val subtitles: ArrayList<NetMoviesSubtitles>? = arrayListOf(),
|
||||||
|
@JsonProperty("qualities") val qualities: ArrayList<NetMoviesQualities>? = arrayListOf(),
|
||||||
|
)
|
||||||
|
|
||||||
|
data class NetMoviesSources(
|
||||||
|
@JsonProperty("data") val data: NetMoviesData? = null,
|
||||||
|
)
|
||||||
|
|
||||||
data class ConsumetHeaders(
|
data class ConsumetHeaders(
|
||||||
@JsonProperty("Referer") val referer: String? = null,
|
@JsonProperty("Referer") val referer: String? = null,
|
||||||
)
|
)
|
||||||
|
@ -1912,18 +1999,6 @@ data class PreviewVideos(
|
||||||
@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,
|
|
||||||
)
|
|
||||||
|
|
||||||
data class Safelink(
|
data class Safelink(
|
||||||
@JsonProperty("safelink") val safelink: String? = null,
|
@JsonProperty("safelink") val safelink: String? = null,
|
||||||
)
|
)
|
||||||
|
|
|
@ -12,7 +12,6 @@ import com.hexated.SoraExtractor.invokeKimcartoon
|
||||||
import com.hexated.SoraExtractor.invokeMovieHab
|
import com.hexated.SoraExtractor.invokeMovieHab
|
||||||
import com.hexated.SoraExtractor.invokeNoverse
|
import com.hexated.SoraExtractor.invokeNoverse
|
||||||
import com.hexated.SoraExtractor.invokeSeries9
|
import com.hexated.SoraExtractor.invokeSeries9
|
||||||
import com.hexated.SoraExtractor.invokeSoraVIP
|
|
||||||
import com.hexated.SoraExtractor.invokeTwoEmbed
|
import com.hexated.SoraExtractor.invokeTwoEmbed
|
||||||
import com.hexated.SoraExtractor.invokeUniqueStream
|
import com.hexated.SoraExtractor.invokeUniqueStream
|
||||||
import com.hexated.SoraExtractor.invokeVidSrc
|
import com.hexated.SoraExtractor.invokeVidSrc
|
||||||
|
@ -30,6 +29,7 @@ import com.hexated.SoraExtractor.invokeM4uhd
|
||||||
import com.hexated.SoraExtractor.invokeMoviesbay
|
import com.hexated.SoraExtractor.invokeMoviesbay
|
||||||
import com.hexated.SoraExtractor.invokeMoviezAdd
|
import com.hexated.SoraExtractor.invokeMoviezAdd
|
||||||
import com.hexated.SoraExtractor.invokeRStream
|
import com.hexated.SoraExtractor.invokeRStream
|
||||||
|
import com.hexated.SoraExtractor.invokeSoraStream
|
||||||
import com.hexated.SoraExtractor.invokeTvMovies
|
import com.hexated.SoraExtractor.invokeTvMovies
|
||||||
import com.hexated.SoraExtractor.invokeUhdmovies
|
import com.hexated.SoraExtractor.invokeUhdmovies
|
||||||
import com.hexated.SoraExtractor.invokeZoro
|
import com.hexated.SoraExtractor.invokeZoro
|
||||||
|
@ -58,12 +58,13 @@ 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"
|
const val consumetMalAPI = "https://api.consumet.org/meta/mal"
|
||||||
|
|
||||||
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=")
|
||||||
|
|
||||||
// private var mainServerAPI = base64DecodeAPI("cA==YXA=bC4=Y2U=ZXI=LnY=aWU=b3Y=LW0=cmE=c28=Ly8=czo=dHA=aHQ=")
|
// private var mainServerAPI = base64DecodeAPI("cA==YXA=bC4=Y2U=ZXI=LnY=aWU=b3Y=LW0=cmE=c28=Ly8=czo=dHA=aHQ=")
|
||||||
|
var netMoviesAPI = base64DecodeAPI("aQ==YXA=cC8=YXA=bC4=Y2U=ZXI=LnY=bG0=Zmk=dC0=bmU=Ly8=czo=dHA=aHQ=")
|
||||||
const val twoEmbedAPI = "https://www.2embed.to"
|
const val twoEmbedAPI = "https://www.2embed.to"
|
||||||
const val vidSrcAPI = "https://v2.vidsrc.me"
|
const val vidSrcAPI = "https://v2.vidsrc.me"
|
||||||
const val dbgoAPI = "https://dbgo.fun"
|
const val dbgoAPI = "https://dbgo.fun"
|
||||||
|
@ -75,7 +76,7 @@ open class SoraStream : TmdbProvider() {
|
||||||
const val idlixAPI = "https://idlixian.com"
|
const val idlixAPI = "https://idlixian.com"
|
||||||
const val noverseAPI = "https://www.nollyverse.com"
|
const val noverseAPI = "https://www.nollyverse.com"
|
||||||
const val olgplyAPI = "https://olgply.xyz"
|
const val olgplyAPI = "https://olgply.xyz"
|
||||||
const val uniqueStreamAPI = "https://uniquestream.net"
|
const val uniqueStreamAPI = "https://uniquestreaming.net"
|
||||||
const val filmxyAPI = "https://www.filmxy.vip"
|
const val filmxyAPI = "https://www.filmxy.vip"
|
||||||
const val kimcartoonAPI = "https://kimcartoon.li"
|
const val kimcartoonAPI = "https://kimcartoon.li"
|
||||||
const val xMovieAPI = "https://xemovies.to"
|
const val xMovieAPI = "https://xemovies.to"
|
||||||
|
@ -305,7 +306,7 @@ open class SoraStream : TmdbProvider() {
|
||||||
|
|
||||||
argamap(
|
argamap(
|
||||||
{
|
{
|
||||||
invokeSoraVIP(
|
invokeSoraStream(
|
||||||
res.title,
|
res.title,
|
||||||
res.year,
|
res.year,
|
||||||
res.season,
|
res.season,
|
||||||
|
|
Loading…
Reference in a new issue