massively improved zoro

This commit is contained in:
Blatzar 2021-12-12 02:49:41 +01:00
parent 4b0a3e0c4e
commit 2a55a256aa
5 changed files with 105 additions and 53 deletions

View file

@ -8,6 +8,7 @@ import com.lagradost.cloudstream3.movieproviders.SflixProvider.Companion.toExtra
import com.lagradost.cloudstream3.movieproviders.SflixProvider.Companion.toSubtitleFile import com.lagradost.cloudstream3.movieproviders.SflixProvider.Companion.toSubtitleFile
import com.lagradost.cloudstream3.network.WebViewResolver import com.lagradost.cloudstream3.network.WebViewResolver
import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.loadExtractor
import org.jsoup.Jsoup import org.jsoup.Jsoup
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.net.URI import java.net.URI
@ -152,7 +153,8 @@ class ZoroProvider : MainAPI() {
EnumSet.of(DubStatus.Subbed) EnumSet.of(DubStatus.Subbed)
} }
val tvType = getType(it.selectFirst(".film-detail > .fd-infor > .fdi-item")?.text().toString()) val tvType =
getType(it.selectFirst(".film-detail > .fd-infor > .fdi-item")?.text().toString())
val href = fixUrl(it.selectFirst(".film-name a").attr("href")) val href = fixUrl(it.selectFirst(".film-name a").attr("href"))
AnimeSearchResponse( AnimeSearchResponse(
@ -187,7 +189,8 @@ class ZoroProvider : MainAPI() {
when { when {
(year != null && japaneseTitle != null && status != null) -> break (year != null && japaneseTitle != null && status != null) -> break
text.contains("Premiered") && year == null -> text.contains("Premiered") && year == null ->
year = info.selectFirst(".name")?.text().toString().split(" ").last().toIntOrNull() year =
info.selectFirst(".name")?.text().toString().split(" ").last().toIntOrNull()
text.contains("Japanese") && japaneseTitle == null -> text.contains("Japanese") && japaneseTitle == null ->
japaneseTitle = info.selectFirst(".name")?.text().toString() japaneseTitle = info.selectFirst(".name")?.text().toString()
@ -255,61 +258,59 @@ class ZoroProvider : MainAPI() {
callback: (ExtractorLink) -> Unit callback: (ExtractorLink) -> Unit
): Boolean { ): Boolean {
// Copy pasted from Sflix :)
val servers: List<Pair<DubStatus, String>> = Jsoup.parse( val servers: List<Pair<DubStatus, String>> = Jsoup.parse(
mapper.readValue<Response>( app.get("$mainUrl/ajax/v2/episode/servers?episodeId=" + data.split("=")[1])
app.get("$mainUrl/ajax/v2/episode/servers?episodeId=" + data.split("=")[1]).text .mapped<Response>().html
).html
).select(".server-item[data-type][data-id]").map { ).select(".server-item[data-type][data-id]").map {
Pair(if (it.attr("data-type") == "sub") DubStatus.Subbed else DubStatus.Dubbed, it.attr("data-id")!!)
}
val res = app.get(
data,
interceptor = WebViewResolver(
Regex("""/getSources""")
)
)
// println("RES TEXT ${res.text}")
val recaptchaToken = res.response.request.url.queryParameter("_token")
val responses = servers.map {
val link = "$mainUrl/ajax/v2/episode/sources?id=${it.second}&_token=$recaptchaToken"
Pair( Pair(
it.first, if (it.attr("data-type") == "sub") DubStatus.Subbed else DubStatus.Dubbed,
getM3u8FromRapidCloud( it.attr("data-id")!!
mapper.readValue<RapidCloudResponse>(
app.get(
link,
res.headers.toMap()
).text
).link
)
) )
} }
responses.forEach { // Prevent duplicates
if (it.second.contains("<html")) return@forEach servers.distinctBy { it.second }.pmap {
val mapped = mapper.readValue<SflixProvider.SourceObject>(it.second) val link =
"$mainUrl/ajax/v2/episode/sources?id=${it.second}"
val extractorLink = app.get(
link,
).mapped<RapidCloudResponse>().link
mapped.tracks?.forEach { track -> // Loads the links in the appropriate extractor.
track?.toSubtitleFile()?.let { subtitleFile -> val hasLoadedExtractorLink = loadExtractor(extractorLink, mainUrl, callback)
subtitleCallback.invoke(subtitleFile)
if (!hasLoadedExtractorLink) {
// Not an extractor because:
// 1. No subtitle callback
// 2. Missing dub/sub status in parameter (might be substituted in the referer)
val response =
getM3u8FromRapidCloud(
extractorLink
)
if (response.contains("<html")) return@pmap
val mapped = mapper.readValue<SflixProvider.SourceObject>(response)
mapped.tracks?.forEach { track ->
track?.toSubtitleFile()?.let { subtitleFile ->
subtitleCallback.invoke(subtitleFile)
}
} }
}
val list = listOf( val list = listOf(
mapped.sources to "source 1", mapped.sources to "source 1",
mapped.sources1 to "source 2", mapped.sources1 to "source 2",
mapped.sources2 to "source 3", mapped.sources2 to "source 3",
mapped.sourcesBackup to "source backup" mapped.sourcesBackup to "source backup"
) )
list.forEach { subList -> list.forEach { subList ->
subList.first?.forEach { a -> subList.first?.forEach { a ->
a?.toExtractorLink(this, subList.second + " - ${it.first}")?.forEach(callback) a?.toExtractorLink(this, subList.second + " - ${it.first}")
?.forEach(callback)
}
} }
} }
} }

View file

@ -0,0 +1,45 @@
package com.lagradost.cloudstream3.extractors
import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.network.WebViewResolver
import com.lagradost.cloudstream3.utils.ExtractorApi
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.M3u8Helper
import com.lagradost.cloudstream3.utils.getQualityFromName
class WatchSB : ExtractorApi() {
override val name: String
get() = "WatchSB"
override val mainUrl: String
get() = "https://watchsb.com"
override val requiresReferer: Boolean
get() = false
override fun getUrl(url: String, referer: String?): List<ExtractorLink> {
val response = app.get(
url, interceptor = WebViewResolver(
Regex("""master\.m3u8""")
)
)
val extractedLinksList = M3u8Helper().m3u8Generation(
M3u8Helper.M3u8Stream(
response.url,
headers = response.headers.toMap()
), true
)
.map { stream ->
val qualityString = if ((stream.quality ?: 0) == 0) "" else "${stream.quality}p"
ExtractorLink(
name,
"$name $qualityString",
stream.streamUrl,
url,
getQualityFromName(stream.quality.toString()),
true
)
}
return extractedLinksList
}
}

View file

@ -9,6 +9,8 @@ import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.mapper import com.lagradost.cloudstream3.mapper
import okhttp3.* import okhttp3.*
import okhttp3.Headers.Companion.toHeaders import okhttp3.Headers.Companion.toHeaders
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import java.io.File import java.io.File
import java.net.URI import java.net.URI
import java.util.* import java.util.*
@ -78,6 +80,7 @@ class AppResponse(
val body by lazy { response.body } val body by lazy { response.body }
val code = response.code val code = response.code
val headers = response.headers val headers = response.headers
val document: Document by lazy { Jsoup.parse(text) }
/** Same as using mapper.readValue<T>() */ /** Same as using mapper.readValue<T>() */
inline fun <reified T : Any> mapped(): T { inline fun <reified T : Any> mapped(): T {

View file

@ -741,9 +741,7 @@ class PlayerFragment : Fragment() {
} }
private fun safeReleasePlayer() { private fun safeReleasePlayer() {
thread { simpleCache?.release()
simpleCache?.release()
}
if (this::exoPlayer.isInitialized) { if (this::exoPlayer.isInitialized) {
exoPlayer.release() exoPlayer.release()
} }
@ -1928,7 +1926,6 @@ class PlayerFragment : Fragment() {
// torrentStream?.stopStream() // torrentStream?.stopStream()
// torrentStream = null // torrentStream = null
super.onDestroy()
canEnterPipMode = false canEnterPipMode = false
savePositionInPlayer() savePositionInPlayer()
@ -1938,6 +1935,7 @@ class PlayerFragment : Fragment() {
activity?.showSystemUI() activity?.showSystemUI()
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER
super.onDestroy()
} }
override fun onPause() { override fun onPause() {

View file

@ -58,13 +58,17 @@ fun getAndUnpack(string: String): String {
return JsUnpacker(packedText).unpack() ?: string return JsUnpacker(packedText).unpack() ?: string
} }
fun loadExtractor(url: String, referer: String?, callback: (ExtractorLink) -> Unit) { /**
* Tries to load the appropriate extractor based on link, returns true if any extractor is loaded.
* */
fun loadExtractor(url: String, referer: String?, callback: (ExtractorLink) -> Unit) : Boolean {
for (extractor in extractorApis) { for (extractor in extractorApis) {
if (url.startsWith(extractor.mainUrl)) { if (url.startsWith(extractor.mainUrl)) {
extractor.getSafeUrl(url, referer)?.forEach(callback) extractor.getSafeUrl(url, referer)?.forEach(callback)
return return true
} }
} }
return false
} }
val extractorApis: Array<ExtractorApi> = arrayOf( val extractorApis: Array<ExtractorApi> = arrayOf(
@ -78,6 +82,7 @@ val extractorApis: Array<ExtractorApi> = arrayOf(
Streamhub(), Streamhub(),
SBPlay(), SBPlay(),
FEmbed(), FEmbed(),
WatchSB(),
// dood extractors // dood extractors
DoodToExtractor(), DoodToExtractor(),