Fixed almost all providers

This commit is contained in:
Blatzar 2022-08-10 04:08:53 +02:00
parent 5c5a8d142f
commit 51101ae3b3
30 changed files with 565 additions and 52 deletions

View File

@ -1,5 +1,6 @@
dependencies {
// implementation(project(mapOf("path" to ":SflixProvider")))
implementation(project(mapOf("path" to ":SflixProvider")))
// implementation(project(mapOf("path" to ":SflixProvider")))
}
// use an integer for version numbers
version = 1

View File

@ -1,3 +1,6 @@
dependencies {
implementation(project(mapOf("path" to ":VidstreamProviderTemplate")))
}
// use an integer for version numbers
version = 1

View File

@ -1,7 +1,8 @@
package com.lagradost
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.animeproviders.GogoanimeProvider.Companion.extractVidstream
import com.lagradost.cloudstream3.extractors.Vidstream
//import com.lagradost.cloudstream3.animeproviders.GogoanimeProvider.Companion.extractVidstream
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.loadExtractor
@ -200,7 +201,7 @@ class DramaSeeProvider : MainAPI() {
val iv = "9262859232435825"
val secretKey = "93422192433952489752342908585752"
val secretDecryptKey = "93422192433952489752342908585752"
extractVidstream(
Vidstream.extractVidstream(
iframe.url,
this.name,
callback,

View File

@ -1,3 +1,7 @@
dependencies {
implementation(project(mapOf("path" to ":WatchAsianProvider")))
implementation(project(mapOf("path" to ":WatchAsianProvider")))
}
// use an integer for version numbers
version = 1

View File

@ -2,8 +2,6 @@ package com.lagradost
import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.extractors.XStreamCdn
import com.lagradost.cloudstream3.extractors.helper.AsianEmbedHelper
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.AppUtils.toJson

View File

@ -1,3 +1,7 @@
dependencies {
implementation(project(mapOf("path" to ":VidstreamProviderTemplate")))
implementation(project(mapOf("path" to ":VidEmbedProvider")))
}
// use an integer for version numbers
version = 1

View File

@ -2,7 +2,7 @@ package com.lagradost
import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.animeproviders.GogoanimeProvider.Companion.extractVidstream
import com.lagradost.cloudstream3.extractors.Vidstream
import com.lagradost.cloudstream3.metaproviders.TmdbLink
import com.lagradost.cloudstream3.metaproviders.TmdbProvider
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
@ -115,7 +115,7 @@ class OpenVidsProvider:TmdbProvider() {
listservers.apmap { links ->
if (links.contains("membed")) {
val membed = VidEmbedProvider()
extractVidstream(
Vidstream.extractVidstream(
links,
this.name,
callback,

View File

@ -1,3 +1,6 @@
dependencies {
implementation(project(mapOf("path" to ":WatchAsianProvider")))
}
// use an integer for version numbers
version = 1

View File

@ -1,7 +1,7 @@
package com.lagradost
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.extractors.FEmbed
//import com.lagradost.cloudstream3.extractors.FEmbed
import com.lagradost.cloudstream3.utils.AppUtils.toJson
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
import com.lagradost.cloudstream3.utils.ExtractorLink

View File

@ -1,3 +1,6 @@
dependencies {
implementation(project(mapOf("path" to ":WatchAsianProvider")))
}
// use an integer for version numbers
version = 1

View File

@ -2,8 +2,8 @@ package com.lagradost
import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.extractors.FEmbed
import com.lagradost.cloudstream3.extractors.helper.VstreamhubHelper
//import com.lagradost.cloudstream3.extractors.FEmbed
//import com.lagradost.cloudstream3.extractors.helper.VstreamhubHelper
import com.lagradost.cloudstream3.network.DdosGuardKiller
import com.lagradost.cloudstream3.utils.AppUtils.toJson
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson

View File

@ -0,0 +1,58 @@
package com.lagradost
import com.lagradost.cloudstream3.SubtitleFile
import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.Qualities
import com.lagradost.cloudstream3.utils.loadExtractor
class VstreamhubHelper {
companion object {
private val baseUrl: String = "https://vstreamhub.com"
private val baseName: String = "Vstreamhub"
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")
doc?.forEach {
val innerText = it?.toString()
if (!innerText.isNullOrEmpty()) {
if (innerText.contains("file:")) {
val startString = "file: "
val aa = innerText.substring(innerText.indexOf(startString))
val linkUrl =
aa.substring(startString.length + 1, aa.indexOf("\",")).trim()
//Log.i(baseName, "Result => (linkUrl) ${linkUrl}")
val exlink = ExtractorLink(
name = "$baseName m3u8",
source = baseName,
url = linkUrl,
quality = Qualities.Unknown.value,
referer = url,
isM3u8 = true
)
callback.invoke(exlink)
}
if (innerText.contains("playerInstance")) {
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("\"")
if (datavid.isNotBlank()) {
loadExtractor(datavid, url, subtitleCallback, callback)
//Log.i(baseName, "Result => (datavid) ${datavid}")
}
}
}
}
}
}
}
}

View File

@ -1,16 +1,11 @@
**⚠️ This is currently under development, dont use it yet if you're not comfortable with constantly merging new changes**
# `Cloudstream3 Plugin Repo Template`
# Cloudstream 3 Movies Repository
Template for a [Cloudstream3](https://github.com/recloudstream) plugin repo
Not all extractors are included, only those need to compile. We need to use loadExtractor in the future.
**⚠️ Make sure you check "Include all branches" when using this template**
## Getting started with writing your first plugin
This template includes 1 example plugin.
1. Open the root build.gradle.kts, read the comments and replace all the placeholders
2. Familiarize yourself with the project structure. Most files are commented
3. Build or deploy your first plugin using:

View File

@ -8,9 +8,7 @@ import com.lagradost.cloudstream3.APIHolder.unixTimeMS
import com.lagradost.cloudstream3.LoadResponse.Companion.addActors
import com.lagradost.cloudstream3.LoadResponse.Companion.addDuration
import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
import com.lagradost.cloudstream3.animeproviders.ZoroProvider
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
import com.lagradost.cloudstream3.mvvm.safeApiCall
//import com.lagradost.cloudstream3.animeproviders.ZoroProvider
import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
@ -678,19 +676,19 @@ open class SflixProvider : MainAPI() {
var sid: String? = null
if (useSidAuthentication && extractorData != null) {
negotiateNewSid(extractorData)?.also {
negotiateNewSid(extractorData)?.also { pollingData ->
app.post(
"$extractorData&t=${generateTimeStamp()}&sid=${it.sid}",
"$extractorData&t=${generateTimeStamp()}&sid=${pollingData.sid}",
requestBody = "40".toRequestBody(),
timeout = 60
)
val text = app.get(
"$extractorData&t=${generateTimeStamp()}&sid=${it.sid}",
"$extractorData&t=${generateTimeStamp()}&sid=${pollingData.sid}",
timeout = 60
).text.replaceBefore("{", "")
sid = parseJson<PollingData>(text).sid
ioSafe { app.get("$extractorData&t=${generateTimeStamp()}&sid=${it.sid}") }
ioSafe { app.get("$extractorData&t=${generateTimeStamp()}&sid=${pollingData.sid}") }
}
}
@ -738,7 +736,7 @@ open class SflixProvider : MainAPI() {
)
?.forEach {
// Sets Zoro SID used for video loading
(this as? ZoroProvider)?.sid?.set(it.url.hashCode(), sid)
// (this as? ZoroProvider)?.sid?.set(it.url.hashCode(), sid)
callback(it)
}
}

View File

@ -1,3 +1,6 @@
dependencies {
implementation(project(mapOf("path" to ":SflixProvider")))
}
// use an integer for version numbers
version = 1

View File

@ -1,3 +1,6 @@
dependencies {
implementation(project(mapOf("path" to ":SflixProvider")))
}
// use an integer for version numbers
version = 1

View File

@ -2,6 +2,8 @@ package com.lagradost
import android.util.Log
import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.SflixProvider.Companion.extractRabbitStream
import com.lagradost.SflixProvider.Companion.runSflixExtractorVerifierJob
import com.lagradost.cloudstream3.APIHolder.getCaptchaToken
import com.lagradost.cloudstream3.SubtitleFile
import com.lagradost.cloudstream3.TvType
@ -9,8 +11,6 @@ import com.lagradost.cloudstream3.apmap
import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.metaproviders.TmdbLink
import com.lagradost.cloudstream3.metaproviders.TmdbProvider
import com.lagradost.cloudstream3.movieproviders.SflixProvider.Companion.extractRabbitStream
import com.lagradost.cloudstream3.movieproviders.SflixProvider.Companion.runSflixExtractorVerifierJob
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.loadExtractor

View File

@ -1,3 +1,6 @@
dependencies {
implementation(project(mapOf("path" to ":VidstreamProviderTemplate")))
}
// use an integer for version numbers
version = 1

View File

@ -2,11 +2,12 @@ package com.lagradost
import com.lagradost.cloudstream3.SubtitleFile
import com.lagradost.cloudstream3.TvType
import com.lagradost.cloudstream3.extractors.VidSrcExtractor
//import com.lagradost.cloudstream3.extractors.VidSrcExtractor
import com.lagradost.cloudstream3.metaproviders.TmdbLink
import com.lagradost.cloudstream3.metaproviders.TmdbProvider
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.loadExtractor
class VidSrcProvider : TmdbProvider() {
override val apiName = "VidSrc"
@ -19,9 +20,9 @@ class VidSrcProvider : TmdbProvider() {
TvType.TvSeries,
)
companion object {
val extractor = VidSrcExtractor()
}
// companion object {
// val extractor = VidSrcExtractor()
// }
override suspend fun loadLinks(
data: String,
@ -44,7 +45,8 @@ class VidSrcProvider : TmdbProvider() {
"$mainUrl/embed/$suffix"
}
extractor.getSafeUrl(embedUrl, null, subtitleCallback, callback)
loadExtractor(embedUrl, null, subtitleCallback, callback)
// extractor.getSafeUrl(embedUrl, null, subtitleCallback, callback)
return true
}

View File

@ -0,0 +1,59 @@
package com.lagradost
import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.utils.ExtractorApi
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.Qualities
import com.lagradost.cloudstream3.utils.getQualityFromName
import java.net.URI
class MultiQuality : ExtractorApi() {
override var name = "MultiQuality"
override var mainUrl = "https://gogo-play.net"
private val sourceRegex = Regex("""file:\s*['"](.*?)['"],label:\s*['"](.*?)['"]""")
private val m3u8Regex = Regex(""".*?(\d*).m3u8""")
private val urlRegex = Regex("""(.*?)([^/]+$)""")
override val requiresReferer = false
override fun getExtractorUrl(id: String): String {
return "$mainUrl/loadserver.php?id=$id"
}
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> {
val extractedLinksList: MutableList<ExtractorLink> = mutableListOf()
with(app.get(url)) {
sourceRegex.findAll(this.text).forEach { sourceMatch ->
val extractedUrl = sourceMatch.groupValues[1]
// Trusting this isn't mp4, may fuck up stuff
if (URI(extractedUrl).path.endsWith(".m3u8")) {
with(app.get(extractedUrl)) {
m3u8Regex.findAll(this.text).forEach { match ->
extractedLinksList.add(
ExtractorLink(
name,
name = name,
urlRegex.find(this.url)!!.groupValues[1] + match.groupValues[0],
url,
getQualityFromName(match.groupValues[1]),
isM3u8 = true
)
)
}
}
} else if (extractedUrl.endsWith(".mp4")) {
extractedLinksList.add(
ExtractorLink(
name,
"$name ${sourceMatch.groupValues[2]}",
extractedUrl,
url.replace(" ", "%20"),
Qualities.Unknown.value,
)
)
}
}
return extractedLinksList
}
}
}

View File

@ -0,0 +1,235 @@
package com.lagradost.cloudstream3.extractors
import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.MultiQuality
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
import com.lagradost.cloudstream3.mvvm.safeApiCall
import com.lagradost.cloudstream3.utils.*
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import java.net.URI
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
/**
* overrideMainUrl is necessary for for other vidstream clones like vidembed.cc
* If they diverge it'd be better to make them separate.
* */
class Vidstream(val mainUrl: String) {
val name: String = "Vidstream"
companion object {
data class GogoSources(
@JsonProperty("source") val source: List<GogoSource>?,
@JsonProperty("sourceBk") val sourceBk: List<GogoSource>?,
//val track: List<Any?>,
//val advertising: List<Any?>,
//val linkiframe: String
)
data class GogoSource(
@JsonProperty("file") val file: String,
@JsonProperty("label") val label: String?,
@JsonProperty("type") val type: String?,
@JsonProperty("default") val default: String? = null
)
// https://github.com/saikou-app/saikou/blob/3e756bd8e876ad7a9318b17110526880525a5cd3/app/src/main/java/ani/saikou/anime/source/extractors/GogoCDN.kt#L60
// No Licence on the function
private fun cryptoHandler(
string: String,
iv: String,
secretKeyString: String,
encrypt: Boolean = true
): String {
//println("IV: $iv, Key: $secretKeyString, encrypt: $encrypt, Message: $string")
val ivParameterSpec = IvParameterSpec(iv.toByteArray())
val secretKey = SecretKeySpec(secretKeyString.toByteArray(), "AES")
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
return if (!encrypt) {
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec)
String(cipher.doFinal(base64DecodeArray(string)))
} else {
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec)
base64Encode(cipher.doFinal(string.toByteArray()))
}
}
/**
* @param iframeUrl something like https://gogoplay4.com/streaming.php?id=XXXXXX
* @param mainApiName used for ExtractorLink names and source
* @param iv secret iv from site, required non-null if isUsingAdaptiveKeys is off
* @param secretKey secret key for decryption from site, required non-null if isUsingAdaptiveKeys is off
* @param secretDecryptKey secret key to decrypt the response json, required non-null if isUsingAdaptiveKeys is off
* @param isUsingAdaptiveKeys generates keys from IV and ID, see getKey()
* @param isUsingAdaptiveData generate encrypt-ajax data based on $("script[data-name='episode']")[0].dataset.value
* */
suspend fun extractVidstream(
iframeUrl: String,
mainApiName: String,
callback: (ExtractorLink) -> Unit,
iv: String?,
secretKey: String?,
secretDecryptKey: String?,
// This could be removed, but i prefer it verbose
isUsingAdaptiveKeys: Boolean,
isUsingAdaptiveData: Boolean,
// If you don't want to re-fetch the document
iframeDocument: Document? = null
) = safeApiCall {
// https://github.com/saikou-app/saikou/blob/3e756bd8e876ad7a9318b17110526880525a5cd3/app/src/main/java/ani/saikou/anime/source/extractors/GogoCDN.kt
// No Licence on the following code
// Also modified of https://github.com/jmir1/aniyomi-extensions/blob/master/src/en/gogoanime/src/eu/kanade/tachiyomi/animeextension/en/gogoanime/extractors/GogoCdnExtractor.kt
// License on the code above https://github.com/jmir1/aniyomi-extensions/blob/master/LICENSE
if ((iv == null || secretKey == null || secretDecryptKey == null) && !isUsingAdaptiveKeys)
return@safeApiCall
val id = Regex("id=([^&]+)").find(iframeUrl)!!.value.removePrefix("id=")
var document: Document? = iframeDocument
val foundIv =
iv ?: (document ?: app.get(iframeUrl).document.also { document = it })
.select("""div.wrapper[class*=container]""")
.attr("class").split("-").lastOrNull() ?: return@safeApiCall
val foundKey = secretKey ?: getKey(base64Decode(id) + foundIv) ?: return@safeApiCall
val foundDecryptKey = secretDecryptKey ?: foundKey
val uri = URI(iframeUrl)
val mainUrl = "https://" + uri.host
val encryptedId = cryptoHandler(id, foundIv, foundKey)
val encryptRequestData = if (isUsingAdaptiveData) {
// Only fetch the document if necessary
val realDocument = document ?: app.get(iframeUrl).document
val dataEncrypted =
realDocument.select("script[data-name='episode']").attr("data-value")
val headers = cryptoHandler(dataEncrypted, foundIv, foundKey, false)
"id=$encryptedId&alias=$id&" + headers.substringAfter("&")
} else {
"id=$encryptedId&alias=$id"
}
val jsonResponse =
app.get(
"$mainUrl/encrypt-ajax.php?$encryptRequestData",
headers = mapOf("X-Requested-With" to "XMLHttpRequest")
)
val dataencrypted =
jsonResponse.text.substringAfter("{\"data\":\"").substringBefore("\"}")
val datadecrypted = cryptoHandler(dataencrypted, foundIv, foundDecryptKey, false)
val sources = AppUtils.parseJson<GogoSources>(datadecrypted)
fun invokeGogoSource(
source: GogoSource,
sourceCallback: (ExtractorLink) -> Unit
) {
sourceCallback.invoke(
ExtractorLink(
mainApiName,
mainApiName,
source.file,
mainUrl,
getQualityFromName(source.label),
isM3u8 = source.type == "hls" || source.label?.contains(
"auto",
ignoreCase = true
) == true
)
)
}
sources.source?.forEach {
invokeGogoSource(it, callback)
}
sources.sourceBk?.forEach {
invokeGogoSource(it, callback)
}
}
}
private fun getExtractorUrl(id: String): String {
return "$mainUrl/streaming.php?id=$id"
}
private fun getDownloadUrl(id: String): String {
return "$mainUrl/download?id=$id"
}
private val normalApis = arrayListOf(MultiQuality())
// https://gogo-stream.com/streaming.php?id=MTE3NDg5
suspend fun getUrl(
id: String,
isCasting: Boolean = false,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit,
): Boolean {
val extractorUrl = getExtractorUrl(id)
argamap(
{
normalApis.apmap { api ->
val url = api.getExtractorUrl(id)
api.getSafeUrl(
url,
callback = callback,
subtitleCallback = subtitleCallback
)
}
}, {
/** Stolen from GogoanimeProvider.kt extractor */
val link = getDownloadUrl(id)
println("Generated vidstream download link: $link")
val page = app.get(link, referer = extractorUrl)
val pageDoc = Jsoup.parse(page.text)
val qualityRegex = Regex("(\\d+)P")
//a[download]
pageDoc.select(".dowload > a")?.apmap { element ->
val href = element.attr("href") ?: return@apmap
val qual = if (element.text()
.contains("HDP")
) "1080" else qualityRegex.find(element.text())?.destructured?.component1()
.toString()
if (!loadExtractor(href, link, subtitleCallback, callback)) {
callback.invoke(
ExtractorLink(
this.name,
name = this.name,
href,
page.url,
getQualityFromName(qual),
element.attr("href").contains(".m3u8")
)
)
}
}
}, {
with(app.get(extractorUrl)) {
val document = Jsoup.parse(this.text)
val primaryLinks = document.select("ul.list-server-items > li.linkserver")
//val extractedLinksList: MutableList<ExtractorLink> = mutableListOf()
// All vidstream links passed to extractors
primaryLinks.distinctBy { it.attr("data-video") }.forEach { element ->
val link = element.attr("data-video")
//val name = element.text()
// Matches vidstream links with extractors
extractorApis.filter { !it.requiresReferer || !isCasting }.apmap { api ->
if (link.startsWith(api.mainUrl)) {
api.getSafeUrl(link, extractorUrl, subtitleCallback, callback)
}
}
}
}
}
)
return true
}
}

View File

@ -1,6 +1,7 @@
package com.lagradost
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.extractors.Vidstream
//import com.lagradost.cloudstream3.animeproviders.GogoanimeProvider.Companion.extractVidstream
//import com.lagradost.cloudstream3.extractors.Vidstream
import com.lagradost.cloudstream3.utils.ExtractorLink
@ -274,12 +275,12 @@ open class VidstreamProviderTemplate : MainAPI() {
// )
// 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)
val vidstreamObject = Vidstream(vidstreamExtractorUrl ?: mainUrl)
// https://vidembed.cc/streaming.php?id=MzUwNTY2&... -> MzUwNTY2
val id = Regex("""id=([^&]*)""").find(iframeLink)?.groupValues?.get(1)
if (id != null) {
// vidstreamObject.getUrl(id, isCasting, subtitleCallback, callback)
vidstreamObject.getUrl(id, isCasting, subtitleCallback, callback)
}
val html = app.get(fixUrl(iframeLink)).text

View File

@ -4,11 +4,13 @@ package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
import com.lagradost.cloudstream3.extractors.Vidstream
@CloudstreamPlugin
class VidstreamProviderTemplatePlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerExtractorAPI(MultiQuality())
registerMainAPI(VidstreamProviderTemplate())
}
}

View File

@ -1,3 +1,6 @@
dependencies {
implementation(project(mapOf("path" to ":VidstreamProviderTemplate")))
}
// use an integer for version numbers
version = 1

View File

@ -0,0 +1,32 @@
package com.lagradost
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
import com.lagradost.cloudstream3.utils.loadExtractor
class AsianEmbedHelper {
companion object {
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")
if (!links.isNullOrEmpty()) {
links.apmap {
val datavid = it.attr("data-video") ?: ""
//Log.i("AsianEmbed", "Result => (datavid) ${datavid}")
if (datavid.isNotBlank()) {
val res = loadExtractor(datavid, url, subtitleCallback, callback)
Log.i("AsianEmbed", "Result => ($res) (datavid) $datavid")
}
}
}
}
}
}

View File

@ -1,9 +1,10 @@
package com.lagradost
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.animeproviders.GogoanimeProvider.Companion.extractVidstream
import com.lagradost.cloudstream3.extractors.XStreamCdn
import com.lagradost.cloudstream3.extractors.helper.AsianEmbedHelper
import com.lagradost.cloudstream3.extractors.Vidstream
//import com.lagradost.cloudstream3.animeproviders.GogoanimeProvider.Companion.extractVidstream
//import com.lagradost.cloudstream3.extractors.XStreamCdn
//import com.lagradost.cloudstream3.extractors.helper.AsianEmbedHelper
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.AppUtils.toJson
import com.lagradost.cloudstream3.utils.ExtractorLink
@ -216,7 +217,7 @@ class WatchAsianProvider : MainAPI() {
url.startsWith("https://asianembed.io") || url.startsWith("https://asianload.io") -> {
val iv = "9262859232435825"
val secretKey = "93422192433952489752342908585752"
extractVidstream(
Vidstream.extractVidstream(
url, this.name, callback, iv, secretKey, secretKey,
isUsingAdaptiveKeys = false,
isUsingAdaptiveData = false

View File

@ -10,5 +10,12 @@ class WatchAsianProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(WatchAsianProvider())
registerExtractorAPI(XStreamCdn())
registerExtractorAPI(LayarKaca())
registerExtractorAPI(DBfilm())
registerExtractorAPI(Luxubu())
registerExtractorAPI(FEmbed())
registerExtractorAPI(Fplayer())
registerExtractorAPI(FeHD())
}
}

View File

@ -0,0 +1,93 @@
package com.lagradost
import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.utils.AppUtils
import com.lagradost.cloudstream3.utils.ExtractorApi
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.getQualityFromName
class LayarKaca: XStreamCdn() {
override val name: String = "LayarKaca-xxi"
override val mainUrl: String = "https://layarkacaxxi.icu"
}
class DBfilm: XStreamCdn() {
override val name: String = "DBfilm"
override val mainUrl: String = "https://dbfilm.bar"
}
class Luxubu : XStreamCdn(){
override val name: String = "FE"
override val mainUrl: String = "https://www.luxubu.review"
}
class FEmbed: XStreamCdn() {
override val name: String = "FEmbed"
override val mainUrl: String = "https://www.fembed.com"
}
class Fplayer: XStreamCdn() {
override val name: String = "Fplayer"
override val mainUrl: String = "https://fplayer.info"
}
class FeHD: XStreamCdn() {
override val name: String = "FeHD"
override val mainUrl: String = "https://fembed-hd.com"
override var domainUrl: String = "fembed-hd.com"
}
open class XStreamCdn : ExtractorApi() {
override val name: String = "XStreamCdn"
override val mainUrl: String = "https://embedsito.com"
override val requiresReferer = false
open var domainUrl: String = "embedsito.com"
private data class ResponseData(
@JsonProperty("file") val file: String,
@JsonProperty("label") val label: String,
//val type: String // Mp4
)
private data class ResponseJson(
@JsonProperty("success") val success: Boolean,
@JsonProperty("data") val data: List<ResponseData>?
)
override fun getExtractorUrl(id: String): String {
return "$domainUrl/api/source/$id"
}
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> {
val headers = mapOf(
"Referer" to url,
"User-Agent" to "Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0",
)
val id = url.trimEnd('/').split("/").last()
val newUrl = "https://${domainUrl}/api/source/${id}"
val extractedLinksList: MutableList<ExtractorLink> = mutableListOf()
with(app.post(newUrl, headers = headers)) {
if (this.code != 200) return listOf()
val text = this.text
if (text.isEmpty()) return listOf()
if (text == """{"success":false,"data":"Video not found or has been removed"}""") return listOf()
AppUtils.parseJson<ResponseJson?>(text)?.let {
if (it.success && it.data != null) {
it.data.forEach { data ->
extractedLinksList.add(
ExtractorLink(
name,
name = name,
data.file,
url,
getQualityFromName(data.label),
)
)
}
}
}
}
return extractedLinksList
}
}

View File

@ -80,6 +80,7 @@ subprojects {
implementation("com.github.Blatzar:NiceHttp:0.3.2") // http library
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.1")
implementation("org.jsoup:jsoup:1.13.1") // html parser
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4") // html parser
//run JS
implementation("org.mozilla:rhino:1.7.14")

View File

@ -12,13 +12,13 @@ include(
"AsiaFlixProvider",
"DoramasYTProvider",
// "SflixProProvider",
// "PinoyMoviePediaProvider",
"PinoyMoviePediaProvider",
"SeriesflixProvider",
"TrailersTwoProvider",
// "PinoyMoviesEsProvider",
"PinoyMoviesEsProvider",
"KisskhProvider",
// "DramaSeeProvider",
// "VidstreamProviderTemplate",
"DramaSeeProvider",
"VidstreamProviderTemplate",
"RebahinProvider",
"AllMoviesForYouProvider",
"UakinoProvider",
@ -26,41 +26,41 @@ include(
"FaselHDProvider",
"MeloMovieProvider",
"PelisplusProvider",
// "AsianLoadProvider",
"AsianLoadProvider",
"YomoviesProvider",
"AkwamProvider",
// "VidEmbedProvider",
"VidEmbedProvider",
"IdlixProvider",
"NginxProvider",
"SoaptwoDayProvider",
"PinoyHDXyzProvider",
"AltadefinizioneProvider",
"PelisflixProvider",
// "SflixProvider",
"SflixProvider",
"ElifilmsProvider",
// "VidSrcProvider",
"VidSrcProvider",
"EgyBestProvider",
// "WatchAsianProvider",
"WatchAsianProvider",
"VfSerieProvider",
"LayarKacaProvider",
"EntrepeliculasyseriesProvider",
"TantiFilmProvider",
// "TwoEmbedProvider",
"TwoEmbedProvider",
"SuperStream",
"FilmpertuttiProvider",
"FrenchStreamProvider",
// "KdramaHoodProvider",
"KdramaHoodProvider",
"MyCimaProvider",
"IlGenioDelloStreamingProvider",
"EstrenosDoramasProvider",
// "HDTodayProvider",
// "DopeboxProvider",
"DopeboxProvider",
"DubokuProvider",
"HDMProvider",
"PhimmoichillProvider",
"PelisplusProviderTemplate",
"OlgplyProvider",
// "SolarmovieProvider",
"SolarmovieProvider",
"PeliSmartProvider",
"VfFilmProvider",
"IHaveNoTvProvider",
@ -70,7 +70,7 @@ include(
"HDrezkaProvider",
"PelisplusHDProvider",
"MultiplexProvider",
// "OpenVidsProvider",
"OpenVidsProvider",
//"BflixProvider",
// "FmoviesToProvider",
"TheFlixToProvider",