From 46646744339cd2e4c019e030038129b64e5a6459 Mon Sep 17 00:00:00 2001 From: Sofie99 Date: Mon, 4 Dec 2023 14:31:26 +0700 Subject: [PATCH] extractor: added Vidplay --- .../cloudstream3/extractors/Vidplay.kt | 92 +++++++++++++++++++ .../cloudstream3/utils/ExtractorApi.kt | 2 + 2 files changed, 94 insertions(+) create mode 100644 app/src/main/java/com/lagradost/cloudstream3/extractors/Vidplay.kt diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/Vidplay.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/Vidplay.kt new file mode 100644 index 00000000..7775b5cf --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/Vidplay.kt @@ -0,0 +1,92 @@ +package com.lagradost.cloudstream3.extractors + +import com.fasterxml.jackson.annotation.JsonProperty +import com.lagradost.cloudstream3.SubtitleFile +import com.lagradost.cloudstream3.app +import com.lagradost.cloudstream3.base64Encode +import com.lagradost.cloudstream3.utils.ExtractorApi +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.M3u8Helper +import javax.crypto.Cipher +import javax.crypto.spec.SecretKeySpec + +// Code found in https://github.com/Claudemirovsky/worstsource-keys +// special credits to @Claudemirovsky for providing key +open class Vidplay : ExtractorApi() { + override val name = "Vidplay" + override val mainUrl = "https://vidplay.site" + override val requiresReferer = true + + override suspend fun getUrl( + url: String, + referer: String?, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ) { + val id = url.substringAfter("/e/").substringBefore("?") + val encodeId = encodeId(id, getKeys()) + val mediaUrl = callFutoken(encodeId, url) + val res = app.get( + "$mediaUrl", headers = mapOf( + "Accept" to "application/json, text/javascript, */*; q=0.01", + "X-Requested-With" to "XMLHttpRequest", + ), referer = url + ).parsedSafe()?.result?.sources + + res?.map { + M3u8Helper.generateM3u8( + this.name, + it.file ?: return@map, + "$mainUrl/" + ).forEach(callback) + } + + } + + private suspend fun getKeys(): List { + return app.get("https://raw.githubusercontent.com/Claudemirovsky/worstsource-keys/keys/keys.json") + .parsed() + } + + private suspend fun callFutoken(id: String, url: String): String? { + val script = app.get("$mainUrl/futoken").text + val k = "k='(\\S+)'".toRegex().find(script)?.groupValues?.get(1) ?: return null + val a = mutableListOf(k) + for (i in id.indices) { + a.add((k[i % k.length].code + id[i].code).toString()) + } + return "$mainUrl/mediainfo/${a.joinToString(",")}?${url.substringAfter("?")}" + } + + private fun encodeId(id: String, keyList: List): String { + val cipher1 = Cipher.getInstance("RC4") + val cipher2 = Cipher.getInstance("RC4") + cipher1.init( + Cipher.DECRYPT_MODE, + SecretKeySpec(keyList[0].toByteArray(), "RC4"), + cipher1.parameters + ) + cipher2.init( + Cipher.DECRYPT_MODE, + SecretKeySpec(keyList[1].toByteArray(), "RC4"), + cipher2.parameters + ) + var input = id.toByteArray() + input = cipher1.doFinal(input) + input = cipher2.doFinal(input) + return base64Encode(input).replace("/", "_") + } + + data class Sources( + @JsonProperty("file") val file: String? = null, + ) + + data class Result( + @JsonProperty("sources") val sources: ArrayList? = arrayListOf(), + ) + + data class Response( + @JsonProperty("result") val result: Result? = null, + ) + +} \ No newline at end of file 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 923c3531..2e9dd691 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt @@ -167,6 +167,7 @@ import com.lagradost.cloudstream3.extractors.Vidgomunimesb import com.lagradost.cloudstream3.extractors.Vidmoly import com.lagradost.cloudstream3.extractors.Vidmolyme import com.lagradost.cloudstream3.extractors.Vido +import com.lagradost.cloudstream3.extractors.Vidplay import com.lagradost.cloudstream3.extractors.Vidstreamz import com.lagradost.cloudstream3.extractors.Vizcloud import com.lagradost.cloudstream3.extractors.Vizcloud2 @@ -793,6 +794,7 @@ val extractorApis: MutableList = arrayListOf( VidSrcExtractor2(), PlayLtXyz(), AStreamHub(), + Vidplay(), Cda(), Dailymotion(),