fixed shinobi in sora & fixed Hdfilmcehennemi title

This commit is contained in:
hexated 2023-02-25 04:32:34 +07:00
parent c82488fcbc
commit 97df334b18
8 changed files with 134 additions and 57 deletions

View file

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

View file

@ -42,7 +42,7 @@ class Hdfilmcehennemi : MainAPI() {
} }
private fun Element.toSearchResult(): SearchResponse? { private fun Element.toSearchResult(): SearchResponse? {
val title = this.selectFirst("a")?.text() ?: return null val title = this.selectFirst("h2.title")?.text() ?: return null
val href = fixUrlNull(this.selectFirst("a")?.attr("href")) ?: return null val href = fixUrlNull(this.selectFirst("a")?.attr("href")) ?: return null
val posterUrl = fixUrlNull(this.selectFirst("img")?.attr("data-src")) val posterUrl = fixUrlNull(this.selectFirst("img")?.attr("data-src"))
return newMovieSearchResponse(title, href, TvType.Movie) { return newMovieSearchResponse(title, href, TvType.Movie) {

View file

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

View file

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

View file

@ -709,61 +709,30 @@ object SoraExtractor : SoraStream() {
season: Int? = null, season: Int? = null,
episode: Int? = null, episode: Int? = null,
subtitleCallback: (SubtitleFile) -> Unit, subtitleCallback: (SubtitleFile) -> Unit,
) {
val (id, type) = getSoraIdAndType(title, year, season) ?: return
val json = fetchSoraEpisodes(id, type, episode) ?: return
json.subtitlingList?.map { sub ->
subtitleCallback.invoke(
SubtitleFile(
getVipLanguage(sub.languageAbbr ?: return@map),
sub.subtitlingUrl ?: return@map
)
)
}
}
suspend fun invokeSoraStreamLite(
title: String? = null,
year: Int? = null,
season: Int? = null,
episode: Int? = null,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit, callback: (ExtractorLink) -> Unit,
) { ) {
val headers = mapOf( val (id, type) = getSoraIdAndType(title, year, season) ?: return
"lang" to "en", val json = fetchSoraEpisodes(id, type, episode) ?: return
"versioncode" to "32",
"clienttype" to "android_tem3",
)
val vipAPI =
base64DecodeAPI("cA==YXA=cy8=Y20=di8=LnQ=b2s=a2w=bG8=aS4=YXA=ZS0=aWw=b2I=LW0=Z2E=Ly8=czo=dHA=aHQ=")
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(Regex("(?i)$title\\s?($season|${season.toRomanNumeral()}|Season\\s$season)")) && it.second == year
}
}
}
}
val id = script?.third?.last() ?: return
val type = script.third?.get(2) ?: return
val json = app.get(
"$vipAPI/movieDrama/get?id=${id}&category=${type}",
headers = headers
).parsedSafe<Load>()?.data?.episodeVo?.find {
it.seriesNo == (episode ?: 0)
} ?: return
json.subtitlingList?.map { sub -> json.subtitlingList?.map { sub ->
subtitleCallback.invoke( subtitleCallback.invoke(
@ -774,6 +743,23 @@ object SoraExtractor : SoraStream() {
) )
} }
json.definitionList?.map { video ->
val media = app.get(
"${soraAPI}/media/previewInfo?category=${type}&contentId=${id}&episodeId=${json.id}&definition=${video.code}",
headers = soraHeaders,
).parsedSafe<SorastreamResponse>()?.data
callback.invoke(
ExtractorLink(
this.name,
this.name,
media?.mediaUrl ?: return@map null,
"",
getSoraQuality(media.currentDefinition ?: ""),
true,
)
)
}
} }
suspend fun invokeXmovies( suspend fun invokeXmovies(
@ -2415,7 +2401,7 @@ object SoraExtractor : SoraStream() {
"$api $tags [$size]", "$api $tags [$size]",
"$api $tags [$size]", "$api $tags [$size]",
path, path,
"", if(api in needRefererIndex) apiUrl else "",
quality, quality,
) )
) )
@ -2927,3 +2913,12 @@ data class TgarData(
data class Gdflix( data class Gdflix(
@JsonProperty("url") val url: String @JsonProperty("url") val url: String
) )
data class SorastreamResponse(
@JsonProperty("data") val data: SorastreamVideos? = null,
)
data class SorastreamVideos(
@JsonProperty("mediaUrl") val mediaUrl: String? = null,
@JsonProperty("currentDefinition") val currentDefinition: String? = null,
)

View file

@ -168,6 +168,7 @@ open class SoraStream : TmdbProvider() {
"$tmdbAPI/discover/tv?api_key=$apiKey&with_networks=453" to "Hulu", "$tmdbAPI/discover/tv?api_key=$apiKey&with_networks=453" to "Hulu",
"$tmdbAPI/discover/tv?api_key=$apiKey&with_networks=2552" to "Apple TV+", "$tmdbAPI/discover/tv?api_key=$apiKey&with_networks=2552" to "Apple TV+",
"$tmdbAPI/discover/tv?api_key=$apiKey&with_networks=49" to "HBO", "$tmdbAPI/discover/tv?api_key=$apiKey&with_networks=49" to "HBO",
"$tmdbAPI/discover/tv?api_key=$apiKey&with_networks=4330" to "Paramount+",
"$tmdbAPI/movie/top_rated?api_key=$apiKey&region=US" to "Top Rated Movies", "$tmdbAPI/movie/top_rated?api_key=$apiKey&region=US" to "Top Rated Movies",
"$tmdbAPI/tv/top_rated?api_key=$apiKey&region=US" to "Top Rated TV Shows", "$tmdbAPI/tv/top_rated?api_key=$apiKey&region=US" to "Top Rated TV Shows",
"$tmdbAPI/movie/upcoming?api_key=$apiKey&region=US" to "Upcoming Movies", "$tmdbAPI/movie/upcoming?api_key=$apiKey&region=US" to "Upcoming Movies",
@ -355,7 +356,6 @@ open class SoraStream : TmdbProvider() {
res.season, res.season,
res.episode, res.episode,
subtitleCallback, subtitleCallback,
callback,
) )
}, },
{ {

View file

@ -21,6 +21,7 @@ import com.hexated.SoraExtractor.invokeRStream
import com.hexated.SoraExtractor.invokeSeries9 import com.hexated.SoraExtractor.invokeSeries9
import com.hexated.SoraExtractor.invokeSmashyStream import com.hexated.SoraExtractor.invokeSmashyStream
import com.hexated.SoraExtractor.invokeSoraStream import com.hexated.SoraExtractor.invokeSoraStream
import com.hexated.SoraExtractor.invokeSoraStreamLite
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
@ -53,7 +54,7 @@ class SoraStreamLite : SoraStream() {
) )
}, },
{ {
invokeSoraStream( invokeSoraStreamLite(
res.title, res.title,
res.year, res.year,
res.season, res.season,

View file

@ -1,6 +1,7 @@
package com.hexated package com.hexated
import android.util.Base64 import android.util.Base64
import com.hexated.SoraStream.Companion.base64DecodeAPI
import com.hexated.SoraStream.Companion.baymoviesAPI import com.hexated.SoraStream.Companion.baymoviesAPI
import com.hexated.SoraStream.Companion.consumetCrunchyrollAPI import com.hexated.SoraStream.Companion.consumetCrunchyrollAPI
import com.hexated.SoraStream.Companion.filmxyAPI import com.hexated.SoraStream.Companion.filmxyAPI
@ -35,6 +36,15 @@ import kotlin.collections.ArrayList
import kotlin.collections.HashMap import kotlin.collections.HashMap
import kotlin.math.min import kotlin.math.min
val soraAPI = base64DecodeAPI("cA==YXA=cy8=Y20=di8=LnQ=b2s=a2w=bG8=aS4=YXA=ZS0=aWw=b2I=LW0=Z2E=Ly8=czo=dHA=aHQ=")
val soraHeaders = mapOf(
"lang" to "en",
"versioncode" to "32",
"clienttype" to "android_tem3",
"deviceid" to getDeviceId(),
)
val encodedIndex = arrayOf( val encodedIndex = arrayOf(
"GamMovies", "GamMovies",
"JSMovies", "JSMovies",
@ -67,6 +77,10 @@ val untrimmedIndex = arrayOf(
"EdithxMovies", "EdithxMovies",
) )
val needRefererIndex = arrayOf(
"ShinobiMovies",
)
val mimeType = arrayOf( val mimeType = arrayOf(
"video/x-matroska", "video/x-matroska",
"video/mp4", "video/mp4",
@ -442,6 +456,56 @@ suspend fun invokeSmashyTwo(
) )
} }
suspend fun getSoraIdAndType(title: String?, year: Int?, season: Int?) : Pair<String, String>? {
val doc = app.get("${base64DecodeAPI("b20=LmM=b2s=a2w=bG8=Ly8=czo=dHA=aHQ=")}/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(Regex("(?i)$title\\s?($season|${season.toRomanNumeral()}|Season\\s$season)")) && it.second == year
}
}
}
}
val id = script?.third?.last() ?: return null
val type = script.third?.get(2) ?: return null
return id to type
}
suspend fun fetchSoraEpisodes(id: String, type: String, episode: Int?) : EpisodeVo? {
return app.get(
"$soraAPI/movieDrama/get?id=${id}&category=${type}",
headers = soraHeaders
).parsedSafe<Load>()?.data?.episodeVo?.find {
it.seriesNo == (episode ?: 0)
}
}
suspend fun bypassOuo(url: String?): String? { suspend fun bypassOuo(url: String?): String? {
var res = session.get(url ?: return null) var res = session.get(url ?: return null)
run lit@{ run lit@{
@ -832,6 +896,16 @@ fun getGMoviesQuality(str: String): Int {
} }
} }
fun getSoraQuality(quality: String): Int {
return when (quality) {
"GROOT_FD" -> Qualities.P360.value
"GROOT_LD" -> Qualities.P480.value
"GROOT_SD" -> Qualities.P720.value
"GROOT_HD" -> Qualities.P1080.value
else -> Qualities.Unknown.value
}
}
fun getFDoviesQuality(str: String): String { fun getFDoviesQuality(str: String): String {
return when { return when {
str.contains("1080P", true) -> "1080P" str.contains("1080P", true) -> "1080P"
@ -858,6 +932,13 @@ fun getDbgoLanguage(str: String): String {
} }
} }
fun getDeviceId(length: Int = 16): String {
val allowedChars = ('a'..'f') + ('0'..'9')
return (1..length)
.map { allowedChars.random() }
.joinToString("")
}
fun String.encodeUrl(): String { fun String.encodeUrl(): String {
val url = URL(this) val url = URL(this)
val uri = URI(url.protocol, url.userInfo, url.host, url.port, url.path, url.query, url.ref) val uri = URI(url.protocol, url.userInfo, url.host, url.port, url.path, url.query, url.ref)