mirror of
https://github.com/hexated/cloudstream-extensions-hexated.git
synced 2024-08-15 00:03:22 +00:00
added new source into SoraExtractor
This commit is contained in:
parent
f2b6850716
commit
1cbdfc282d
3 changed files with 115 additions and 22 deletions
|
@ -1,5 +1,5 @@
|
||||||
// use an integer for version numbers
|
// use an integer for version numbers
|
||||||
version = 31
|
version = 32
|
||||||
|
|
||||||
|
|
||||||
cloudstream {
|
cloudstream {
|
||||||
|
|
|
@ -1046,20 +1046,8 @@ object SoraExtractor : SoraStream() {
|
||||||
link?.substringBefore("=http") ?: return@apmap null,
|
link?.substringBefore("=http") ?: return@apmap null,
|
||||||
"$kissKhAPI/",
|
"$kissKhAPI/",
|
||||||
subtitleCallback,
|
subtitleCallback,
|
||||||
) { links ->
|
callback
|
||||||
callback.invoke(
|
)
|
||||||
ExtractorLink(
|
|
||||||
"StreamSS",
|
|
||||||
"StreamSS",
|
|
||||||
links.url,
|
|
||||||
links.referer,
|
|
||||||
links.quality,
|
|
||||||
links.isM3u8,
|
|
||||||
links.headers,
|
|
||||||
links.extractorData
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1131,6 +1119,75 @@ object SoraExtractor : SoraStream() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun invokeLing(
|
||||||
|
title: String? = null,
|
||||||
|
year: Int? = null,
|
||||||
|
season: Int? = null,
|
||||||
|
episode: Int? = null,
|
||||||
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
|
callback: (ExtractorLink) -> Unit
|
||||||
|
) {
|
||||||
|
val fixTitle = title?.replace("–", "-")
|
||||||
|
val url = if(season == null) {
|
||||||
|
"$lingAPI/en/videos/films/?title=$fixTitle"
|
||||||
|
} else {
|
||||||
|
"$lingAPI/en/videos/serials/?title=$fixTitle"
|
||||||
|
}
|
||||||
|
|
||||||
|
val scriptData = app.get(url).document.select("div.blk.padding_b0 div.col-sm-30").map {
|
||||||
|
Triple(
|
||||||
|
it.selectFirst("div.video-body h5")?.text(),
|
||||||
|
it.selectFirst("div.video-body > p")?.text(),
|
||||||
|
it.selectFirst("div.video-body a")?.attr("href"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val script = if (scriptData.size == 1) {
|
||||||
|
scriptData.first()
|
||||||
|
} else {
|
||||||
|
scriptData.find {
|
||||||
|
it.first?.contains("$fixTitle", true) == true && it.second?.contains("$year") == true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val doc = app.get(fixUrl(script?.third ?: return, lingAPI)).document
|
||||||
|
val iframe = (if(season == null) {
|
||||||
|
doc.selectFirst("a.video-js.vjs-default-skin")?.attr("data-href")
|
||||||
|
} else {
|
||||||
|
doc.select("div.blk div#tab_$season li")[episode!!.minus(1)].select("h5 a").attr("data-href")
|
||||||
|
})?.let { fixUrl(it, lingAPI) }
|
||||||
|
|
||||||
|
val source = app.get(iframe ?: return)
|
||||||
|
val link = Regex("((https:|http:)//.*\\.mp4)").find(source.text)?.value ?: return
|
||||||
|
val quality = when {
|
||||||
|
link.contains("1080p") -> Qualities.P1080.value
|
||||||
|
link.contains("720p") -> Qualities.P720.value
|
||||||
|
else -> Qualities.Unknown.value
|
||||||
|
}
|
||||||
|
callback.invoke(
|
||||||
|
ExtractorLink(
|
||||||
|
"Ling",
|
||||||
|
"Ling",
|
||||||
|
link,
|
||||||
|
"$lingAPI/",
|
||||||
|
quality,
|
||||||
|
headers = mapOf(
|
||||||
|
"Range" to "bytes=0-"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
source.document.select("div#player-tracks track").map {
|
||||||
|
subtitleCallback.invoke(
|
||||||
|
SubtitleFile(
|
||||||
|
SubtitleHelper.fromTwoLettersToLanguage(it.attr("srclang")) ?: return@map null,
|
||||||
|
it.attr("src")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class FilmxyCookies(
|
data class FilmxyCookies(
|
||||||
|
|
|
@ -22,6 +22,7 @@ import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
|
import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
|
||||||
import com.lagradost.cloudstream3.metaproviders.TmdbProvider
|
import com.lagradost.cloudstream3.metaproviders.TmdbProvider
|
||||||
import com.hexated.SoraExtractor.invoZoro
|
import com.hexated.SoraExtractor.invoZoro
|
||||||
|
import com.hexated.SoraExtractor.invokeLing
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.toJson
|
import com.lagradost.cloudstream3.utils.AppUtils.toJson
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
|
@ -67,6 +68,7 @@ open class SoraStream : TmdbProvider() {
|
||||||
const val consumetFlixhqAPI = "https://api.consumet.org/movies/flixhq"
|
const val consumetFlixhqAPI = "https://api.consumet.org/movies/flixhq"
|
||||||
const val consumetZoroAPI = "https://api.consumet.org/anime/zoro"
|
const val consumetZoroAPI = "https://api.consumet.org/anime/zoro"
|
||||||
const val kissKhAPI = "https://kisskh.me"
|
const val kissKhAPI = "https://kisskh.me"
|
||||||
|
const val lingAPI = "https://ling-online.net"
|
||||||
|
|
||||||
fun getType(t: String?): TvType {
|
fun getType(t: String?): TvType {
|
||||||
return when (t) {
|
return when (t) {
|
||||||
|
@ -181,9 +183,13 @@ open class SoraStream : TmdbProvider() {
|
||||||
?: throw ErrorLoadingException("Invalid Json Response")
|
?: throw ErrorLoadingException("Invalid Json Response")
|
||||||
val res = responses.result ?: return null
|
val res = responses.result ?: return null
|
||||||
val title = res.title ?: res.name ?: return null
|
val title = res.title ?: res.name ?: return null
|
||||||
|
val poster = getOriImageUrl(res.backdropPath)
|
||||||
val orgTitle = res.originalTitle ?: res.originalName ?: return null
|
val orgTitle = res.originalTitle ?: res.originalName ?: return null
|
||||||
val type = getType(data.type)
|
val type = getType(data.type)
|
||||||
val year = (res.releaseDate ?: res.firstAirDate)?.split("-")?.first()?.toIntOrNull()
|
val year = (res.releaseDate ?: res.firstAirDate)?.split("-")?.first()?.toIntOrNull()
|
||||||
|
val genres = res.genres?.mapNotNull { it.name }
|
||||||
|
val show =
|
||||||
|
if (genres?.contains("Animation") == true && res.original_language == "ja") "Anime" else "Series/Movies"
|
||||||
|
|
||||||
val actors = responses.cast?.mapNotNull { cast ->
|
val actors = responses.cast?.mapNotNull { cast ->
|
||||||
ActorData(
|
ActorData(
|
||||||
|
@ -216,6 +222,8 @@ open class SoraStream : TmdbProvider() {
|
||||||
title = title,
|
title = title,
|
||||||
year = season.airDate?.split("-")?.first()?.toIntOrNull(),
|
year = season.airDate?.split("-")?.first()?.toIntOrNull(),
|
||||||
orgTitle = orgTitle,
|
orgTitle = orgTitle,
|
||||||
|
show = show,
|
||||||
|
airedYear = year
|
||||||
).toJson(),
|
).toJson(),
|
||||||
name = eps.name,
|
name = eps.name,
|
||||||
season = eps.seasonNumber,
|
season = eps.seasonNumber,
|
||||||
|
@ -234,10 +242,10 @@ open class SoraStream : TmdbProvider() {
|
||||||
TvType.TvSeries,
|
TvType.TvSeries,
|
||||||
episodes
|
episodes
|
||||||
) {
|
) {
|
||||||
this.posterUrl = getOriImageUrl(res.backdropPath)
|
this.posterUrl = poster
|
||||||
this.year = year
|
this.year = year
|
||||||
this.plot = res.overview
|
this.plot = res.overview
|
||||||
this.tags = res.genres?.mapNotNull { it.name }
|
this.tags = genres
|
||||||
this.showStatus = getStatus(res.status)
|
this.showStatus = getStatus(res.status)
|
||||||
this.recommendations = recommendations
|
this.recommendations = recommendations
|
||||||
this.actors = actors
|
this.actors = actors
|
||||||
|
@ -255,12 +263,13 @@ open class SoraStream : TmdbProvider() {
|
||||||
title = title,
|
title = title,
|
||||||
year = year,
|
year = year,
|
||||||
orgTitle = orgTitle,
|
orgTitle = orgTitle,
|
||||||
|
show = show,
|
||||||
).toJson(),
|
).toJson(),
|
||||||
) {
|
) {
|
||||||
this.posterUrl = getOriImageUrl(res.backdropPath)
|
this.posterUrl = poster
|
||||||
this.year = year
|
this.year = year
|
||||||
this.plot = res.overview
|
this.plot = res.overview
|
||||||
this.tags = res.genres?.mapNotNull { it.name }
|
this.tags = genres
|
||||||
this.recommendations = recommendations
|
this.recommendations = recommendations
|
||||||
this.actors = actors
|
this.actors = actors
|
||||||
addTrailer(trailer)
|
addTrailer(trailer)
|
||||||
|
@ -362,7 +371,7 @@ open class SoraStream : TmdbProvider() {
|
||||||
// )
|
// )
|
||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
if (res.season != null) invoZoro(
|
if (res.season != null && res.show == "Anime") invoZoro(
|
||||||
res.id,
|
res.id,
|
||||||
res.season,
|
res.season,
|
||||||
res.episode,
|
res.episode,
|
||||||
|
@ -406,14 +415,38 @@ open class SoraStream : TmdbProvider() {
|
||||||
invokeKimcartoon(res.title, res.season, res.episode, subtitleCallback, callback)
|
invokeKimcartoon(res.title, res.season, res.episode, subtitleCallback, callback)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
invokeXmovies(res.title, res.year, res.season, res.episode, subtitleCallback, callback)
|
invokeXmovies(
|
||||||
|
res.title,
|
||||||
|
res.year,
|
||||||
|
res.season,
|
||||||
|
res.episode,
|
||||||
|
subtitleCallback,
|
||||||
|
callback
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
invokeFlixhq(res.title, res.year, res.season, res.episode, subtitleCallback, callback)
|
invokeFlixhq(
|
||||||
|
res.title,
|
||||||
|
res.year,
|
||||||
|
res.season,
|
||||||
|
res.episode,
|
||||||
|
subtitleCallback,
|
||||||
|
callback
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
invoKisskh(res.title, res.season, res.episode, subtitleCallback, callback)
|
invoKisskh(res.title, res.season, res.episode, subtitleCallback, callback)
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
invokeLing(
|
||||||
|
res.title,
|
||||||
|
res.airedYear ?: res.year,
|
||||||
|
res.season,
|
||||||
|
res.episode,
|
||||||
|
subtitleCallback,
|
||||||
|
callback
|
||||||
|
)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
@ -430,6 +463,8 @@ open class SoraStream : TmdbProvider() {
|
||||||
val title: String? = null,
|
val title: String? = null,
|
||||||
val year: Int? = null,
|
val year: Int? = null,
|
||||||
val orgTitle: String? = null,
|
val orgTitle: String? = null,
|
||||||
|
val show: String? = null,
|
||||||
|
val airedYear: Int? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class Data(
|
data class Data(
|
||||||
|
@ -525,6 +560,7 @@ open class SoraStream : TmdbProvider() {
|
||||||
@JsonProperty("release_date") val releaseDate: String? = null,
|
@JsonProperty("release_date") val releaseDate: String? = null,
|
||||||
@JsonProperty("first_air_date") val firstAirDate: String? = null,
|
@JsonProperty("first_air_date") val firstAirDate: String? = null,
|
||||||
@JsonProperty("overview") val overview: String? = null,
|
@JsonProperty("overview") val overview: String? = null,
|
||||||
|
@JsonProperty("original_language") val original_language: String? = null,
|
||||||
@JsonProperty("status") val status: String? = null,
|
@JsonProperty("status") val status: String? = null,
|
||||||
@JsonProperty("genres") val genres: ArrayList<Genres>? = arrayListOf(),
|
@JsonProperty("genres") val genres: ArrayList<Genres>? = arrayListOf(),
|
||||||
@JsonProperty("seasons") val seasons: ArrayList<Seasons>? = arrayListOf(),
|
@JsonProperty("seasons") val seasons: ArrayList<Seasons>? = arrayListOf(),
|
||||||
|
|
Loading…
Reference in a new issue