[Sora] fixed some sources and improvement

This commit is contained in:
hexated 2023-01-09 03:23:44 +07:00
parent d12b118c7e
commit 5ac2e599f3
3 changed files with 170 additions and 94 deletions

View file

@ -1,5 +1,5 @@
// use an integer for version numbers // use an integer for version numbers
version = 70 version = 71
cloudstream { cloudstream {

View file

@ -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,
) )

View file

@ -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,