sora: disable SfMovies & fix CinemaTv

This commit is contained in:
alex 2024-01-25 06:03:02 +07:00
parent 92a0b490d7
commit a340c9ebec
5 changed files with 55 additions and 60 deletions

View file

@ -1,7 +1,7 @@
import org.jetbrains.kotlin.konan.properties.Properties import org.jetbrains.kotlin.konan.properties.Properties
// use an integer for version numbers // use an integer for version numbers
version = 219 version = 220
android { android {
defaultConfig { defaultConfig {

View file

@ -2337,43 +2337,23 @@ object SoraExtractor : SoraStream() {
subtitleCallback: (SubtitleFile) -> Unit, subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit, callback: (ExtractorLink) -> Unit,
) { ) {
val id = imdbId?.removePrefix("tt") val media = app.get("$cinemaTvAPI/v1/${if (season == null) "movies" else "shows"}?filters[q]=$title")
val slug = title.createSlug() .parsedSafe<CinemaTvResponse>()?.items?.find {
val url = if (season == null) { it.imdb_id?.removePrefix("tt")
"$cinemaTvAPI/movies/play/$id-$slug-$year" .equals(imdbId?.removePrefix("tt")) || (it.title.equals(
title,
true
) && it.year == year)
} ?: return
val mediaId = if (season == null) {
media.id_movie
} else { } else {
"$cinemaTvAPI/shows/play/$id-$slug-$year" app.get("$cinemaTvAPI/v1/shows?expand=episodes&id=${media.id_show}")
} .parsedSafe<CinemaTvResponse>()?.episodes?.find { it.episode == episode && it.season == season }?.id
} ?: return
val session = val sources = app.get("$cinemaTvAPI/v1/${if (season == null) "movies" else "episodes"}/view?expand=streams,subtitles&id=$mediaId").parsedSafe<CinemaTvResponse>()
"PHPSESSID=ngr4cudjrimdnhkth30ssohs0n; _csrf=a6ffd7bb7654083fce6df528225a238d0e85aa1fb885dc7638c1259ec1ba0d5ca%3A2%3A%7Bi%3A0%3Bs%3A5%3A%22_csrf%22%3Bi%3A1%3Bs%3A32%3A%22mTTLiDLjxohs-CpKk0bjRH3HdYMB9uBV%22%3B%7D; _ga=GA1.1.1195498587.1701871187; _ga_VZD7HJ3WK6=GS1.1.$unixTime.4.0.1.$unixTime.0.0.0"
val headers = mapOf(
"Cookie" to session,
"x-requested-with" to "com.wwcinematv",
)
val doc = app.get(url, headers = headers).document
val script = doc.selectFirst("script:containsData(hash:)")?.data()
val hash = Regex("hash:\\s*['\"](\\S+)['\"]").find(script ?: return)?.groupValues?.get(1)
val expires = Regex("expires:\\s*(\\d+)").find(script)?.groupValues?.get(1)
val episodeId = (if (season == null) {
"""id_movie:\s*(\d+)"""
} else {
"""episode:\s*['"]$episode['"],[\n\s]+id_episode:\s*(\d+),[\n\s]+season:\s*['"]$season['"]"""
}).let { it.toRegex().find(script)?.groupValues?.get(1) }
val videoUrl = if (season == null) {
"$cinemaTvAPI/api/v1/security/movie-access?id_movie=$episodeId&hash=$hash&expires=$expires"
} else {
"$cinemaTvAPI/api/v1/security/episode-access?id_episode=$episodeId&hash=$hash&expires=$expires"
}
val sources = app.get(
videoUrl,
referer = url,
headers = mapOf("X-Requested-With" to "XMLHttpRequest")
).parsedSafe<CinemaTvResponse>()
sources?.streams?.mapKeys { source -> sources?.streams?.mapKeys { source ->
callback.invoke( callback.invoke(
@ -2381,19 +2361,18 @@ object SoraExtractor : SoraStream() {
"CinemaTv", "CinemaTv",
"CinemaTv", "CinemaTv",
source.value, source.value,
"$cinemaTvAPI/", "",
getQualityFromName(source.key), getQualityFromName(source.key),
true true
) )
) )
} }
sources?.subtitles?.map { sub -> sources?.subtitles?.map {
val file = sub.file.toString()
subtitleCallback.invoke( subtitleCallback.invoke(
SubtitleFile( SubtitleFile(
sub.language ?: return@map, it.language ?: return@map,
if (file.startsWith("[")) return@map else fixUrl(file, cinemaTvAPI), fixUrl(it.url ?: return@map, cinemaTvAPI)
) )
) )
} }

View file

@ -191,15 +191,31 @@ data class JikanResponse(
@JsonProperty("data") val data: JikanData? = null, @JsonProperty("data") val data: JikanData? = null,
) )
data class CinemaTvSubtitles(
@JsonProperty("language") val language: String? = null,
@JsonProperty("file") val file: Any? = null,
)
data class CinemaTvResponse( data class CinemaTvResponse(
@JsonProperty("items") val items: ArrayList<Items>? = arrayListOf(),
@JsonProperty("episodes") val episodes: ArrayList<Episodes>? = arrayListOf(),
@JsonProperty("streams") val streams: HashMap<String, String>? = null, @JsonProperty("streams") val streams: HashMap<String, String>? = null,
@JsonProperty("subtitles") val subtitles: ArrayList<CinemaTvSubtitles>? = arrayListOf(), @JsonProperty("subtitles") val subtitles: ArrayList<Subtitles>? = arrayListOf(),
) ) {
data class Items(
@JsonProperty("id_movie") val id_movie: Int? = null,
@JsonProperty("id_show") val id_show: Int? = null,
@JsonProperty("title") val title: String? = null,
@JsonProperty("year") val year: Int? = null,
@JsonProperty("imdb_id") val imdb_id: String? = null,
)
data class Episodes(
@JsonProperty("id") val id: Int? = null,
@JsonProperty("season") val season: Int? = null,
@JsonProperty("episode") val episode: Int? = null,
)
data class Subtitles(
@JsonProperty("language") val language: String? = null,
@JsonProperty("url") val url: String? = null,
)
}
data class VidsrctoResult( data class VidsrctoResult(
@JsonProperty("id") val id: String? = null, @JsonProperty("id") val id: String? = null,

View file

@ -717,12 +717,12 @@ open class SoraStream : TmdbProvider() {
callback callback
) )
}, },
{ // {
if (!res.isAnime) invokeSFMovies( // if (!res.isAnime) invokeSFMovies(
res.id, res.title, res.airedYear // res.id, res.title, res.airedYear
?: res.year, res.season, res.episode, callback // ?: res.year, res.season, res.episode, callback
) // )
}, // },
// { // {
// invokeMMovies(res.title, res.season, res.episode, subtitleCallback, callback) // invokeMMovies(res.title, res.season, res.episode, subtitleCallback, callback)
// }, // },

View file

@ -326,12 +326,12 @@ class SoraStreamLite : SoraStream() {
callback callback
) )
}, },
{ // {
if (!res.isAnime) invokeSFMovies( // if (!res.isAnime) invokeSFMovies(
res.id, res.title, res.airedYear // res.id, res.title, res.airedYear
?: res.year, res.season, res.episode, callback // ?: res.year, res.season, res.episode, callback
) // )
}, // },
// { // {
// invokeMMovies(res.title, res.season, res.episode, subtitleCallback, callback) // invokeMMovies(res.title, res.season, res.episode, subtitleCallback, callback)
// }, // },