mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
fixed Sflix and Zoro
This commit is contained in:
parent
2f71fa5664
commit
70c14d116c
4 changed files with 51 additions and 17 deletions
|
@ -250,7 +250,10 @@ class ZoroProvider : MainAPI() {
|
||||||
private fun getM3u8FromRapidCloud(url: String): String {
|
private fun getM3u8FromRapidCloud(url: String): String {
|
||||||
return get(
|
return get(
|
||||||
"$url&autoPlay=1&oa=0",
|
"$url&autoPlay=1&oa=0",
|
||||||
headers = mapOf("Referer" to "https://zoro.to/", "User-Agent" to "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0"),
|
headers = mapOf(
|
||||||
|
"Referer" to "https://zoro.to/",
|
||||||
|
"User-Agent" to "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0"
|
||||||
|
),
|
||||||
interceptor = WebViewResolver(
|
interceptor = WebViewResolver(
|
||||||
Regex("""/getSources""")
|
Regex("""/getSources""")
|
||||||
)
|
)
|
||||||
|
@ -284,17 +287,35 @@ class ZoroProvider : MainAPI() {
|
||||||
Regex("""/getSources""")
|
Regex("""/getSources""")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
// println("RES TEXT ${res.text}")
|
||||||
|
|
||||||
val recaptchaToken = res.request.url.queryParameter("_token")
|
val recaptchaToken = res.request.url.queryParameter("_token")
|
||||||
|
|
||||||
val responses = servers.map {
|
val responses = servers.map {
|
||||||
val link = "$mainUrl/ajax/v2/episode/sources?id=${it.second}&_token=$recaptchaToken"
|
val link = "$mainUrl/ajax/v2/episode/sources?id=${it.second}&_token=$recaptchaToken"
|
||||||
Pair(it.first, getM3u8FromRapidCloud(mapper.readValue<RapidCloudResponse>(get(link, res.request.headers.toMap()).text).link))
|
Pair(
|
||||||
|
it.first,
|
||||||
|
getM3u8FromRapidCloud(
|
||||||
|
mapper.readValue<RapidCloudResponse>(
|
||||||
|
get(
|
||||||
|
link,
|
||||||
|
res.request.headers.toMap()
|
||||||
|
).text
|
||||||
|
).link
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
responses.forEach {
|
responses.forEach {
|
||||||
if (it.second.contains("<html")) return@forEach
|
if (it.second.contains("<html")) return@forEach
|
||||||
val mapped = mapper.readValue<SflixProvider.SourceObject>(it.second)
|
val mapped = mapper.readValue<SflixProvider.SourceObject>(it.second)
|
||||||
|
|
||||||
|
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",
|
||||||
|
@ -307,12 +328,6 @@ class ZoroProvider : MainAPI() {
|
||||||
a?.toExtractorLink(this, subList.second + " - ${it.first}")?.forEach(callback)
|
a?.toExtractorLink(this, subList.second + " - ${it.first}")?.forEach(callback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mapped.tracks?.forEach { track ->
|
|
||||||
track?.toSubtitleFile()?.let { subtitleFile ->
|
|
||||||
subtitleCallback.invoke(subtitleFile)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -297,7 +297,11 @@ class SflixProvider : MainAPI() {
|
||||||
).text
|
).text
|
||||||
|
|
||||||
val mapped = mapper.readValue<SourceObject>(sources)
|
val mapped = mapper.readValue<SourceObject>(sources)
|
||||||
|
mapped.tracks?.forEach {
|
||||||
|
it?.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",
|
||||||
|
@ -309,11 +313,6 @@ class SflixProvider : MainAPI() {
|
||||||
it?.toExtractorLink(this, subList.second)?.forEach(callback)
|
it?.toExtractorLink(this, subList.second)?.forEach(callback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mapped.tracks?.forEach {
|
|
||||||
it?.toSubtitleFile()?.let { subtitleFile ->
|
|
||||||
subtitleCallback.invoke(subtitleFile)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ var baseClient = OkHttpClient()
|
||||||
private const val DEFAULT_TIME = 10
|
private const val DEFAULT_TIME = 10
|
||||||
private val DEFAULT_TIME_UNIT = TimeUnit.MINUTES
|
private val DEFAULT_TIME_UNIT = TimeUnit.MINUTES
|
||||||
private const val DEFAULT_USER_AGENT = USER_AGENT
|
private const val DEFAULT_USER_AGENT = USER_AGENT
|
||||||
private val DEFAULT_HEADERS = mapOf("User-Agent" to DEFAULT_USER_AGENT)
|
private val DEFAULT_HEADERS = mapOf("user-agent" to DEFAULT_USER_AGENT)
|
||||||
private val DEFAULT_DATA: Map<String, String> = mapOf()
|
private val DEFAULT_DATA: Map<String, String> = mapOf()
|
||||||
private val DEFAULT_COOKIES: Map<String, String> = mapOf()
|
private val DEFAULT_COOKIES: Map<String, String> = mapOf()
|
||||||
private val DEFAULT_REFERER: String? = null
|
private val DEFAULT_REFERER: String? = null
|
||||||
|
|
|
@ -4,12 +4,14 @@ import android.annotation.SuppressLint
|
||||||
import android.net.http.SslError
|
import android.net.http.SslError
|
||||||
import android.webkit.*
|
import android.webkit.*
|
||||||
import com.lagradost.cloudstream3.AcraApplication
|
import com.lagradost.cloudstream3.AcraApplication
|
||||||
|
import com.lagradost.cloudstream3.USER_AGENT
|
||||||
import com.lagradost.cloudstream3.utils.Coroutines.main
|
import com.lagradost.cloudstream3.utils.Coroutines.main
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
|
import java.net.URI
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
class WebViewResolver(val interceptUrl: Regex) : Interceptor {
|
class WebViewResolver(val interceptUrl: Regex) : Interceptor {
|
||||||
|
@ -48,6 +50,7 @@ class WebViewResolver(val interceptUrl: Regex) : Interceptor {
|
||||||
// Bare minimum to bypass captcha
|
// Bare minimum to bypass captcha
|
||||||
settings.javaScriptEnabled = true
|
settings.javaScriptEnabled = true
|
||||||
settings.domStorageEnabled = true
|
settings.domStorageEnabled = true
|
||||||
|
settings.userAgentString = USER_AGENT
|
||||||
}
|
}
|
||||||
|
|
||||||
webView?.webViewClient = object : WebViewClient() {
|
webView?.webViewClient = object : WebViewClient() {
|
||||||
|
@ -56,6 +59,7 @@ class WebViewResolver(val interceptUrl: Regex) : Interceptor {
|
||||||
request: WebResourceRequest
|
request: WebResourceRequest
|
||||||
): WebResourceResponse? {
|
): WebResourceResponse? {
|
||||||
val webViewUrl = request.url.toString()
|
val webViewUrl = request.url.toString()
|
||||||
|
// println("Loading WebView URL: $webViewUrl")
|
||||||
|
|
||||||
if (interceptUrl.containsMatchIn(webViewUrl)) {
|
if (interceptUrl.containsMatchIn(webViewUrl)) {
|
||||||
fixedRequest = getRequestCreator(
|
fixedRequest = getRequestCreator(
|
||||||
|
@ -70,12 +74,28 @@ class WebViewResolver(val interceptUrl: Regex) : Interceptor {
|
||||||
|
|
||||||
println("Web-view request finished: $webViewUrl")
|
println("Web-view request finished: $webViewUrl")
|
||||||
destroyWebView()
|
destroyWebView()
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Suppress image requests as we don't display them anywhere
|
||||||
|
// Less data, low chance of causing issues.
|
||||||
|
val blacklistedFiles = listOf(".jpg", ".png", ".webp", ".jpeg", ".webm", ".mp4")
|
||||||
|
|
||||||
|
/** NOTE! request.requestHeaders is not perfect!
|
||||||
|
* They don't contain all the headers the browser actually gives.
|
||||||
|
* Overriding with okhttp might fuck up otherwise working requests,
|
||||||
|
* e.g the recaptcha request.
|
||||||
|
* **/
|
||||||
return try {
|
return try {
|
||||||
when {
|
when {
|
||||||
// suppress favicon requests as we don't display them anywhere
|
blacklistedFiles.any { URI(webViewUrl).path.endsWith(it) } || webViewUrl.endsWith(
|
||||||
webViewUrl.endsWith("/favicon.ico") -> WebResourceResponse("image/png", null, null)
|
"/favicon.ico"
|
||||||
|
) -> WebResourceResponse(
|
||||||
|
"image/png",
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
|
||||||
webViewUrl.contains("recaptcha") -> super.shouldInterceptRequest(view, request)
|
webViewUrl.contains("recaptcha") -> super.shouldInterceptRequest(view, request)
|
||||||
|
|
||||||
request.method == "GET" -> get(
|
request.method == "GET" -> get(
|
||||||
|
|
Loading…
Reference in a new issue