From 47f4e10078a7d0af6d19a875a5a3314878b9467d Mon Sep 17 00:00:00 2001 From: LagradOst <11805592+LagradOst@users.noreply.github.com> Date: Wed, 27 Jul 2022 19:36:31 +0200 Subject: [PATCH] added subtitles to ExtractorApi --- .../com/lagradost/cloudstream3/MainAPI.kt | 52 ++++---- .../animeproviders/AnimeFlickProvider.kt | 7 +- .../animeproviders/AnimeIndoProvider.kt | 3 +- .../animeproviders/AnimeSailProvider.kt | 10 +- .../animeproviders/AnimefenixProvider.kt | 7 +- .../animeproviders/AnimeflvIOProvider.kt | 8 +- .../animeproviders/AnimeflvProvider.kt | 2 +- .../animeproviders/AnimekisaProvider.kt | 4 +- .../animeproviders/GogoanimeProvider.kt | 12 +- .../animeproviders/GomunimeProvider.kt | 6 +- .../animeproviders/JKAnimeProvider.kt | 109 ++++++++++++----- .../animeproviders/KimCartoonProvider.kt | 9 +- .../animeproviders/KuronimeProvider.kt | 2 +- .../animeproviders/MonoschinosProvider.kt | 2 +- .../animeproviders/MundoDonghuaProvider.kt | 2 +- .../animeproviders/NeonimeProvider.kt | 2 +- .../animeproviders/NineAnimeProvider.kt | 2 +- .../animeproviders/NontonAnimeIDProvider.kt | 14 ++- .../animeproviders/OploverzProvider.kt | 2 +- .../animeproviders/OtakudesuProvider.kt | 2 +- .../animeproviders/WcoProvider.kt | 7 +- .../animeproviders/ZoroProvider.kt | 17 +-- .../cloudstream3/extractors/Pelisplus.kt | 23 ++-- .../extractors/VidSrcExtractor.kt | 44 ++++--- .../cloudstream3/extractors/Vidstream.kt | 20 +-- .../extractors/YoutubeExtractor.kt | 88 +++++++------- .../extractors/helper/AsianEmbedHelper.kt | 9 +- .../extractors/helper/VstreamhubHelper.kt | 18 ++- .../movieproviders/AllMoviesForYouProvider.kt | 4 +- .../movieproviders/AltadefinizioneProvider.kt | 80 ++++++------ .../movieproviders/BflixProvider.kt | 36 ++++-- .../movieproviders/CineblogProvider.kt | 4 +- .../movieproviders/CinecalidadProvider.kt | 115 ++++++++++-------- .../movieproviders/CuevanaProvider.kt | 6 +- .../movieproviders/DoramasYTProvider.kt | 2 +- .../movieproviders/DramaSeeProvider.kt | 7 +- .../movieproviders/DramaidProvider.kt | 2 +- .../movieproviders/ElifilmsProvider.kt | 2 +- .../EntrepeliculasyseriesProvider.kt | 2 +- .../movieproviders/EstrenosDoramasProvider.kt | 4 +- .../movieproviders/FilmanProvider.kt | 14 ++- .../movieproviders/FilmpertuttiProvider.kt | 6 +- .../movieproviders/FrenchStreamProvider.kt | 11 +- .../cloudstream3/movieproviders/HDMovie5.kt | 4 +- .../movieproviders/IHaveNoTvProvider.kt | 2 +- .../movieproviders/IdlixProvider.kt | 2 +- .../movieproviders/KdramaHoodProvider.kt | 29 +++-- .../movieproviders/LayarKacaProvider.kt | 2 +- .../movieproviders/OpenVidsProvider.kt | 2 +- .../movieproviders/PeliSmartProvider.kt | 2 +- .../movieproviders/PelisflixProvider.kt | 2 +- .../movieproviders/PelisplusHDProvider.kt | 2 +- .../PelisplusProviderTemplate.kt | 6 +- .../movieproviders/PinoyHDXyzProvider.kt | 2 +- .../movieproviders/PinoyMoviePediaProvider.kt | 2 +- .../movieproviders/PinoyMoviesEsProvider.kt | 68 +++++++---- .../movieproviders/RebahinProvider.kt | 7 +- .../movieproviders/SeriesflixProvider.kt | 2 +- .../movieproviders/SflixProvider.kt | 3 +- .../movieproviders/TantiFilmProvider.kt | 2 +- .../movieproviders/TwoEmbedProvider.kt | 2 +- .../VidstreamProviderTemplate.kt | 15 ++- .../movieproviders/WatchAsianProvider.kt | 45 +++---- .../movieproviders/YomoviesProvider.kt | 12 +- .../ui/player/AbstractPlayerFragment.kt | 1 + .../cloudstream3/ui/player/LinkGenerator.kt | 4 +- .../ui/player/PlayerSubtitleHelper.kt | 2 + .../cloudstream3/ui/result/ResultFragment.kt | 2 +- .../cloudstream3/utils/ExtractorApi.kt | 63 +++++++--- 69 files changed, 621 insertions(+), 442 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt index 185dadf5..cf3b253c 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt @@ -899,6 +899,11 @@ data class TvSeriesSearchResponse( override var posterHeaders: Map? = null, ) : SearchResponse +data class TrailerData( + var mirros: List, + var subtitles: List = emptyList(), +) + interface LoadResponse { var name: String var url: String @@ -910,7 +915,8 @@ interface LoadResponse { var rating: Int? // 0-10000 var tags: List? var duration: Int? // in minutes - var trailers: List? + var trailers: MutableList + var recommendations: List? var actors: List? var comingSoon: Boolean @@ -965,35 +971,25 @@ interface LoadResponse { /**better to call addTrailer with mutible trailers directly instead of calling this multiple times*/ suspend fun LoadResponse.addTrailer(trailerUrl: String?, referer: String? = null) { if (!isTrailersEnabled || trailerUrl == null) return - try { - val newTrailers = loadExtractor(trailerUrl, referer) - addTrailer(newTrailers) - } catch (e: Exception) { - logError(e) - } + val links = arrayListOf() + val subs = arrayListOf() + loadExtractor(trailerUrl, referer, { subs.add(it) }, { links.add(it) }) + this.trailers.add(TrailerData(links, subs)) } fun LoadResponse.addTrailer(newTrailers: List) { - if (this.trailers == null) { - this.trailers = newTrailers - } else { - val update = this.trailers?.toMutableList() ?: mutableListOf() - update.addAll(newTrailers) - this.trailers = update - } + trailers.addAll(newTrailers.map { TrailerData(listOf(it)) }) } suspend fun LoadResponse.addTrailer(trailerUrls: List?, referer: String? = null) { if (!isTrailersEnabled || trailerUrls == null) return - val newTrailers = trailerUrls.apmap { trailerUrl -> - try { - loadExtractor(trailerUrl, referer) - } catch (e: Exception) { - logError(e) - emptyList() - } - }.flatten().distinct() - addTrailer(newTrailers) + val trailers = trailerUrls.apmap { trailerUrl -> + val links = arrayListOf() + val subs = arrayListOf() + loadExtractor(trailerUrl, referer, { subs.add(it) }, { links.add(it) }) + links to subs + }.map { (links, subs) -> TrailerData(links, subs) } + this.trailers.addAll(trailers) } fun LoadResponse.addImdbId(id: String?) { @@ -1087,7 +1083,7 @@ data class TorrentLoadResponse( override var rating: Int? = null, override var tags: List? = null, override var duration: Int? = null, - override var trailers: List? = null, + override var trailers: MutableList = mutableListOf(), override var recommendations: List? = null, override var actors: List? = null, override var comingSoon: Boolean = false, @@ -1115,7 +1111,7 @@ data class AnimeLoadResponse( override var rating: Int? = null, override var duration: Int? = null, - override var trailers: List? = null, + override var trailers: MutableList = mutableListOf(), override var recommendations: List? = null, override var actors: List? = null, override var comingSoon: Boolean = false, @@ -1163,7 +1159,7 @@ data class LiveStreamLoadResponse( override var rating: Int? = null, override var tags: List? = null, override var duration: Int? = null, - override var trailers: List? = null, + override var trailers: MutableList = mutableListOf(), override var recommendations: List? = null, override var actors: List? = null, override var comingSoon: Boolean = false, @@ -1185,7 +1181,7 @@ data class MovieLoadResponse( override var rating: Int? = null, override var tags: List? = null, override var duration: Int? = null, - override var trailers: List? = null, + override var trailers: MutableList = mutableListOf(), override var recommendations: List? = null, override var actors: List? = null, override var comingSoon: Boolean = false, @@ -1306,7 +1302,7 @@ data class TvSeriesLoadResponse( override var rating: Int? = null, override var tags: List? = null, override var duration: Int? = null, - override var trailers: List? = null, + override var trailers: MutableList = mutableListOf(), override var recommendations: List? = null, override var actors: List? = null, override var comingSoon: Boolean = false, diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt index 9b172e16..2f58d1a8 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt @@ -56,8 +56,9 @@ class AnimeFlickProvider : MainAPI() { val title = doc.selectFirst("h2.title")!!.text() val yearText = doc.selectFirst(".trending-year")?.text() - val year = if (yearText != null) Regex("""(\d{4})""").find(yearText)?.destructured?.component1() - ?.toIntOrNull() else null + val year = + if (yearText != null) Regex("""(\d{4})""").find(yearText)?.destructured?.component1() + ?.toIntOrNull() else null val description = doc.selectFirst("p")?.text() val genres = doc.select("a[href*=\"genre-\"]").map { it.text() } @@ -95,7 +96,7 @@ class AnimeFlickProvider : MainAPI() { var alreadyAdded = false for (extractor in extractorApis) { if (link.startsWith(extractor.mainUrl)) { - extractor.getSafeUrl(link, data)?.forEach(callback) + extractor.getSafeUrl(link, data, subtitleCallback, callback) alreadyAdded = true break } diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeIndoProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeIndoProvider.kt index 38d2efb0..914975a2 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeIndoProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeIndoProvider.kt @@ -8,7 +8,6 @@ import com.lagradost.cloudstream3.utils.loadExtractor import com.lagradost.nicehttp.NiceResponse import org.jsoup.Jsoup import org.jsoup.nodes.Element -import java.util.ArrayList class AnimeIndoProvider : MainAPI() { override var mainUrl = "https://animeindo.sbs" @@ -183,7 +182,7 @@ class AnimeIndoProvider : MainAPI() { it } }.apmap { - loadExtractor(it, data, callback) + loadExtractor(it, data, subtitleCallback, callback) } return true diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeSailProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeSailProvider.kt index e5f38e0f..b1dc3fc3 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeSailProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeSailProvider.kt @@ -112,7 +112,8 @@ class AnimeSailProvider : MainAPI() { ) val episodes = document.select("ul.daftar > li").map { val header = it.select("a").text().trim() - val name = Regex("(Episode\\s?[0-9]+)").find(header)?.groupValues?.getOrNull(0) ?: header + val name = + Regex("(Episode\\s?[0-9]+)").find(header)?.groupValues?.getOrNull(0) ?: header val link = fixUrl(it.select("a").attr("href")) Episode(link, name = name) }.reversed() @@ -157,7 +158,8 @@ class AnimeSailProvider : MainAPI() { iframe.contains("/race/") -> "Race" else -> this.name } - val quality = Regex("\\.([0-9]{3,4})\\.").find(link)?.groupValues?.get(1) + val quality = + Regex("\\.([0-9]{3,4})\\.").find(link)?.groupValues?.get(1) callback.invoke( ExtractorLink( source = source, @@ -174,11 +176,11 @@ class AnimeSailProvider : MainAPI() { iframe.startsWith("$mainUrl/utils/player/framezilla/") || iframe.startsWith("https://uservideo.xyz") -> { request(iframe, ref = data).document.select("iframe").attr("src") .let { link -> - loadExtractor(fixUrl(link), mainUrl, callback) + loadExtractor(fixUrl(link), mainUrl, subtitleCallback, callback) } } else -> { - loadExtractor(iframe, mainUrl, callback) + loadExtractor(iframe, mainUrl, subtitleCallback, callback) } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimefenixProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimefenixProvider.kt index d00543d4..ee1ac5be 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimefenixProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimefenixProvider.kt @@ -2,11 +2,12 @@ package com.lagradost.cloudstream3.animeproviders import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.* -import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.AppUtils.parseJson +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.Qualities +import com.lagradost.cloudstream3.utils.loadExtractor import org.jsoup.Jsoup import java.util.* -import kotlin.collections.ArrayList class AnimefenixProvider:MainAPI() { @@ -179,7 +180,7 @@ class AnimefenixProvider:MainAPI() { else -> "" } - loadExtractor(links, data, callback) + loadExtractor(links, data, subtitleCallback, callback) argamap({ if (links.contains("AmaNormal")) { diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeflvIOProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeflvIOProvider.kt index aadfdcad..9a03c856 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeflvIOProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeflvIOProvider.kt @@ -2,11 +2,13 @@ package com.lagradost.cloudstream3.movieproviders import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.* -import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.AppUtils.parseJson +import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.M3u8Helper.Companion.generateM3u8 +import com.lagradost.cloudstream3.utils.Qualities +import com.lagradost.cloudstream3.utils.getQualityFromName +import com.lagradost.cloudstream3.utils.loadExtractor import java.util.* -import kotlin.collections.ArrayList class AnimeflvIOProvider:MainAPI() { override var mainUrl = "https://animeflv.io" //Also scrapes from animeid.to @@ -220,7 +222,7 @@ class AnimeflvIOProvider:MainAPI() { } } } - loadExtractor(url, data, callback) + loadExtractor(url, data, subtitleCallback, callback) } return true } diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeflvProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeflvProvider.kt index df40481b..561505aa 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeflvProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeflvProvider.kt @@ -173,7 +173,7 @@ class AnimeflvnetProvider : MainAPI() { it.replace("https://embedsb.com/e/", "https://watchsb.com/e/") .replace("https://ok.ru", "http://ok.ru") }.apmap { - loadExtractor(it, data, callback) + loadExtractor(it, data, subtitleCallback, callback) } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimekisaProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimekisaProvider.kt index c70cf86b..dab8e406 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimekisaProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimekisaProvider.kt @@ -2,8 +2,6 @@ package com.lagradost.cloudstream3.animeproviders import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.* -import com.lagradost.cloudstream3.mvvm.normalSafeApiCall -import com.lagradost.cloudstream3.mvvm.safeApiCall import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall import com.lagradost.cloudstream3.utils.AppUtils.parseJson import com.lagradost.cloudstream3.utils.ExtractorLink @@ -126,7 +124,7 @@ class AnimekisaProvider : MainAPI() { ): Boolean { app.get(data).document.select("#servers-list ul.nav li a").apmap { val server = it.attr("data-embed") - loadExtractor(server, data, callback) + loadExtractor(server, data, subtitleCallback, callback) } return true } diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt index e3118d35..a9a786ce 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt @@ -338,7 +338,11 @@ class GogoanimeProvider : MainAPI() { @JsonProperty("default") val default: String? = null ) - private suspend fun extractVideos(uri: String, callback: (ExtractorLink) -> Unit) { + private suspend fun extractVideos( + uri: String, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ) { val doc = app.get(uri).document val iframe = fixUrlNull(doc.selectFirst("div.play-video > iframe")?.attr("src")) ?: return @@ -366,7 +370,7 @@ class GogoanimeProvider : MainAPI() { ) } else { val url = it.attr("href") - loadExtractor(url, null, callback) + loadExtractor(url, null, subtitleCallback, callback) } } }, { @@ -378,7 +382,7 @@ class GogoanimeProvider : MainAPI() { val status = element.attr("data-status") ?: return@forEach if (status != "1") return@forEach val data = element.attr("data-video") ?: return@forEach - loadExtractor(data, streamingResponse.url, callback) + loadExtractor(data, streamingResponse.url, subtitleCallback, callback) } }, { val iv = "3134003223491201" @@ -405,7 +409,7 @@ class GogoanimeProvider : MainAPI() { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ): Boolean { - extractVideos(data, callback) + extractVideos(data, subtitleCallback, callback) return true } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GomunimeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GomunimeProvider.kt index c3d8d714..a816df25 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GomunimeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GomunimeProvider.kt @@ -145,7 +145,9 @@ class GomunimeProvider : MainAPI() { document.select(".bixbox.bxcl.epcheck > script").toString().trim() )?.groupValues?.get(1).toString().replace(Regex("""\\"""), "").trim() ).map { - val name = Regex("(Episode\\s?[0-9]+)").find(it.epTitle.toString())?.groupValues?.getOrNull(0) ?: it.epTitle + val name = + Regex("(Episode\\s?[0-9]+)").find(it.epTitle.toString())?.groupValues?.getOrNull(0) + ?: it.epTitle val link = it.epLink Episode(link, name) }.reversed() @@ -194,7 +196,7 @@ class GomunimeProvider : MainAPI() { safeApiCall { when { it.second.contains("frame") -> { - loadExtractor(it.first, data, callback) + loadExtractor(it.first, data, subtitleCallback, callback) } it.second.contains("hls") -> { app.post( diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/JKAnimeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/JKAnimeProvider.kt index c84c1fba..54f713de 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/JKAnimeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/JKAnimeProvider.kt @@ -3,12 +3,12 @@ package com.lagradost.cloudstream3.animeproviders import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.* -import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.AppUtils.parseJson +import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.M3u8Helper.Companion.generateM3u8 +import com.lagradost.cloudstream3.utils.getQualityFromName +import com.lagradost.cloudstream3.utils.loadExtractor import java.util.* -import kotlin.collections.ArrayList -import kotlin.collections.List class JKAnimeProvider : MainAPI() { @@ -34,9 +34,18 @@ class JKAnimeProvider : MainAPI() { override suspend fun getMainPage(): HomePageResponse { val urls = listOf( - Pair("$mainUrl/directorio/?filtro=fecha&tipo=TV&estado=1&fecha=none&temporada=none&orden=desc", "En emisión"), - Pair("$mainUrl/directorio/?filtro=fecha&tipo=none&estado=none&fecha=none&temporada=none&orden=none", "Animes"), - Pair("$mainUrl/directorio/?filtro=fecha&tipo=Movie&estado=none&fecha=none&temporada=none&orden=none", "Películas"), + Pair( + "$mainUrl/directorio/?filtro=fecha&tipo=TV&estado=1&fecha=none&temporada=none&orden=desc", + "En emisión" + ), + Pair( + "$mainUrl/directorio/?filtro=fecha&tipo=none&estado=none&fecha=none&temporada=none&orden=none", + "Animes" + ), + Pair( + "$mainUrl/directorio/?filtro=fecha&tipo=Movie&estado=none&fecha=none&temporada=none&orden=none", + "Películas" + ), ) val items = ArrayList() @@ -46,12 +55,14 @@ class JKAnimeProvider : MainAPI() { "Últimos episodios", app.get(mainUrl).document.select(".listadoanime-home a.bloqq").map { val title = it.selectFirst("h5")?.text() - val dubstat =if (title!!.contains("Latino") || title.contains("Castellano")) + val dubstat = if (title!!.contains("Latino") || title.contains("Castellano")) DubStatus.Dubbed else DubStatus.Subbed - val poster = it.selectFirst(".anime__sidebar__comment__item__pic img")?.attr("src") ?: "" + val poster = + it.selectFirst(".anime__sidebar__comment__item__pic img")?.attr("src") ?: "" val epRegex = Regex("/(\\d+)/|/especial/|/ova/") val url = it.attr("href").replace(epRegex, "") - val epNum = it.selectFirst("h6")?.text()?.replace("Episodio ", "")?.toIntOrNull() + val epNum = + it.selectFirst("h6")?.text()?.replace("Episodio ", "")?.toIntOrNull() newAnimeSearchResponse(title, url) { this.posterUrl = poster addDubStatus(dubstat, epNum) @@ -82,12 +93,12 @@ class JKAnimeProvider : MainAPI() { return HomePageResponse(items) } - data class MainSearch ( + data class MainSearch( @JsonProperty("animes") val animes: List, @JsonProperty("anime_types") val animeTypes: AnimeTypes ) - data class Animes ( + data class Animes( @JsonProperty("id") val id: String, @JsonProperty("slug") val slug: String, @JsonProperty("title") val title: String, @@ -98,7 +109,7 @@ class JKAnimeProvider : MainAPI() { @JsonProperty("thumbnail") val thumbnail: String ) - data class AnimeTypes ( + data class AnimeTypes( @JsonProperty("TV") val TV: String, @JsonProperty("OVA") val OVA: String, @JsonProperty("Movie") val Movie: String, @@ -134,7 +145,8 @@ class JKAnimeProvider : MainAPI() { val title = doc.selectFirst(".anime__details__title > h3")?.text() val type = doc.selectFirst(".anime__details__text")?.text() val description = doc.selectFirst(".anime__details__text > p")?.text() - val genres = doc.select("div.col-lg-6:nth-child(1) > ul:nth-child(1) > li:nth-child(2) > a").map { it.text() } + val genres = doc.select("div.col-lg-6:nth-child(1) > ul:nth-child(1) > li:nth-child(2) > a") + .map { it.text() } val status = when (doc.selectFirst("span.enemision")?.text()) { "En emisión" -> ShowStatus.Ongoing "Concluido" -> ShowStatus.Completed @@ -143,7 +155,8 @@ class JKAnimeProvider : MainAPI() { val animeID = doc.selectFirst("div.ml-2")?.attr("data-anime")?.toInt() val animeeps = "$mainUrl/ajax/last_episode/$animeID/" val jsoneps = app.get(animeeps).text - val lastepnum = jsoneps.substringAfter("{\"number\":\"").substringBefore("\",\"title\"").toInt() + val lastepnum = + jsoneps.substringAfter("{\"number\":\"").substringBefore("\",\"title\"").toInt() val episodes = (1..lastepnum).map { val link = "${url.removeSuffix("/")}/$it" Episode(link) @@ -158,7 +171,7 @@ class JKAnimeProvider : MainAPI() { } } - data class Nozomi ( + data class Nozomi( @JsonProperty("file") val file: String? ) @@ -193,16 +206,17 @@ class JKAnimeProvider : MainAPI() { if (script.data().contains("var video = []")) { val videos = script.data().replace("\\/", "/") fetchUrls(videos).map { - it.replace("$mainUrl/jkfembed.php?u=","https://embedsito.com/v/") - .replace("$mainUrl/jkokru.php?u=","http://ok.ru/videoembed/") - .replace("$mainUrl/jkvmixdrop.php?u=","https://mixdrop.co/e/") - .replace("$mainUrl/jk.php?u=","$mainUrl/") + it.replace("$mainUrl/jkfembed.php?u=", "https://embedsito.com/v/") + .replace("$mainUrl/jkokru.php?u=", "http://ok.ru/videoembed/") + .replace("$mainUrl/jkvmixdrop.php?u=", "https://mixdrop.co/e/") + .replace("$mainUrl/jk.php?u=", "$mainUrl/") }.apmap { link -> - loadExtractor(link, data, callback) + loadExtractor(link, data, subtitleCallback, callback) if (link.contains("um2.php")) { val doc = app.get(link, referer = data).document val gsplaykey = doc.select("form input[value]").attr("value") - val postgsplay = app.post("$mainUrl/gsplay/redirect_post.php", + app.post( + "$mainUrl/gsplay/redirect_post.php", headers = mapOf( "Host" to "jkanime.net", "User-Agent" to USER_AGENT, @@ -219,11 +233,14 @@ class JKAnimeProvider : MainAPI() { "Sec-Fetch-Site" to "same-origin", "TE" to "trailers", "Pragma" to "no-cache", - "Cache-Control" to "no-cache",), - data = mapOf(Pair("data",gsplaykey)), - allowRedirects = false).okhttpResponse.headers.values("location").apmap { loc -> - val postkey = loc.replace("/gsplay/player.html#","") - val nozomitext = app.post("$mainUrl/gsplay/api.php", + "Cache-Control" to "no-cache", + ), + data = mapOf(Pair("data", gsplaykey)), + allowRedirects = false + ).okhttpResponse.headers.values("location").apmap { loc -> + val postkey = loc.replace("/gsplay/player.html#", "") + val nozomitext = app.post( + "$mainUrl/gsplay/api.php", headers = mapOf( "Host" to "jkanime.net", "User-Agent" to USER_AGENT, @@ -236,8 +253,9 @@ class JKAnimeProvider : MainAPI() { "Connection" to "keep-alive", "Sec-Fetch-Dest" to "empty", "Sec-Fetch-Mode" to "cors", - "Sec-Fetch-Site" to "same-origin",), - data = mapOf(Pair("v",postkey)), + "Sec-Fetch-Site" to "same-origin", + ), + data = mapOf(Pair("v", postkey)), allowRedirects = false ).text val json = parseJson(nozomitext) @@ -245,13 +263,20 @@ class JKAnimeProvider : MainAPI() { if (nozomiurl.isEmpty()) null else nozomiurl.forEach { url -> val nozominame = "Nozomi" - streamClean(nozominame, url!!, "", null, callback, url.contains(".m3u8")) + streamClean( + nozominame, + url!!, + "", + null, + callback, + url.contains(".m3u8") + ) } } } if (link.contains("um.php")) { val desutext = app.get(link, referer = data).text - val desuRegex = Regex("((https:|http:)\\/\\/.*\\.m3u8)") + val desuRegex = Regex("((https:|http:)//.*\\.m3u8)") val file = desuRegex.find(desutext)?.value val namedesu = "Desu" generateM3u8( @@ -259,13 +284,31 @@ class JKAnimeProvider : MainAPI() { file!!, mainUrl, ).forEach { desurl -> - streamClean(namedesu, desurl.url, mainUrl, desurl.quality.toString(), callback, true) + streamClean( + namedesu, + desurl.url, + mainUrl, + desurl.quality.toString(), + callback, + true + ) } } if (link.contains("jkmedia")) { - app.get(link, referer = data, allowRedirects = false).okhttpResponse.headers.values("location").apmap { xtremeurl -> + app.get( + link, + referer = data, + allowRedirects = false + ).okhttpResponse.headers.values("location").apmap { xtremeurl -> val namex = "Xtreme S" - streamClean(namex, xtremeurl, "", null, callback, xtremeurl.contains(".m3u8")) + streamClean( + namex, + xtremeurl, + "", + null, + callback, + xtremeurl.contains(".m3u8") + ) } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/KimCartoonProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/KimCartoonProvider.kt index 7dcca2da..5a537912 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/KimCartoonProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/KimCartoonProvider.kt @@ -3,7 +3,6 @@ package com.lagradost.cloudstream3.animeproviders import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.loadExtractor -import org.jsoup.Jsoup class KimCartoonProvider : MainAPI() { @@ -83,9 +82,9 @@ class KimCartoonProvider : MainAPI() { override suspend fun quickSearch(query: String): List { return app.post( - "$mainUrl/Ajax/SearchSuggest", - data = mapOf("keyword" to query) - ).document.select("a").map { + "$mainUrl/Ajax/SearchSuggest", + data = mapOf("keyword" to query) + ).document.select("a").map { AnimeSearchResponse( it.text(), it.attr("href"), @@ -143,7 +142,7 @@ class KimCartoonProvider : MainAPI() { servers.apmap { app.get(it).document.select("#my_video_1").attr("src").let { iframe -> if (iframe.isNotEmpty()) { - loadExtractor(iframe, "$mainUrl/", callback) + loadExtractor(iframe, "$mainUrl/", subtitleCallback, callback) } //There are other servers, but they require some work to do } diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/KuronimeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/KuronimeProvider.kt index d438e915..edb3d9f7 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/KuronimeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/KuronimeProvider.kt @@ -180,7 +180,7 @@ class KuronimeProvider : MainAPI() { safeApiCall { when { it.startsWith("https://animeku.org") -> invokeKuroSource(it, callback) - else -> loadExtractor(it, mainUrl, callback) + else -> loadExtractor(it, mainUrl, subtitleCallback, callback) } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/MonoschinosProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/MonoschinosProvider.kt index 2548bb8b..b10c480a 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/MonoschinosProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/MonoschinosProvider.kt @@ -148,7 +148,7 @@ class MonoschinosProvider : MainAPI() { callback.invoke(link) } } else { - loadExtractor(url, mainUrl, callback) + loadExtractor(url, mainUrl, subtitleCallback, callback) } } return true diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/MundoDonghuaProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/MundoDonghuaProvider.kt index 54fdfe45..372bfb1a 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/MundoDonghuaProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/MundoDonghuaProvider.kt @@ -163,7 +163,7 @@ class MundoDonghuaProvider : MainAPI() { }.toList().apmap { val unpack = getAndUnpack(it).replace("diasfem","embedsito") fetchUrls(unpack).apmap { url -> - loadExtractor(url, data, callback) + loadExtractor(url, data, subtitleCallback, callback) } if (unpack.contains("protea_tab")) { val protearegex = Regex("(protea_tab.*slug.*,type)") diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/NeonimeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/NeonimeProvider.kt index cd5d213c..ed46d6b7 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/NeonimeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/NeonimeProvider.kt @@ -169,7 +169,7 @@ class NeonimeProvider : MainAPI() { } source.apmap { - loadExtractor(it, data, callback) + loadExtractor(it, data, subtitleCallback, callback) } return true diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/NineAnimeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/NineAnimeProvider.kt index 60cdd0a1..ae9a763c 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/NineAnimeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/NineAnimeProvider.kt @@ -339,7 +339,7 @@ class NineAnimeProvider : MainAPI() { val encodedStreamUrl = getEpisodeLinks(it.attr("data-link-id"))?.result?.url ?: return@apmap val url = decodeVrf(encodedStreamUrl) - if (!loadExtractor(url, callback = callback, referer = mainUrl)) { + if (!loadExtractor(url, mainUrl, subtitleCallback, callback)) { callback( ExtractorLink( this.name, diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/NontonAnimeIDProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/NontonAnimeIDProvider.kt index deacbdee..0f92d632 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/NontonAnimeIDProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/NontonAnimeIDProvider.kt @@ -3,10 +3,10 @@ package com.lagradost.cloudstream3.animeproviders import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer -import com.lagradost.cloudstream3.utils.* +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.loadExtractor import org.jsoup.Jsoup import org.jsoup.nodes.Element -import java.util.ArrayList class NontonAnimeIDProvider : MainAPI() { override var mainUrl = "https://75.119.159.228" @@ -175,13 +175,17 @@ class NontonAnimeIDProvider : MainAPI() { ) ).parsed().content ).select("li").map { - val name = Regex("(Episode\\s?[0-9]+)").find(it.selectFirst("a")?.text().toString())?.groupValues?.getOrNull(0) ?: it.selectFirst("a")?.text() + val name = Regex("(Episode\\s?[0-9]+)").find( + it.selectFirst("a")?.text().toString() + )?.groupValues?.getOrNull(0) ?: it.selectFirst("a")?.text() val link = fixUrl(it.selectFirst("a")!!.attr("href")) Episode(link, name) }.reversed() } else { document.select("ul.misha_posts_wrap2 > li").map { - val name = Regex("(Episode\\s?[0-9]+)").find(it.selectFirst("a")?.text().toString())?.groupValues?.getOrNull(0) ?: it.selectFirst("a")?.text() + val name = Regex("(Episode\\s?[0-9]+)").find( + it.selectFirst("a")?.text().toString() + )?.groupValues?.getOrNull(0) ?: it.selectFirst("a")?.text() val link = it.select("a").attr("href") Episode(link, name) }.reversed() @@ -243,7 +247,7 @@ class NontonAnimeIDProvider : MainAPI() { } sources.apmap { - loadExtractor(it, "$mainUrl/", callback) + loadExtractor(it, "$mainUrl/", subtitleCallback, callback) } return true diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/OploverzProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/OploverzProvider.kt index 640efead..092dc041 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/OploverzProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/OploverzProvider.kt @@ -193,7 +193,7 @@ class OploverzProvider : MainAPI() { } sources.apmap { - loadExtractor(it, data, callback) + loadExtractor(it, data, subtitleCallback, callback) } return true diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/OtakudesuProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/OtakudesuProvider.kt index 883a408e..7aed6e41 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/OtakudesuProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/OtakudesuProvider.kt @@ -189,7 +189,7 @@ class OtakudesuProvider : MainAPI() { } } - loadExtractor(sources, data, callback) + loadExtractor(sources, data, subtitleCallback, callback) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt index a6763c70..0df4a8d4 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt @@ -56,7 +56,8 @@ class WcoProvider : MainAPI() { nameHeader.attr("href").replace("/watch/", "/anime/") .replace(Regex("-episode-.*"), "/") val isDub = - filmPoster!!.selectFirst("> div.film-poster-quality")?.text()?.contains("DUB") + filmPoster!!.selectFirst("> div.film-poster-quality")?.text() + ?.contains("DUB") ?: false val poster = filmPoster.selectFirst("> img")!!.attr("data-src") val set: EnumSet = @@ -231,8 +232,8 @@ class WcoProvider : MainAPI() { } for (server in servers) { - WcoStream().getSafeUrl(server["link"].toString(), "")?.forEach(callback) - Mcloud().getSafeUrl(server["link"].toString(), "")?.forEach(callback) + WcoStream().getSafeUrl(server["link"].toString(), null, subtitleCallback, callback) + Mcloud().getSafeUrl(server["link"].toString(), null, subtitleCallback, callback) } return true } diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ZoroProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ZoroProvider.kt index 2200f2c7..e24f10db 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ZoroProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ZoroProvider.kt @@ -55,17 +55,18 @@ class ZoroProvider : MainAPI() { private fun Element.toSearchResult(): SearchResponse? { val href = fixUrl(this.select("a").attr("href")) val title = this.select("h3.film-name").text() - val dubSub = this.select(".film-poster > .tick.ltr").text() + val dubSub = this.select(".film-poster > .tick.ltr").text() //val episodes = this.selectFirst(".film-poster > .tick-eps")?.text()?.toIntOrNull() val dubExist = dubSub.contains("dub", ignoreCase = true) val subExist = dubSub.contains("sub", ignoreCase = true) - val episodes = this.selectFirst(".film-poster > .tick.rtl > .tick-eps")?.text()?.let { eps -> - //println("REGEX:::: $eps") - // current episode / max episode - //Regex("Ep (\\d+)/(\\d+)") - epRegex.find(eps)?.groupValues?.get(1)?.toIntOrNull() - } + val episodes = + this.selectFirst(".film-poster > .tick.rtl > .tick-eps")?.text()?.let { eps -> + //println("REGEX:::: $eps") + // current episode / max episode + //Regex("Ep (\\d+)/(\\d+)") + epRegex.find(eps)?.groupValues?.get(1)?.toIntOrNull() + } if (href.contains("/news/") || title.trim().equals("News", ignoreCase = true)) return null val posterUrl = fixUrl(this.select("img").attr("data-src")) val type = getType(this.select("div.fd-infor > span.fdi-item").text()) @@ -346,7 +347,7 @@ class ZoroProvider : MainAPI() { link, ).parsed().link val hasLoadedExtractorLink = - loadExtractor(extractorLink, "https://rapid-cloud.ru/", callback) + loadExtractor(extractorLink, "https://rapid-cloud.ru/", subtitleCallback, callback) if (!hasLoadedExtractorLink) { extractRabbitStream( diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/Pelisplus.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/Pelisplus.kt index 0bc66308..cc743d5e 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/Pelisplus.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/Pelisplus.kt @@ -1,5 +1,6 @@ package com.lagradost.cloudstream3.extractors +import com.lagradost.cloudstream3.SubtitleFile import com.lagradost.cloudstream3.apmap import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall @@ -27,12 +28,16 @@ class Pelisplus(val mainUrl: String) { private val normalApis = arrayListOf(MultiQuality()) // https://gogo-stream.com/streaming.php?id=MTE3NDg5 - suspend fun getUrl(id: String, isCasting: Boolean = false, callback: (ExtractorLink) -> Unit): Boolean { + suspend fun getUrl( + id: String, + isCasting: Boolean = false, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { try { normalApis.apmap { api -> val url = api.getExtractorUrl(id) - val source = api.getSafeUrl(url) - source?.forEach { callback.invoke(it) } + api.getSafeUrl(url, subtitleCallback = subtitleCallback, callback = callback) } val extractorUrl = getExtractorUrl(id) @@ -50,9 +55,10 @@ class Pelisplus(val mainUrl: String) { val href = element.attr("href") ?: return@apmap val qual = if (element.text() .contains("HDP") - ) "1080" else qualityRegex.find(element.text())?.destructured?.component1().toString() + ) "1080" else qualityRegex.find(element.text())?.destructured?.component1() + .toString() - if (!loadExtractor(href, link, callback)) { + if (!loadExtractor(href, link, subtitleCallback, callback)) { callback.invoke( ExtractorLink( this.name, @@ -80,12 +86,7 @@ class Pelisplus(val mainUrl: String) { // Matches vidstream links with extractors extractorApis.filter { !it.requiresReferer || !isCasting }.apmap { api -> if (link.startsWith(api.mainUrl)) { - val extractedLinks = api.getSafeUrl(link, extractorUrl) - if (extractedLinks?.isNotEmpty() == true) { - extractedLinks.forEach { - callback.invoke(it) - } - } + api.getSafeUrl(link, extractorUrl, subtitleCallback, callback) } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/VidSrcExtractor.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/VidSrcExtractor.kt index caa266ca..a4a1797c 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/VidSrcExtractor.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/VidSrcExtractor.kt @@ -1,5 +1,6 @@ package com.lagradost.cloudstream3.extractors +import com.lagradost.cloudstream3.SubtitleFile import com.lagradost.cloudstream3.apmap import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.utils.ExtractorApi @@ -12,35 +13,42 @@ class VidSrcExtractor : ExtractorApi() { override val mainUrl = "https://v2.vidsrc.me" override val requiresReferer = false - override suspend fun getUrl(url: String, referer: String?): List? { + override suspend fun getUrl( + url: String, + referer: String?, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ) { val iframedoc = app.get(url).document - val serverslist = iframedoc.select("div#sources.button_content div#content div#list div").map { - val datahash = it.attr("data-hash") - if (datahash.isNotBlank()) { - val links = try { - app.get("$mainUrl/src/$datahash", referer = "https://source.vidsrc.me/").url - } catch (e: Exception) { - "" - } - links - } else "" - } + val serverslist = + iframedoc.select("div#sources.button_content div#content div#list div").map { + val datahash = it.attr("data-hash") + if (datahash.isNotBlank()) { + val links = try { + app.get("$mainUrl/src/$datahash", referer = "https://source.vidsrc.me/").url + } catch (e: Exception) { + "" + } + links + } else "" + } - return serverslist.apmap { server -> - val linkfixed = server.replace("https://vidsrc.xyz/","https://embedsito.com/") + serverslist.apmap { server -> + val linkfixed = server.replace("https://vidsrc.xyz/", "https://embedsito.com/") if (linkfixed.contains("/pro")) { val srcresponse = app.get(server, referer = mainUrl).text val m3u8Regex = Regex("((https:|http:)//.*\\.m3u8)") - val srcm3u8 = m3u8Regex.find(srcresponse)?.value ?: return@apmap listOf() + val srcm3u8 = m3u8Regex.find(srcresponse)?.value ?: return@apmap M3u8Helper.generateM3u8( name, srcm3u8, mainUrl - ) + ).forEach(callback) } else { - loadExtractor(linkfixed, url) + loadExtractor(linkfixed, url, subtitleCallback, callback) } - }.flatten() + } } + } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/Vidstream.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/Vidstream.kt index 4ade14a5..1d853b2d 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/Vidstream.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/Vidstream.kt @@ -1,5 +1,6 @@ package com.lagradost.cloudstream3.extractors +import com.lagradost.cloudstream3.SubtitleFile import com.lagradost.cloudstream3.apmap import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.argamap @@ -30,15 +31,19 @@ class Vidstream(val mainUrl: String) { suspend fun getUrl( id: String, isCasting: Boolean = false, - callback: (ExtractorLink) -> Unit + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit, ): Boolean { val extractorUrl = getExtractorUrl(id) argamap( { normalApis.apmap { api -> val url = api.getExtractorUrl(id) - val source = api.getSafeUrl(url) - source?.forEach { callback.invoke(it) } + api.getSafeUrl( + url, + callback = callback, + subtitleCallback = subtitleCallback + ) } }, { /** Stolen from GogoanimeProvider.kt extractor */ @@ -57,7 +62,7 @@ class Vidstream(val mainUrl: String) { ) "1080" else qualityRegex.find(element.text())?.destructured?.component1() .toString() - if (!loadExtractor(href, link, callback)) { + if (!loadExtractor(href, link, subtitleCallback, callback)) { callback.invoke( ExtractorLink( this.name, @@ -84,12 +89,7 @@ class Vidstream(val mainUrl: String) { // Matches vidstream links with extractors extractorApis.filter { !it.requiresReferer || !isCasting }.apmap { api -> if (link.startsWith(api.mainUrl)) { - val extractedLinks = api.getSafeUrl(link, extractorUrl) - if (extractedLinks?.isNotEmpty() == true) { - extractedLinks.forEach { - callback.invoke(it) - } - } + api.getSafeUrl(link, extractorUrl, subtitleCallback, callback) } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/YoutubeExtractor.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/YoutubeExtractor.kt index de458739..8148ca3e 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/YoutubeExtractor.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/YoutubeExtractor.kt @@ -1,14 +1,14 @@ package com.lagradost.cloudstream3.extractors -import com.lagradost.cloudstream3.ErrorLoadingException -import com.lagradost.cloudstream3.mvvm.Resource -import com.lagradost.cloudstream3.mvvm.safeApiCall +import com.lagradost.cloudstream3.SubtitleFile +import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.utils.ExtractorApi import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.schemaStripRegex import org.schabi.newpipe.extractor.ServiceList import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeStreamExtractor import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeStreamLinkHandlerFactory +import org.schabi.newpipe.extractor.stream.SubtitlesStream import org.schabi.newpipe.extractor.stream.VideoStream class YoutubeShortLinkExtractor : YoutubeExtractor() { @@ -26,56 +26,56 @@ open class YoutubeExtractor : ExtractorApi() { companion object { private var ytVideos: MutableMap> = mutableMapOf() + private var ytVideosSubtitles: MutableMap> = mutableMapOf() } override fun getExtractorUrl(id: String): String { return "$mainUrl/watch?v=$id" } - override suspend fun getUrl(url: String, referer: String?): List? { - val streams = safeApiCall { - val streams = ytVideos[url] ?: let { - val link = - YoutubeStreamLinkHandlerFactory.getInstance().fromUrl( - url.replace( - schemaStripRegex, "" - ) + override suspend fun getUrl( + url: String, + referer: String?, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ) { + if (ytVideos[url].isNullOrEmpty()) { + val link = + YoutubeStreamLinkHandlerFactory.getInstance().fromUrl( + url.replace( + schemaStripRegex, "" ) - - val s = object : YoutubeStreamExtractor( - ServiceList.YouTube, - link - ) { - - } - s.fetchPage() - val streams = s.videoStreams ?: return@let emptyList() - ytVideos[url] = streams - streams - } - if (streams.isEmpty()) { - throw ErrorLoadingException("No Youtube streams") - } - - streams - //streams.sortedBy { it.height } - // .firstOrNull { !it.isVideoOnly && it.height > 0 } - // ?: throw ErrorLoadingException("No valid Youtube stream") - } - if (streams is Resource.Success) { - return streams.value.mapNotNull { - if (it.isVideoOnly || it.height <= 0) return@mapNotNull null - - ExtractorLink( - this.name, - this.name, - it.url ?: return@mapNotNull null, - "", - it.height ) + + val s = object : YoutubeStreamExtractor( + ServiceList.YouTube, + link + ) { + + } + s.fetchPage() + ytVideos[url] = s.videoStreams + ytVideosSubtitles[url] = try { + s.subtitlesDefault.filterNotNull() + } catch (e: Exception) { + logError(e) + emptyList() } - } else { - return null } + ytVideos[url]?.mapNotNull { + if (it.isVideoOnly || it.height <= 0) return@mapNotNull null + + ExtractorLink( + this.name, + this.name, + it.url ?: return@mapNotNull null, + "", + it.height + ) + }?.forEach(callback) + ytVideosSubtitles[url]?.mapNotNull { + SubtitleFile(it.languageTag ?: return@mapNotNull null, it.url ?: return@mapNotNull null) + }?.forEach(subtitleCallback) } + } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/helper/AsianEmbedHelper.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/helper/AsianEmbedHelper.kt index f8fd37fa..e70a9474 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/helper/AsianEmbedHelper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/helper/AsianEmbedHelper.kt @@ -1,6 +1,7 @@ package com.lagradost.cloudstream3.extractors.helper import android.util.Log +import com.lagradost.cloudstream3.SubtitleFile import com.lagradost.cloudstream3.apmap import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.utils.ExtractorLink @@ -8,7 +9,11 @@ import com.lagradost.cloudstream3.utils.loadExtractor class AsianEmbedHelper { companion object { - suspend fun getUrls(url: String, callback: (ExtractorLink) -> Unit) { + suspend fun getUrls( + url: String, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ) { // Fetch links val doc = app.get(url).document val links = doc.select("div#list-server-more > ul > li.linkserver") @@ -17,7 +22,7 @@ class AsianEmbedHelper { val datavid = it.attr("data-video") ?: "" //Log.i("AsianEmbed", "Result => (datavid) ${datavid}") if (datavid.isNotBlank()) { - val res = loadExtractor(datavid, url, callback) + val res = loadExtractor(datavid, url, subtitleCallback, callback) Log.i("AsianEmbed", "Result => ($res) (datavid) $datavid") } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/helper/VstreamhubHelper.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/helper/VstreamhubHelper.kt index 7117aa50..5c2d6e7c 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/helper/VstreamhubHelper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/helper/VstreamhubHelper.kt @@ -1,5 +1,6 @@ package com.lagradost.cloudstream3.extractors.helper +import com.lagradost.cloudstream3.SubtitleFile import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.Qualities @@ -10,7 +11,11 @@ class VstreamhubHelper { private val baseUrl: String = "https://vstreamhub.com" private val baseName: String = "Vstreamhub" - suspend fun getUrls(url: String, callback: (ExtractorLink) -> Unit) { + suspend fun getUrls( + url: String, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ) { if (url.startsWith(baseUrl)) { // Fetch links val doc = app.get(url).document.select("script") @@ -20,7 +25,8 @@ class VstreamhubHelper { if (innerText.contains("file:")) { val startString = "file: " val aa = innerText.substring(innerText.indexOf(startString)) - val linkUrl = aa.substring(startString.length + 1, aa.indexOf("\",")).trim() + val linkUrl = + aa.substring(startString.length + 1, aa.indexOf("\",")).trim() //Log.i(baseName, "Result => (linkUrl) ${linkUrl}") val exlink = ExtractorLink( name = "$baseName m3u8", @@ -33,12 +39,14 @@ class VstreamhubHelper { callback.invoke(exlink) } if (innerText.contains("playerInstance")) { - val aa = innerText.substring(innerText.indexOf("playerInstance.addButton")) + val aa = + innerText.substring(innerText.indexOf("playerInstance.addButton")) val startString = "window.open([" val bb = aa.substring(aa.indexOf(startString)) - val datavid = bb.substring(startString.length, bb.indexOf("]")).removeSurrounding("\"") + val datavid = bb.substring(startString.length, bb.indexOf("]")) + .removeSurrounding("\"") if (datavid.isNotBlank()) { - loadExtractor(datavid, url, callback) + loadExtractor(datavid, url, subtitleCallback, callback) //Log.i(baseName, "Result => (datavid) ${datavid}") } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AllMoviesForYouProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AllMoviesForYouProvider.kt index 9434f7bc..4a90bc08 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AllMoviesForYouProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AllMoviesForYouProvider.kt @@ -197,9 +197,9 @@ class AllMoviesForYouProvider : MainAPI() { val soup = app.get(id).document soup.select("body iframe").map { val link = fixUrl(it.attr("src").replace("streamhub.to/d/", "streamhub.to/e/")) - loadExtractor(link, data, callback) + loadExtractor(link, data, subtitleCallback, callback) } - } else loadExtractor(id, data, callback) + } else loadExtractor(id, data, subtitleCallback, callback) } return true } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AltadefinizioneProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AltadefinizioneProvider.kt index 67fadb25..719acc96 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AltadefinizioneProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AltadefinizioneProvider.kt @@ -2,10 +2,10 @@ package com.lagradost.cloudstream3.movieproviders import androidx.core.text.parseAsHtml import com.lagradost.cloudstream3.* -import com.lagradost.cloudstream3.mvvm.logError -import com.lagradost.cloudstream3.app -import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer +import com.lagradost.cloudstream3.mvvm.logError +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.loadExtractor class AltadefinizioneProvider : MainAPI() { @@ -55,16 +55,18 @@ class AltadefinizioneProvider : MainAPI() { } override suspend fun search(query: String): List { - val doc = app.post("$mainUrl/index.php", data = mapOf( - "do" to "search", - "subaction" to "search", - "story" to query, - "sortby" to "news_read" - )).document + val doc = app.post( + "$mainUrl/index.php", data = mapOf( + "do" to "search", + "subaction" to "search", + "story" to query, + "sortby" to "news_read" + ) + ).document return doc.select("div.box").map { val title = it.selectFirst("img")!!.attr("alt") val link = it.selectFirst("a")!!.attr("href") - val image = mainUrl+it.selectFirst("img")!!.attr("src") + val image = mainUrl + it.selectFirst("img")!!.attr("src") val quality = getQualityFromString(it.selectFirst("span")!!.text()) MovieSearchResponse( @@ -83,18 +85,20 @@ class AltadefinizioneProvider : MainAPI() { override suspend fun load(url: String): LoadResponse { val page = app.get(url) val document = page.document - val title = document.selectFirst(" h1 > a")!!.text().replace("streaming","") - val description = document.select("#sfull").toString().substringAfter("altadefinizione").substringBeforeLast("fonte trama").parseAsHtml().toString() + val title = document.selectFirst(" h1 > a")!!.text().replace("streaming", "") + val description = document.select("#sfull").toString().substringAfter("altadefinizione") + .substringBeforeLast("fonte trama").parseAsHtml().toString() val rating = null - val year = document.selectFirst("#details > li:nth-child(2)")!!.childNode(2).toString().filter { it.isDigit() }.toInt() + val year = document.selectFirst("#details > li:nth-child(2)")!!.childNode(2).toString() + .filter { it.isDigit() }.toInt() val poster = fixUrl(document.selectFirst("div.thumbphoto > img")!!.attr("src")) val recomm = document.select("ul.related-list > li").map { val href = it.selectFirst("a")!!.attr("href") val posterUrl = mainUrl + it.selectFirst("img")!!.attr("src") - val name = it.selectFirst("img")!!.attr("alt") + val name = it.selectFirst("img")!!.attr("alt") MovieSearchResponse( name, href, @@ -110,29 +114,29 @@ class AltadefinizioneProvider : MainAPI() { val actors: List = document.select("#staring > a").map { ActorData(actor = Actor(it.text())) - } + } val tags: List = document.select("#details > li:nth-child(1) > a").map { it.text() } val trailerurl = document.selectFirst("#showtrailer > div > div > iframe")?.attr("src") return newMovieLoadResponse( - title, - url, - TvType.Movie, - url - ) { - posterUrl = fixUrlNull(poster) - this.year = year - this.plot = description - this.rating = rating - this.recommendations = recomm - this.duration = null - this.actors = actors - this.tags = tags - addTrailer(trailerurl) - } + title, + url, + TvType.Movie, + url + ) { + posterUrl = fixUrlNull(poster) + this.year = year + this.plot = description + this.rating = rating + this.recommendations = recomm + this.duration = null + this.actors = actors + this.tags = tags + addTrailer(trailerurl) } + } override suspend fun loadLinks( @@ -142,23 +146,21 @@ class AltadefinizioneProvider : MainAPI() { callback: (ExtractorLink) -> Unit ): Boolean { val doc = app.get(data).document - if (doc.select("div.guardahd-player").isNullOrEmpty()){ - val videoUrl = doc.select("input").filter { it.hasAttr("data-mirror") }.last().attr("value") - loadExtractor(videoUrl, data, callback) + if (doc.select("div.guardahd-player").isNullOrEmpty()) { + val videoUrl = + doc.select("input").filter { it.hasAttr("data-mirror") }.last().attr("value") + loadExtractor(videoUrl, data, subtitleCallback, callback) doc.select("#mirrors > li > a").forEach { - loadExtractor(fixUrl(it.attr("data-target")), data, callback) + loadExtractor(fixUrl(it.attr("data-target")), data, subtitleCallback, callback) } - } - else{ + } else { val pagelinks = doc.select("div.guardahd-player").select("iframe").attr("src") val docLinks = app.get(pagelinks).document docLinks.select("body > div > ul > li").forEach { - loadExtractor(fixUrl(it.attr("data-link")), data, callback) + loadExtractor(fixUrl(it.attr("data-link")), data, subtitleCallback, callback) } } - - return true } } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/BflixProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/BflixProvider.kt index 7507c661..fef586c9 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/BflixProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/BflixProvider.kt @@ -27,8 +27,14 @@ open class BflixProvider : MainAPI() { Pair("Movies", "div.tab-content[data-name=movies] div.filmlist div.item"), Pair("Shows", "div.tab-content[data-name=shows] div.filmlist div.item"), Pair("Trending", "div.tab-content[data-name=trending] div.filmlist div.item"), - Pair("Latest Movies", "div.container section.bl:contains(Latest Movies) div.filmlist div.item"), - Pair("Latest TV-Series", "div.container section.bl:contains(Latest TV-Series) div.filmlist div.item"), + Pair( + "Latest Movies", + "div.container section.bl:contains(Latest Movies) div.filmlist div.item" + ), + Pair( + "Latest TV-Series", + "div.container section.bl:contains(Latest TV-Series) div.filmlist div.item" + ), ) for ((name, element) in testa) try { val test = soup.select(element).map { @@ -57,7 +63,8 @@ open class BflixProvider : MainAPI() { } //Credits to https://github.com/jmir1 - private val key = "5uLKesbh0nkrpPq9VwMC6+tQBdomjJ4HNl/fWOSiREvAYagT8yIG7zx2D13UZFXc" //key credits to @Modder4869 + private val key = + "5uLKesbh0nkrpPq9VwMC6+tQBdomjJ4HNl/fWOSiREvAYagT8yIG7zx2D13UZFXc" //key credits to @Modder4869 private fun getVrf(id: String): String? { val reversed = ue(encode(id) + "0000000").slice(0..5).reversed() @@ -216,7 +223,7 @@ open class BflixProvider : MainAPI() { } val tags = soup.select("div.info .meta div:contains(Genre) a").map { it.text() } - val episodes = Jsoup.parse( + val episodes = Jsoup.parse( app.get( "$mainUrl/ajax/film/servers?id=$movieid&vrf=$movieidencoded" ).parsed().html @@ -232,15 +239,16 @@ open class BflixProvider : MainAPI() { val eptitle = it.selectFirst(".episode a span.name")!!.text() val secondtitle = it.selectFirst(".episode a span")!!.text() - .replace(Regex("(Episode (\\d+):|Episode (\\d+)-|Episode (\\d+))"),"") ?: "" + .replace(Regex("(Episode (\\d+):|Episode (\\d+)-|Episode (\\d+))"), "") ?: "" Episode( href, - secondtitle+eptitle, + secondtitle + eptitle, season, episode, ) } - val tvType = if (url.contains("/movie/") && episodes.size == 1) TvType.Movie else TvType.TvSeries + val tvType = + if (url.contains("/movie/") && episodes.size == 1) TvType.Movie else TvType.TvSeries val recommendations = soup.select("div.bl-2 section.bl div.content div.filmlist div.item") ?.mapNotNull { element -> @@ -261,9 +269,12 @@ open class BflixProvider : MainAPI() { val durationregex = Regex("((\\d+) min)") val yearegex = Regex("(\\d+)<\\/span>") val duration = if (durationdoc.contains("na min")) null - else durationregex.find(durationdoc)?.destructured?.component1()?.replace(" min","")?.toIntOrNull() - val year = if (mainUrl == "https://bflix.ru") { yearegex.find(durationdoc)?.destructured?.component1() - ?.replace(Regex("|<\\/span>"),"") } else null + else durationregex.find(durationdoc)?.destructured?.component1()?.replace(" min", "") + ?.toIntOrNull() + val year = if (mainUrl == "https://bflix.ru") { + yearegex.find(durationdoc)?.destructured?.component1() + ?.replace(Regex("|<\\/span>"), "") + } else null return when (tvType) { TvType.TvSeries -> { TvSeriesLoadResponse( @@ -343,7 +354,8 @@ open class BflixProvider : MainAPI() { val a = it.select("a").map { it.attr("data-kname") } - val tvType = if (data.contains("movie/") && a.size == 1) TvType.Movie else TvType.TvSeries + val tvType = + if (data.contains("movie/") && a.size == 1) TvType.Movie else TvType.TvSeries val servers = if (tvType == TvType.Movie) it.select(".episode a").attr("data-ep") else it.select(".episode a[href=$cleandata]").attr("data-ep") @@ -364,7 +376,7 @@ open class BflixProvider : MainAPI() { ?.replace("/embed/", "/e/")?.replace(Regex("(\\?sub.info.*)"), "") }.apmap { url -> loadExtractor( - url, data, callback + url, data, subtitleCallback, callback ) } //Apparently any server works, I haven't found any diference diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CineblogProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CineblogProvider.kt index cd0b3908..77114ba4 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CineblogProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CineblogProvider.kt @@ -155,7 +155,7 @@ class CineblogProvider : MainAPI() { rating, null, null, - null, + mutableListOf(), recomm ) } else { @@ -205,7 +205,7 @@ class CineblogProvider : MainAPI() { val url2= Regex("""src='((.|\\n)*?)'""").find(test.text)?.groups?.get(1)?.value.toString() val trueUrl = app.get(url2, headers = mapOf("referer" to mainUrl)).url - loadExtractor(trueUrl, data, callback) + loadExtractor(trueUrl, data, subtitleCallback, callback) return true } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CinecalidadProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CinecalidadProvider.kt index 91fa8941..fff75318 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CinecalidadProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CinecalidadProvider.kt @@ -6,7 +6,7 @@ import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.loadExtractor -class CinecalidadProvider:MainAPI() { +class CinecalidadProvider : MainAPI() { override var mainUrl = "https://cinecalidad.lol" override var name = "Cinecalidad" override var lang = "es" @@ -98,9 +98,10 @@ class CinecalidadProvider:MainAPI() { val href = li.selectFirst("a")!!.attr("href") val epThumb = li.selectFirst("img.lazy")!!.attr("data-src") val name = li.selectFirst(".episodiotitle a")!!.text() - val seasonid = li.selectFirst(".numerando")!!.text().replace(Regex("(S|E)"),"").let { str -> - str.split("-").mapNotNull { subStr -> subStr.toIntOrNull() } - } + val seasonid = + li.selectFirst(".numerando")!!.text().replace(Regex("(S|E)"), "").let { str -> + str.split("-").mapNotNull { subStr -> subStr.toIntOrNull() } + } val isValid = seasonid.size == 2 val episode = if (isValid) seasonid.getOrNull(1) else null val season = if (isValid) seasonid.getOrNull(0) else null @@ -112,7 +113,8 @@ class CinecalidadProvider:MainAPI() { if (epThumb.contains("svg")) null else epThumb ) } - return when (val tvType = if (url.contains("/ver-pelicula/")) TvType.Movie else TvType.TvSeries) { + return when (val tvType = + if (url.contains("/ver-pelicula/")) TvType.Movie else TvType.TvSeries) { TvType.TvSeries -> { TvSeriesLoadResponse( title, @@ -156,18 +158,18 @@ class CinecalidadProvider:MainAPI() { val url = it.attr("data-option") if (url.startsWith("https://cinestart.net")) { val extractor = Cinestart() - extractor.getSafeUrl(url)?.forEach { link -> - callback.invoke(link) - } + extractor.getSafeUrl(url, null, subtitleCallback, callback) } else { - loadExtractor(url, mainUrl, callback) + loadExtractor(url, mainUrl, subtitleCallback, callback) } if (url.startsWith("https://cinecalidad.lol")) { - val cineurlregex = Regex("(https:\\/\\/cinecalidad\\.lol\\/play\\/\\?h=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)") + val cineurlregex = + Regex("(https:\\/\\/cinecalidad\\.lol\\/play\\/\\?h=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)") cineurlregex.findAll(url).map { - it.value.replace("/play/","/play/r.php") + it.value.replace("/play/", "/play/r.php") }.toList().apmap { - app.get(it, + app.get( + it, headers = mapOf( "Host" to "cinecalidad.lol", "User-Agent" to USER_AGENT, @@ -182,57 +184,61 @@ class CinecalidadProvider:MainAPI() { "Sec-Fetch-Site" to "same-origin", "Sec-Fetch-User" to "?1", ), - allowRedirects = false).okhttpResponse.headers.values("location").apmap { extractedurl -> - if (extractedurl.contains("cinestart")) { - loadExtractor(extractedurl, mainUrl, callback) + allowRedirects = false + ).okhttpResponse.headers.values("location").apmap { extractedurl -> + if (extractedurl.contains("cinestart")) { + loadExtractor(extractedurl, mainUrl, subtitleCallback, callback) } } } } } - if (datatext.contains("en castellano")) app.get("$data?ref=es").document.select(".dooplay_player_option").apmap { - val url = it.attr("data-option") - if (url.startsWith("https://cinestart.net")) { - val extractor = Cinestart() - extractor.getSafeUrl(url)?.forEach { link -> - callback.invoke(link) + if (datatext.contains("en castellano")) app.get("$data?ref=es").document.select(".dooplay_player_option") + .apmap { + val url = it.attr("data-option") + if (url.startsWith("https://cinestart.net")) { + val extractor = Cinestart() + extractor.getSafeUrl(url, null, subtitleCallback, callback) + } else { + loadExtractor(url, mainUrl, subtitleCallback, callback) } - } else { - loadExtractor(url, mainUrl, callback) - } - if (url.startsWith("https://cinecalidad.lol")) { - val cineurlregex = Regex("(https:\\/\\/cinecalidad\\.lol\\/play\\/\\?h=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)") - cineurlregex.findAll(url).map { - it.value.replace("/play/","/play/r.php") - }.toList().apmap { - app.get(it, - headers = mapOf( - "Host" to "cinecalidad.lol", - "User-Agent" to USER_AGENT, - "Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", - "Accept-Language" to "en-US,en;q=0.5", - "DNT" to "1", - "Connection" to "keep-alive", - "Referer" to data, - "Upgrade-Insecure-Requests" to "1", - "Sec-Fetch-Dest" to "iframe", - "Sec-Fetch-Mode" to "navigate", - "Sec-Fetch-Site" to "same-origin", - "Sec-Fetch-User" to "?1", - ), - allowRedirects = false).okhttpResponse.headers.values("location").apmap { extractedurl -> - if (extractedurl.contains("cinestart")) { - loadExtractor(extractedurl, mainUrl, callback) + if (url.startsWith("https://cinecalidad.lol")) { + val cineurlregex = + Regex("(https:\\/\\/cinecalidad\\.lol\\/play\\/\\?h=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)") + cineurlregex.findAll(url).map { + it.value.replace("/play/", "/play/r.php") + }.toList().apmap { + app.get( + it, + headers = mapOf( + "Host" to "cinecalidad.lol", + "User-Agent" to USER_AGENT, + "Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "Accept-Language" to "en-US,en;q=0.5", + "DNT" to "1", + "Connection" to "keep-alive", + "Referer" to data, + "Upgrade-Insecure-Requests" to "1", + "Sec-Fetch-Dest" to "iframe", + "Sec-Fetch-Mode" to "navigate", + "Sec-Fetch-Site" to "same-origin", + "Sec-Fetch-User" to "?1", + ), + allowRedirects = false + ).okhttpResponse.headers.values("location").apmap { extractedurl -> + if (extractedurl.contains("cinestart")) { + loadExtractor(extractedurl, mainUrl, subtitleCallback, callback) + } } } } } - } - if (datatext.contains("Subtítulo LAT") || datatext.contains("Forzados LAT")) { + if (datatext.contains("Subtítulo LAT") || datatext.contains("Forzados LAT")) { doc.select("#panel_descarga.pane a").apmap { - val link = if (data.contains("serie") || data.contains("episodio")) "${data}${it.attr("href")}" - else it.attr("href") + val link = + if (data.contains("serie") || data.contains("episodio")) "${data}${it.attr("href")}" + else it.attr("href") val docsub = app.get(link) val linksub = docsub.document val validsub = docsub.text @@ -241,8 +247,11 @@ class CinecalidadProvider:MainAPI() { val langdoc = linksub.selectFirst("div.titulo h3")!!.text() val reallang = langregex.find(langdoc)?.destructured?.component1() linksub.select("a.link").apmap { - val sublink = if (data.contains("serie") || data.contains("episodio")) "${data}${it.attr("href")}" - else it.attr("href") + val sublink = + if (data.contains("serie") || data.contains("episodio")) "${data}${ + it.attr("href") + }" + else it.attr("href") subtitleCallback( SubtitleFile(reallang!!, sublink) ) diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CuevanaProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CuevanaProvider.kt index 771cdf3e..7c7aca67 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CuevanaProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CuevanaProvider.kt @@ -227,7 +227,7 @@ class CuevanaProvider : MainAPI() { val json = parseJson(url) val link = json.url if (link.contains("fembed")) { - loadExtractor(link, data, callback) + loadExtractor(link, data, subtitleCallback, callback) } } } @@ -281,7 +281,7 @@ class CuevanaProvider : MainAPI() { ), data = mapOf(Pair("url", gotolink)) ).okhttpResponse.headers.values("location").apmap { golink -> - loadExtractor(golink, data, callback) + loadExtractor(golink, data, subtitleCallback, callback) } } } @@ -311,7 +311,7 @@ class CuevanaProvider : MainAPI() { ), data = mapOf(Pair("h", inlink)) ).okhttpResponse.headers.values("location").apmap { link -> - loadExtractor(link, data, callback) + loadExtractor(link, data, subtitleCallback, callback) } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DoramasYTProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DoramasYTProvider.kt index b216ec6f..1d1c88d2 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DoramasYTProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DoramasYTProvider.kt @@ -147,7 +147,7 @@ class DoramasYTProvider : MainAPI() { callback.invoke(link) } } else { - loadExtractor(url, mainUrl, callback) + loadExtractor(url, mainUrl, subtitleCallback, callback) } } return true diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DramaSeeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DramaSeeProvider.kt index 2e0565bf..7eef691b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DramaSeeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DramaSeeProvider.kt @@ -50,14 +50,15 @@ class DramaSeeProvider : MainAPI() { override suspend fun search(query: String): List { val url = "$mainUrl/search?q=$query" val document = app.get(url).document - val posters = document.select ("div.film-poster") + val posters = document.select("div.film-poster") return posters.mapNotNull { val innerA = it.select("a") ?: return@mapNotNull null val link = fixUrlNull(innerA.attr("href")) ?: return@mapNotNull null val title = innerA.attr("title") ?: return@mapNotNull null - val year = Regex(""".*\((\d{4})\)""").find(title)?.groupValues?.getOrNull(1)?.toIntOrNull() + val year = + Regex(""".*\((\d{4})\)""").find(title)?.groupValues?.getOrNull(1)?.toIntOrNull() val imgSrc = it.select("img")?.attr("data-src") ?: return@mapNotNull null val image = fixUrlNull(imgSrc) @@ -193,7 +194,7 @@ class DramaSeeProvider : MainAPI() { val status = element.attr("data-status") ?: return@forEach if (status != "1") return@forEach val extractorData = element.attr("data-video") ?: return@forEach - loadExtractor(extractorData, iframe.url, callback) + loadExtractor(extractorData, iframe.url, subtitleCallback, callback) } }, { val iv = "9262859232435825" diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DramaidProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DramaidProvider.kt index b8796f29..662d23a5 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DramaidProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DramaidProvider.kt @@ -206,7 +206,7 @@ class DramaidProvider : MainAPI() { }.apmap { when { it.contains("motonews.club") -> invokeDriveSource(it, this.name, subtitleCallback, callback) - else -> loadExtractor(it, data, callback) + else -> loadExtractor(it, data, subtitleCallback, callback) } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/ElifilmsProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/ElifilmsProvider.kt index dd3e1d15..9e6f9bfe 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/ElifilmsProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/ElifilmsProvider.kt @@ -87,7 +87,7 @@ class ElifilmsProvider : MainAPI() { val encodedurl = it.attr("data-id") val urlDecoded = base64Decode(encodedurl) val url = fixUrl(urlDecoded) - loadExtractor(url, data, callback) + loadExtractor(url, data, subtitleCallback, callback) } return true } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/EntrepeliculasyseriesProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/EntrepeliculasyseriesProvider.kt index 68103f8c..b46d67d4 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/EntrepeliculasyseriesProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/EntrepeliculasyseriesProvider.kt @@ -170,7 +170,7 @@ class EntrepeliculasyseriesProvider:MainAPI() { data = mapOf(Pair("h", postkey)), allowRedirects = false ).okhttpResponse.headers.values("location").apmap { - loadExtractor(it, data, callback) + loadExtractor(it, data, subtitleCallback, callback) } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/EstrenosDoramasProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/EstrenosDoramasProvider.kt index bddd9de0..5cb11248 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/EstrenosDoramasProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/EstrenosDoramasProvider.kt @@ -189,7 +189,7 @@ class EstrenosDoramasProvider : MainAPI() { val document = app.get(data).document document.select("div.tab_container iframe").apmap { container -> val directlink = fixUrl(container.attr("src")) - loadExtractor(directlink, data, callback) + loadExtractor(directlink, data, subtitleCallback, callback) if (directlink.contains("/repro/amz/")) { val amzregex = Regex("https:\\/\\/repro3\\.estrenosdoramas\\.us\\/repro\\/amz\\/examples\\/.*\\.php\\?key=.*\$") @@ -239,7 +239,7 @@ class EstrenosDoramasProvider : MainAPI() { ).text val extracteklink = link.substringAfter("\"urlremoto\":\"").substringBefore("\"}") .replace("\\/", "/").replace("//ok.ru/","http://ok.ru/") - loadExtractor(extracteklink, data, callback) + loadExtractor(extracteklink, data, subtitleCallback, callback) } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/FilmanProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/FilmanProvider.kt index 75c2f728..08bf21f8 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/FilmanProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/FilmanProvider.kt @@ -2,8 +2,9 @@ package com.lagradost.cloudstream3.movieproviders import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.* -import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.loadExtractor import org.jsoup.Jsoup import org.jsoup.select.Elements @@ -58,10 +59,11 @@ class FilmanProvider : MainAPI() { val series = lists[3].select("#item-list > div:not(.clearfix)") if (movies.isEmpty() && series.isEmpty()) return ArrayList() fun getVideos(type: TvType, items: Elements): List { - return items.mapNotNull { i -> - val href = i.selectFirst(".poster > a")?.attr("href")?: return@mapNotNull null - val img = i.selectFirst(".poster > a > img")?.attr("src")?.replace("/thumb/", "/big/") - val name = i.selectFirst(".film_title")?.text()?: return@mapNotNull null + return items.mapNotNull { i -> + val href = i.selectFirst(".poster > a")?.attr("href") ?: return@mapNotNull null + val img = + i.selectFirst(".poster > a > img")?.attr("src")?.replace("/thumb/", "/big/") + val name = i.selectFirst(".film_title")?.text() ?: return@mapNotNull null val year = i.selectFirst(".film_year")?.text()?.toIntOrNull() if (type === TvType.TvSeries) { TvSeriesSearchResponse( @@ -136,7 +138,7 @@ class FilmanProvider : MainAPI() { document?.select(".link-to-video")?.apmap { item -> val decoded = base64Decode(item.select("a").attr("data-iframe")) val link = tryParseJson(decoded)?.src ?: return@apmap - loadExtractor(link, null, callback) + loadExtractor(link, subtitleCallback, callback) } return true } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/FilmpertuttiProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/FilmpertuttiProvider.kt index 15efa32d..cda70a31 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/FilmpertuttiProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/FilmpertuttiProvider.kt @@ -224,15 +224,15 @@ class FilmpertuttiProvider : MainAPI() { tryParseJson>(data)?.apmap { id -> if (id.contains("buckler")){ val id2 = unshorten_linkup(id).trim().replace("/v/","/e/").replace("/f/","/e/") - loadExtractor(id2, data, callback) + loadExtractor(id2, data, subtitleCallback, callback) } else if (id.contains("isecure")){ val doc1 = app.get(id).document val id2 = doc1.selectFirst("iframe")!!.attr("src") - loadExtractor(id2, data, callback) + loadExtractor(id2, data, subtitleCallback, callback) } else{ - loadExtractor(id, data, callback) + loadExtractor(id, data, subtitleCallback, callback) } } return true diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/FrenchStreamProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/FrenchStreamProvider.kt index 9923adca..6eac9a62 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/FrenchStreamProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/FrenchStreamProvider.kt @@ -68,7 +68,7 @@ class FrenchStreamProvider : MainAPI() { ?.mapNotNull { // all the tags like action, thriller ...; unused variable it?.text() } - return newMovieLoadResponse(title,url,TvType.Movie,url) { + return newMovieLoadResponse(title, url, TvType.Movie, url) { this.posterUrl = poster addRating(soup.select("div.fr-count > div").text()) this.year = soup.select("ul.flist-col > li").getOrNull(2)?.text()?.toIntOrNull() @@ -82,8 +82,7 @@ class FrenchStreamProvider : MainAPI() { //println("listeEpisode:") val episodeList = if ("strong").text().toFloatOrNull()?.times(1000))?.toInt(), info.select(".sgeneros>a").map { it.text() }, info.select(".runtime").text().substringBefore(" Min.").toIntOrNull(), - null, + mutableListOf(), doc.select("#single_relacionados>article>a").map { val img = it.select("img") MovieSearchResponse( @@ -149,7 +149,7 @@ class HDMovie5 : MainAPI() { val html = p.parsedSafe()?.embedURL ?: return@apmapIndexed false val doc = Jsoup.parse(html) val link = doc.select("iframe").attr("src") - loadExtractor(httpsify(link), "$mainUrl/", callback) + loadExtractor(httpsify(link), "$mainUrl/", subtitleCallback, callback) }.contains(true) } } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/IHaveNoTvProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/IHaveNoTvProvider.kt index b6d224d7..2be28b3d 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/IHaveNoTvProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/IHaveNoTvProvider.kt @@ -215,7 +215,7 @@ class IHaveNoTvProvider : MainAPI() { val iframe = soup.selectFirst("#videoWrap iframe") if (iframe != null) { - loadExtractor(iframe.attr("src"), null, callback) + loadExtractor(iframe.attr("src"), null, subtitleCallback, callback) } return true } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/IdlixProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/IdlixProvider.kt index dec6bf17..4b1912b5 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/IdlixProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/IdlixProvider.kt @@ -365,7 +365,7 @@ class IdlixProvider : MainAPI() { if (source.startsWith("https://uservideo.xyz")) { source = app.get(source).document.select("iframe").attr("src") } - loadExtractor(source, data, callback) + loadExtractor(source, data, subtitleCallback, callback) } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/KdramaHoodProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/KdramaHoodProvider.kt index 5a193cdb..a87c34ec 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/KdramaHoodProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/KdramaHoodProvider.kt @@ -48,7 +48,9 @@ class KdramaHoodProvider : MainAPI() { val rex = Regex("\\((\\d+)") //Log.i(this.name, "Result => (rex value) ${rex.find(yearText)?.value}") rex.find(yearText)?.value?.toIntOrNull() - } catch (e: Exception) { null } + } catch (e: Exception) { + null + } MovieSearchResponse( name = title, @@ -67,7 +69,7 @@ class KdramaHoodProvider : MainAPI() { val url = "$mainUrl/?s=$query" val html = app.get(url).document val document = html.getElementsByTag("body") - .select("div.item_1.items > div.item") ?: return listOf() + .select("div.item_1.items > div.item") ?: return listOf() return document.mapNotNull { if (it == null) { @@ -105,15 +107,21 @@ class KdramaHoodProvider : MainAPI() { val startLink = "https://kdramahood.com/drama-release-year/" var res: Int? = null info?.select("div.metadatac")?.forEach { - if (res != null) { return@forEach } - if (it == null) { return@forEach } + if (res != null) { + return@forEach + } + if (it == null) { + return@forEach + } val yearLink = it.select("a").attr("href") ?: return@forEach if (yearLink.startsWith(startLink)) { res = yearLink.substring(startLink.length).replace("/", "").toIntOrNull() } } res - } catch (e: Exception) { null } + } catch (e: Exception) { + null + } val recs = doc.select("div.sidebartv > div.tvitemrel").mapNotNull { val a = it?.select("a") ?: return@mapNotNull null @@ -161,10 +169,13 @@ class KdramaHoodProvider : MainAPI() { } //Fetch default source and subtitles epVidLinkEl.select("div.embed2")?.forEach { defsrc -> - if (defsrc == null) { return@forEach } + if (defsrc == null) { + return@forEach + } val scriptstring = defsrc.toString() if (scriptstring.contains("sources: [{")) { - "(?<=playerInstance2.setup\\()([\\s\\S]*?)(?=\\);)".toRegex().find(scriptstring)?.value?.let { itemjs -> + "(?<=playerInstance2.setup\\()([\\s\\S]*?)(?=\\);)".toRegex() + .find(scriptstring)?.value?.let { itemjs -> listOfLinks.add("$mainUrl$itemjs") } } @@ -264,7 +275,7 @@ class KdramaHoodProvider : MainAPI() { //Log.i(this.name, "Result => (url) $url") when { url.startsWith("https://asianembed.io") -> { - AsianEmbedHelper.getUrls(url, callback) + AsianEmbedHelper.getUrls(url, subtitleCallback, callback) } url.startsWith("https://embedsito.com") -> { val extractor = XStreamCdn() @@ -274,7 +285,7 @@ class KdramaHoodProvider : MainAPI() { } } else -> { - loadExtractor(url, mainUrl, callback) + loadExtractor(url, mainUrl, subtitleCallback, callback) } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/LayarKacaProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/LayarKacaProvider.kt index adb15e48..8b96f88c 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/LayarKacaProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/LayarKacaProvider.kt @@ -219,7 +219,7 @@ class LayarKacaProvider : MainAPI() { } else { it } - loadExtractor(link, data, callback) + loadExtractor(link, data, subtitleCallback, callback) } return true diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/OpenVidsProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/OpenVidsProvider.kt index 49e63f72..569aef26 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/OpenVidsProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/OpenVidsProvider.kt @@ -126,7 +126,7 @@ class OpenVidsProvider:TmdbProvider() { membed.isUsingAdaptiveKeys, membed.isUsingAdaptiveData) } else - loadExtractor(links, data, callback) + loadExtractor(links, data, subtitleCallback, callback) } return true } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PeliSmartProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PeliSmartProvider.kt index 0976c8b8..588efea3 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PeliSmartProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PeliSmartProvider.kt @@ -152,7 +152,7 @@ class PeliSmartProvider: MainAPI() { .replace("https://pelismarthd.com/p/1.php?v=","https://evoload.io/e/") .replace("https://pelismarthd.com/p/2.php?v=","https://streamtape.com/e/") .replace("https://pelismarthd.com/p/4.php?v=","https://dood.to/e/") - loadExtractor(urlc, data, callback) + loadExtractor(urlc, data, subtitleCallback, callback) } return true } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisflixProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisflixProvider.kt index 005cbb7f..a22a1ca8 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisflixProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisflixProvider.kt @@ -222,7 +222,7 @@ class PelisflixProvider : MainAPI() { allowRedirects = false ).okhttpResponse.headers.values("location").apmap { link -> val url1 = link.replace("#bu", "") - loadExtractor(url1, data, callback) + loadExtractor(url1, data, subtitleCallback, callback) } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusHDProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusHDProvider.kt index ae8d2718..d45587f8 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusHDProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusHDProvider.kt @@ -165,7 +165,7 @@ class PelisplusHDProvider:MainAPI() { ): Boolean { app.get(data).document.select("div.player > script").map { script -> fetchUrls(script.data().replace("https://pelisplushd.net/fembed.php?url=","https://www.fembed.com/v/")).apmap { - loadExtractor(it, data, callback) + loadExtractor(it, data, subtitleCallback, callback) } } return true diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusProviderTemplate.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusProviderTemplate.kt index b198b4e4..41c51afd 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusProviderTemplate.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusProviderTemplate.kt @@ -229,7 +229,7 @@ open class PelisplusProviderTemplate : MainAPI() { if (info.contains("Latino")) { doc.select(".server-item-1 li").apmap { val serverid = fixUrl(it.attr("data-video")).replace("streaming.php","play") - loadExtractor(serverid, data, callback) + loadExtractor(serverid, data, subtitleCallback, callback) if (serverid.contains("pelisplus.icu")) { getPelisStream(serverid, callback) } @@ -239,7 +239,7 @@ open class PelisplusProviderTemplate : MainAPI() { if (info.contains("Subtitulado")) { doc.select(".server-item-0 li").apmap { val serverid = fixUrl(it.attr("data-video")).replace("streaming.php","play") - loadExtractor(serverid, data, callback) + loadExtractor(serverid, data, subtitleCallback, callback) if (serverid.contains("pelisplus.icu")) { getPelisStream(serverid, callback) } @@ -249,7 +249,7 @@ open class PelisplusProviderTemplate : MainAPI() { if (info.contains("Castellano")) { doc.select(".server-item-2 li").apmap { val serverid = fixUrl(it.attr("data-video")).replace("streaming.php","play") - loadExtractor(serverid, data, callback) + loadExtractor(serverid, data, subtitleCallback, callback) if (serverid.contains("pelisplus.icu")) { getPelisStream(serverid, callback) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyHDXyzProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyHDXyzProvider.kt index 1e6b71b6..dca312d5 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyHDXyzProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyHDXyzProvider.kt @@ -221,7 +221,7 @@ class PinoyHDXyzProvider : MainAPI() { mapper.readValue>(data).forEach { item -> val url = item.trim() if (url.isNotBlank()) { - if (loadExtractor(url, mainUrl, callback)) { + if (loadExtractor(url, mainUrl, subtitleCallback, callback)) { count++ } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviePediaProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviePediaProvider.kt index 7ed1be88..ebc73b6f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviePediaProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviePediaProvider.kt @@ -231,7 +231,7 @@ class PinoyMoviePediaProvider : MainAPI() { callback.invoke(it) } } else { - loadExtractor(link, mainUrl, callback) + loadExtractor(link, mainUrl, subtitleCallback, callback) } } return count > 0 diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviesEsProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviesEsProvider.kt index cee6107f..6b68e5c1 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviesEsProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PinoyMoviesEsProvider.kt @@ -1,6 +1,5 @@ package com.lagradost.cloudstream3.movieproviders -import android.util.Log import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.extractors.FEmbed @@ -26,7 +25,11 @@ class PinoyMoviesEsProvider : MainAPI() { @JsonProperty("type") val type: String ) - private fun getRowElements(mainbody: Elements, rows: List>, sep: String): MutableList { + private fun getRowElements( + mainbody: Elements, + rows: List>, + sep: String + ): MutableList { val all = mutableListOf() for (item in rows) { val title = item.first @@ -36,10 +39,14 @@ class PinoyMoviesEsProvider : MainAPI() { if (urlTitle.isNullOrEmpty()) { urlTitle = it?.select("div.data") } - if (urlTitle.isNullOrEmpty()) { return@mapNotNull null } + if (urlTitle.isNullOrEmpty()) { + return@mapNotNull null + } // Fetch details val link = fixUrlNull(urlTitle.select("a")?.attr("href")) - if (link.isNullOrBlank()) { return@mapNotNull null } + if (link.isNullOrBlank()) { + return@mapNotNull null + } val image = it?.select("div.poster > img")?.attr("data-src") @@ -47,7 +54,9 @@ class PinoyMoviesEsProvider : MainAPI() { val name = urlTitle.select("h3")?.text() ?: urlTitle.select("h2")?.text() ?: urlTitle.select("h1")?.text() - if (name.isNullOrBlank()) { return@mapNotNull null } + if (name.isNullOrBlank()) { + return@mapNotNull null + } var year = urlTitle.select("span")?.text()?.toIntOrNull() @@ -80,27 +89,32 @@ class PinoyMoviesEsProvider : MainAPI() { } return all } + override suspend fun getMainPage(): HomePageResponse { val all = ArrayList() val document = app.get(mainUrl).document val mainbody = document.getElementsByTag("body") if (mainbody != null) { // All rows will be hardcoded bc of the nature of the site - val homepage1 = getRowElements(mainbody, listOf( - Pair("Suggestion", "items.featured"), - Pair("All Movies", "items.full") - ), ".") + val homepage1 = getRowElements( + mainbody, listOf( + Pair("Suggestion", "items.featured"), + Pair("All Movies", "items.full") + ), "." + ) if (homepage1.isNotEmpty()) { all.addAll(homepage1) } //2nd rows - val homepage2 = getRowElements(mainbody, listOf( - Pair("Action", "genre_action"), - Pair("Comedy", "genre_comedy"), - Pair("Romance", "genre_romance"), - Pair("Horror", "genre_horror") - //Pair("Rated-R", "genre_rated-r") - ), "#") + val homepage2 = getRowElements( + mainbody, listOf( + Pair("Action", "genre_action"), + Pair("Comedy", "genre_comedy"), + Pair("Romance", "genre_romance"), + Pair("Horror", "genre_horror") + //Pair("Rated-R", "genre_rated-r") + ), "#" + ) if (homepage2.isNotEmpty()) { all.addAll(homepage2) } @@ -156,7 +170,9 @@ class PinoyMoviesEsProvider : MainAPI() { val aName = a.select("img")?.attr("alt") ?: return@mapNotNull null val aYear = try { aName.trim().takeLast(5).removeSuffix(")").toIntOrNull() - } catch (e: Exception) { null } + } catch (e: Exception) { + null + } MovieSearchResponse( url = aUrl, name = aName, @@ -181,8 +197,10 @@ class PinoyMoviesEsProvider : MainAPI() { Pair("nume", "1"), Pair("type", "movie") ) - val innerPage = app.post("https://pinoymovies.es/wp-admin/admin-ajax.php ", - referer = url, data = content).document.select("body")?.text()?.trim() + val innerPage = app.post( + "https://pinoymovies.es/wp-admin/admin-ajax.php ", + referer = url, data = content + ).document.select("body")?.text()?.trim() if (!innerPage.isNullOrBlank()) { tryParseJson(innerPage)?.let { listOfLinks.add(it.embed_url) @@ -204,17 +222,17 @@ class PinoyMoviesEsProvider : MainAPI() { } override suspend fun loadLinks( - data: String, - isCasting: Boolean, - subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit ): Boolean { // parse movie servers var count = 0 tryParseJson>(data)?.forEach { link -> //Log.i(this.name, "Result => (link) $link") if (link.startsWith("https://vstreamhub.com")) { - VstreamhubHelper.getUrls(link, callback) + VstreamhubHelper.getUrls(link, subtitleCallback, callback) count++ } else if (link.contains("fembed.com")) { val extractor = FEmbed() @@ -224,7 +242,7 @@ class PinoyMoviesEsProvider : MainAPI() { count++ } } else { - if (loadExtractor(link, mainUrl, callback)) { + if (loadExtractor(link, mainUrl, subtitleCallback, callback)) { count++ } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/RebahinProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/RebahinProvider.kt index 84dae89c..0a45f118 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/RebahinProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/RebahinProvider.kt @@ -7,11 +7,12 @@ import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.safeApiCall import com.lagradost.cloudstream3.network.WebViewResolver -import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.getQualityFromName +import com.lagradost.cloudstream3.utils.loadExtractor import org.jsoup.nodes.Element import java.net.URI -import java.util.ArrayList class RebahinProvider : MainAPI() { override var mainUrl = "http://167.88.14.149" @@ -263,7 +264,7 @@ class RebahinProvider : MainAPI() { callback ) else -> { - loadExtractor(link, "$mainUrl/", callback) + loadExtractor(link, "$mainUrl/", subtitleCallback, callback) if (link.startsWith("https://sbfull.com")) { val response = app.get( link, interceptor = WebViewResolver( diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SeriesflixProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SeriesflixProvider.kt index 7fca3179..08b07b31 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SeriesflixProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SeriesflixProvider.kt @@ -217,7 +217,7 @@ class SeriesflixProvider : MainAPI() { allowRedirects = false ).okhttpResponse.headers.values("location").apmap { link -> val url1 = link.replace("#bu", "") - loadExtractor(url1, data, callback) + loadExtractor(url1, data, subtitleCallback, callback) } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SflixProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SflixProvider.kt index aba04ad5..0543e42f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SflixProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SflixProvider.kt @@ -24,7 +24,6 @@ import org.jsoup.Jsoup import org.jsoup.nodes.Element import java.net.URI import java.util.* -import kotlin.collections.ArrayList import kotlin.system.measureTimeMillis open class SflixProvider : MainAPI() { @@ -346,7 +345,7 @@ open class SflixProvider : MainAPI() { "https://ws11.rabbitstream.net/socket.io/?EIO=4&transport=polling" if (iframeLink.contains("streamlare", ignoreCase = true)) { - loadExtractor(iframeLink, null).forEach(callback) + loadExtractor(iframeLink, null,subtitleCallback,callback) } else { extractRabbitStream(iframeLink, subtitleCallback, callback, false) { it } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TantiFilmProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TantiFilmProvider.kt index 38d0a104..30b00ec0 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TantiFilmProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TantiFilmProvider.kt @@ -232,7 +232,7 @@ class TantifilmProvider : MainAPI() { iframe.forEach { id -> val doc2 = app.get(id).document val id2 = app.get(doc2.selectFirst("iframe")!!.attr("src")).url - loadExtractor(id2, data, callback) + loadExtractor(id2, data, subtitleCallback, callback) } return true } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TwoEmbedProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TwoEmbedProvider.kt index ba4e31e4..6d589533 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TwoEmbedProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TwoEmbedProvider.kt @@ -66,7 +66,7 @@ class TwoEmbedProvider : TmdbProvider() { if (iframeLink.contains("rabbitstream")) { extractRabbitStream(iframeLink, subtitleCallback, callback, false) { it } } else { - loadExtractor(iframeLink, embedUrl, callback) + loadExtractor(iframeLink, embedUrl, subtitleCallback, callback) } } return true diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidstreamProviderTemplate.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidstreamProviderTemplate.kt index 52b43037..513ce73d 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidstreamProviderTemplate.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidstreamProviderTemplate.kt @@ -67,8 +67,10 @@ open class VidstreamProviderTemplate : MainAPI() { open val iv: String? = null open val secretKey: String? = null open val secretDecryptKey: String? = null + /** Generated the key from IV and ID */ open val isUsingAdaptiveKeys: Boolean = false + /** * Generate data for the encrypt-ajax automatically (only on supported sites) * See $("script[data-name='episode']")[0].dataset.value @@ -260,7 +262,16 @@ open class VidstreamProviderTemplate : MainAPI() { val iframeLink = Jsoup.parse(app.get(data).text).selectFirst("iframe")?.attr("src") ?: return false - extractVidstream(iframeLink, this.name, callback, iv, secretKey, secretDecryptKey, isUsingAdaptiveKeys, isUsingAdaptiveData) + extractVidstream( + iframeLink, + this.name, + callback, + iv, + secretKey, + secretDecryptKey, + isUsingAdaptiveKeys, + isUsingAdaptiveData + ) // In this case the video player is a vidstream clone and can be handled by the vidstream extractor. // This case is a both unorthodox and you normally do not call extractors as they detect the url returned and does the rest. val vidstreamObject = Vidstream(vidstreamExtractorUrl ?: mainUrl) @@ -268,7 +279,7 @@ open class VidstreamProviderTemplate : MainAPI() { val id = Regex("""id=([^&]*)""").find(iframeLink)?.groupValues?.get(1) if (id != null) { - vidstreamObject.getUrl(id, isCasting, callback) + vidstreamObject.getUrl(id, isCasting, subtitleCallback, callback) } val html = app.get(fixUrl(iframeLink)).text diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/WatchAsianProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/WatchAsianProvider.kt index 6ee0d970..0e7e52b5 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/WatchAsianProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/WatchAsianProvider.kt @@ -22,7 +22,7 @@ class WatchAsianProvider : MainAPI() { val headers = mapOf("X-Requested-By" to mainUrl) val doc = app.get(mainUrl, headers = headers).document val rowPair = mutableListOf>() - doc.select("div.block-tab")?.forEach { + doc.select("div.block-tab").forEach { it?.select("ul.tab > li")?.mapNotNull { row -> val link = row?.attr("data-tab") ?: return@mapNotNull null val title = row.text() ?: return@mapNotNull null @@ -77,12 +77,12 @@ class WatchAsianProvider : MainAPI() { return document.mapNotNull { val innerA = it?.selectFirst("a") ?: return@mapNotNull null val link = fixUrlNull(innerA.attr("href")) ?: return@mapNotNull null - val title = it.select("h3.title")?.text() ?: return@mapNotNull null + val title = it.select("h3.title").text() ?: return@mapNotNull null if (title.isEmpty()) { return@mapNotNull null } val year = null - val imgsrc = innerA.select("img")?.attr("data-original") ?: return@mapNotNull null + val imgsrc = innerA.select("img").attr("data-original") ?: return@mapNotNull null val image = fixUrlNull(imgsrc) //Log.i(this.name, "Result => (img movie) $title / $link") MovieSearchResponse( @@ -100,31 +100,31 @@ class WatchAsianProvider : MainAPI() { val body = app.get(url).document // Declare vars val isDramaDetail = url.contains("/drama-detail/") - var poster = "" + var poster: String? = null var title = "" var descript: String? = null var year: Int? = null var tags: List? = null if (isDramaDetail) { val main = body.select("div.details") - val inner = main?.select("div.info") + val inner = main.select("div.info") // Video details - poster = fixUrlNull(main?.select("div.img > img")?.attr("src")) ?: "" + poster = fixUrlNull(main.select("div.img > img").attr("src")) //Log.i(this.name, "Result => (imgLinkCode) ${imgLinkCode}") - title = inner?.select("h1")?.firstOrNull()?.text() ?: "" + title = inner.select("h1").firstOrNull()?.text() ?: "" //Log.i(this.name, "Result => (year) ${title.substring(title.length - 5)}") - descript = inner?.text() + descript = inner.text() - inner?.select("p")?.forEach { p -> + inner.select("p").forEach { p -> val caption = p?.selectFirst("span")?.text()?.trim()?.lowercase()?.removeSuffix(":")?.trim() ?: return@forEach when (caption) { "genre" -> { - tags = p.select("a")?.mapNotNull { it?.text()?.trim() } + tags = p.select("a").mapNotNull { it?.text()?.trim() } } "released" -> { - year = p.select("a")?.text()?.trim()?.toIntOrNull() + year = p.select("a").text().trim()?.toIntOrNull() } } } @@ -147,7 +147,7 @@ class WatchAsianProvider : MainAPI() { // Episodes Links //Log.i(this.name, "Result => (all eps) ${body.select("ul.list-episode-item-2.all-episode > li")}") - val episodeList = body.select("ul.list-episode-item-2.all-episode > li")?.mapNotNull { ep -> + val episodeList = body.select("ul.list-episode-item-2.all-episode > li").mapNotNull { ep -> //Log.i(this.name, "Result => (epA) ${ep.select("a")}") val innerA = ep.select("a") ?: return@mapNotNull null //Log.i(this.name, "Result => (innerA) ${fixUrlNull(innerA.attr("href"))}") @@ -164,7 +164,7 @@ class WatchAsianProvider : MainAPI() { posterUrl = poster, date = null ) - } ?: listOf() + } //If there's only 1 episode, consider it a movie. if (episodeList.size == 1) { //Clean title @@ -216,21 +216,24 @@ class WatchAsianProvider : MainAPI() { url.startsWith("https://asianembed.io") || url.startsWith("https://asianload.io") -> { val iv = "9262859232435825" val secretKey = "93422192433952489752342908585752" - extractVidstream(url, this.name, callback, iv, secretKey, secretKey, + extractVidstream( + url, this.name, callback, iv, secretKey, secretKey, isUsingAdaptiveKeys = false, isUsingAdaptiveData = false ) - AsianEmbedHelper.getUrls(url, callback) + AsianEmbedHelper.getUrls(url, subtitleCallback, callback) } url.startsWith("https://embedsito.com") -> { val extractor = XStreamCdn() extractor.domainUrl = "embedsito.com" - extractor.getSafeUrl(url)?.apmap { link -> - callback.invoke(link) - } + extractor.getSafeUrl( + url, + subtitleCallback = subtitleCallback, + callback = callback, + ) } else -> { - loadExtractor(url, mainUrl, callback) + loadExtractor(url, mainUrl, subtitleCallback, callback) } } } @@ -240,8 +243,8 @@ class WatchAsianProvider : MainAPI() { private suspend fun getServerLinks(url: String): String { val moviedoc = app.get(url, referer = mainUrl).document return moviedoc.select("div.anime_muti_link > ul > li") - ?.mapNotNull { + .mapNotNull { fixUrlNull(it?.attr("data-video")) ?: return@mapNotNull null - }?.toJson() ?: "" + }.toJson() } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/YomoviesProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/YomoviesProvider.kt index f50507c6..149b9dae 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/YomoviesProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/YomoviesProvider.kt @@ -7,7 +7,6 @@ import com.lagradost.cloudstream3.mvvm.safeApiCall import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.loadExtractor import org.jsoup.nodes.Element -import java.util.ArrayList class YomoviesProvider : MainAPI() { override var mainUrl = "https://yomovies.plus" @@ -122,8 +121,15 @@ class YomoviesProvider : MainAPI() { source, referer = "$mainUrl/" ).document.select("ul.list-server-items li") - .apmap { loadExtractor(it.attr("data-video").substringBefore("=https://msubload"), "$mainUrl/", callback) } - else -> loadExtractor(source, "$mainUrl/", callback) + .apmap { + loadExtractor( + it.attr("data-video").substringBefore("=https://msubload"), + "$mainUrl/", + subtitleCallback, + callback + ) + } + else -> loadExtractor(source, "$mainUrl/", subtitleCallback, callback) } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/AbstractPlayerFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/AbstractPlayerFragment.kt index df0944e5..0ce93821 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/AbstractPlayerFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/AbstractPlayerFragment.kt @@ -375,6 +375,7 @@ abstract class AbstractPlayerFragment( subView = player_view?.findViewById(R.id.exo_subtitles) subStyle = SubtitlesFragment.getCurrentSavedStyle() player.initSubtitles(subView, subtitle_holder, subStyle) + SubtitlesFragment.applyStyleEvent += ::onSubStyleChanged try { diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/LinkGenerator.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/LinkGenerator.kt index d604e2f8..f56fcb51 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/LinkGenerator.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/LinkGenerator.kt @@ -44,7 +44,9 @@ class LinkGenerator( offset: Int ): Boolean { links.apmap { link -> - if (!extract || !loadExtractor(link, referer) { + if (!extract || !loadExtractor(link, referer, { + subtitleCallback(PlayerSubtitleHelper.getSubtitleData(it)) + }) { callback(it to null) }) { diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerSubtitleHelper.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerSubtitleHelper.kt index 11fd76b1..7e13c292 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerSubtitleHelper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerSubtitleHelper.kt @@ -1,5 +1,6 @@ package com.lagradost.cloudstream3.ui.player +import android.util.Log import android.util.TypedValue import android.view.ViewGroup import android.widget.FrameLayout @@ -89,6 +90,7 @@ class PlayerSubtitleHelper { regexSubtitlesToRemoveCaptions = style.removeCaptions subtitleView?.context?.let { ctx -> subStyle = style + Log.i(TAG,"SET STYLE = $style") subtitleView?.setStyle(ctx.fromSaveToStyle(style)) subtitleView?.translationY = -style.elevation.toPx.toFloat() val size = style.fixedTextSize diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt index 6e4f0db2..e5b13abf 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt @@ -1901,7 +1901,7 @@ class ResultFragment : ResultTrailerPlayer() { setRecommendations(d.recommendations, null) setActors(d.actors) setNextEpisode(if (d is EpisodeResponse) d.nextAiring else null) - setTrailers(d.trailers) + setTrailers(d.trailers.flatMap { it.mirros }) // I dont care about subtitles yet! if (syncModel.addSyncs(d.syncData)) { syncModel.updateMetaAndUser() diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt index cf706183..0fc81200 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt @@ -1,12 +1,12 @@ package com.lagradost.cloudstream3.utils import android.net.Uri +import com.lagradost.cloudstream3.SubtitleFile import com.lagradost.cloudstream3.TvType import com.lagradost.cloudstream3.USER_AGENT import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.extractors.* import com.lagradost.cloudstream3.mvvm.logError -import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall import kotlinx.coroutines.delay import org.jsoup.Jsoup @@ -155,12 +155,26 @@ suspend fun unshortenLinkSafe(url: String): String { } } +suspend fun loadExtractor( + url: String, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit +): Boolean { + return loadExtractor( + url = url, + referer = null, + subtitleCallback = subtitleCallback, + callback = callback + ) +} + /** * Tries to load the appropriate extractor based on link, returns true if any extractor is loaded. * */ suspend fun loadExtractor( url: String, referer: String? = null, + subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ): Boolean { val currentUrl = unshortenLinkSafe(url) @@ -169,7 +183,7 @@ suspend fun loadExtractor( if (currentUrl.replace(schemaStripRegex, "") .startsWith(extractor.mainUrl.replace(schemaStripRegex, "")) ) { - extractor.getSafeUrl(currentUrl, referer)?.forEach(callback) + extractor.getSafeUrl(currentUrl, referer, subtitleCallback, callback) return true } } @@ -177,20 +191,6 @@ suspend fun loadExtractor( return false } -suspend fun loadExtractor( - url: String, - referer: String? = null, -): List { - val currentUrl = unshortenLinkSafe(url) - - for (extractor in extractorApis) { - if (currentUrl.startsWith(extractor.mainUrl)) { - return extractor.getSafeUrl(currentUrl, referer) ?: emptyList() - } - } - return emptyList() -} - val extractorApis: Array = arrayOf( //AllProvider(), WcoStream(), @@ -372,14 +372,39 @@ abstract class ExtractorApi { abstract val mainUrl: String abstract val requiresReferer: Boolean - suspend fun getSafeUrl(url: String, referer: String? = null): List? { - return suspendSafeApiCall { getUrl(url, referer) } + //suspend fun getSafeUrl(url: String, referer: String? = null): List? { + // return suspendSafeApiCall { getUrl(url, referer) } + //} + + // this is the new extractorapi, override to add subtitles and stuff + open suspend fun getUrl( + url: String, + referer: String? = null, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ) { + getUrl(url, referer)?.forEach(callback) + } + + suspend fun getSafeUrl( + url: String, + referer: String? = null, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ) { + try { + getUrl(url, referer, subtitleCallback, callback) + } catch (e: Exception) { + logError(e) + } } /** * Will throw errors, use getSafeUrl if you don't want to handle the exception yourself */ - abstract suspend fun getUrl(url: String, referer: String? = null): List? + open suspend fun getUrl(url: String, referer: String? = null): List? { + return emptyList() + } open fun getExtractorUrl(id: String): String { return id