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,44 +258,40 @@ 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
// Loads the links in the appropriate extractor.
val hasLoadedExtractorLink = loadExtractor(extractorLink, mainUrl, callback)
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 -> mapped.tracks?.forEach { track ->
track?.toSubtitleFile()?.let { subtitleFile -> track?.toSubtitleFile()?.let { subtitleFile ->
@ -309,7 +308,9 @@ class ZoroProvider : MainAPI() {
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(),