mirror of
https://github.com/recloudstream/cloudstream.git
synced 2025-08-06 19:43:48 +08:00
Added Filegram and Fix Vidguard Extractor (#1370)
This commit is contained in:
@ -0,0 +1,63 @@
|
||||
package com.lagradost.cloudstream3.extractors
|
||||
|
||||
import com.lagradost.cloudstream3.SubtitleFile
|
||||
import com.lagradost.cloudstream3.USER_AGENT
|
||||
import com.lagradost.cloudstream3.app
|
||||
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
import com.lagradost.cloudstream3.utils.M3u8Helper
|
||||
import com.lagradost.cloudstream3.utils.fixUrl
|
||||
import com.lagradost.cloudstream3.utils.getAndUnpack
|
||||
import org.jsoup.nodes.Element
|
||||
|
||||
open class Filegram : ExtractorApi() {
|
||||
override val name = "Filegram"
|
||||
override val mainUrl = "https://filegram.to"
|
||||
override val requiresReferer = true
|
||||
|
||||
override suspend fun getUrl(
|
||||
url: String,
|
||||
referer: String?,
|
||||
subtitleCallback: (SubtitleFile) -> Unit,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
) {
|
||||
val header = mapOf(
|
||||
"Accept" to "*/*",
|
||||
"Accept-language" to "en-US,en;q=0.9",
|
||||
"Origin" to mainUrl,
|
||||
"Accept-Encoding" to "gzip, deflate, br, zstd",
|
||||
"Connection" to "keep-alive",
|
||||
"Sec-Fetch-Dest" to "empty",
|
||||
"Sec-Fetch-Mode" to "cors",
|
||||
"Sec-Fetch-Site" to "same-site",
|
||||
"user-agent" to USER_AGENT,
|
||||
)
|
||||
|
||||
val doc = app.get(getEmbedUrl(url), referer = referer).document
|
||||
val unpackedJs = unpackJs(doc).toString()
|
||||
val videoUrl = Regex("""file:\s*"([^"]+\.m3u8[^"]*)"""").find(unpackedJs)?.groupValues?.get(1)
|
||||
if (videoUrl != null) {
|
||||
M3u8Helper.generateM3u8(
|
||||
this.name,
|
||||
fixUrl(videoUrl),
|
||||
"$mainUrl/",
|
||||
headers = header
|
||||
).forEach(callback)
|
||||
}
|
||||
}
|
||||
|
||||
private fun unpackJs(script: Element): String? {
|
||||
return script.select("script").find { it.data().contains("eval(function(p,a,c,k,e,d)") }
|
||||
?.data()?.let { getAndUnpack(it) }
|
||||
}
|
||||
|
||||
private fun getEmbedUrl(url: String): String {
|
||||
return if (!url.contains("/embed-")) {
|
||||
val videoId = url.substringAfter("$mainUrl/")
|
||||
"$mainUrl/embed-$videoId"
|
||||
} else {
|
||||
url
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -12,7 +12,8 @@ import org.mozilla.javascript.Context
|
||||
import org.mozilla.javascript.NativeJSON
|
||||
import org.mozilla.javascript.NativeObject
|
||||
import org.mozilla.javascript.Scriptable
|
||||
import java.util.Base64
|
||||
import kotlin.io.encoding.Base64
|
||||
import kotlin.io.encoding.ExperimentalEncodingApi
|
||||
|
||||
class Vidguardto1 : Vidguardto() {
|
||||
override val mainUrl = "https://bembed.net"
|
||||
@ -37,8 +38,7 @@ open class Vidguardto : ExtractorApi() {
|
||||
subtitleCallback: (SubtitleFile) -> Unit,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
) {
|
||||
val embedUrl = url.replace("/d/", "/e/")
|
||||
val res = app.get(embedUrl)
|
||||
val res = app.get(getEmbedUrl(url))
|
||||
val resc = res.document.select("script:containsData(eval)").firstOrNull()?.data()
|
||||
resc?.let {
|
||||
val jsonStr2 = AppUtils.parseJson<SvgObject>(runJS2(it))
|
||||
@ -57,41 +57,43 @@ open class Vidguardto : ExtractorApi() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun sigDecode(url: String): String {
|
||||
@OptIn(ExperimentalEncodingApi::class)
|
||||
private fun sigDecode(url: String): String {
|
||||
val sig = url.split("sig=")[1].split("&")[0]
|
||||
var t = ""
|
||||
for (v in sig.chunked(2)) {
|
||||
val byteValue = Integer.parseInt(v, 16) xor 2
|
||||
t += byteValue.toChar()
|
||||
}
|
||||
val padding = when (t.length % 4) {
|
||||
2 -> "=="
|
||||
3 -> "="
|
||||
else -> ""
|
||||
}
|
||||
val decoded = Base64.getDecoder().decode((t + padding).toByteArray(Charsets.UTF_8))
|
||||
t = String(decoded).dropLast(5).reversed()
|
||||
val charArray = t.toCharArray()
|
||||
for (i in 0 until charArray.size - 1 step 2) {
|
||||
val temp = charArray[i]
|
||||
charArray[i] = charArray[i + 1]
|
||||
charArray[i + 1] = temp
|
||||
}
|
||||
val modifiedSig = String(charArray).dropLast(5)
|
||||
return url.replace(sig, modifiedSig)
|
||||
val t = sig.chunked(2)
|
||||
.joinToString("") { (Integer.parseInt(it, 16) xor 2).toChar().toString() }
|
||||
.let {
|
||||
val padding = when (it.length % 4) {
|
||||
2 -> "=="
|
||||
3 -> "="
|
||||
else -> ""
|
||||
}
|
||||
String(Base64.decode((it + padding).toByteArray(Charsets.UTF_8)))
|
||||
}
|
||||
.dropLast(5)
|
||||
.reversed()
|
||||
.toCharArray()
|
||||
.apply {
|
||||
for (i in indices step 2) {
|
||||
if (i + 1 < size) {
|
||||
this[i] = this[i + 1].also { this[i + 1] = this[i] }
|
||||
}
|
||||
}
|
||||
}
|
||||
.concatToString()
|
||||
.dropLast(5)
|
||||
return url.replace(sig, t)
|
||||
}
|
||||
|
||||
private fun runJS2(hideMyHtmlContent: String): String {
|
||||
var result = ""
|
||||
val r = Runnable {
|
||||
Log.d("runJS", "start")
|
||||
val rhino = Context.enter()
|
||||
rhino.initSafeStandardObjects()
|
||||
rhino.optimizationLevel = -1
|
||||
val scope: Scriptable = rhino.initSafeStandardObjects()
|
||||
scope.put("window", scope, scope)
|
||||
try {
|
||||
Log.d("runJS", "Executing JavaScript: $hideMyHtmlContent")
|
||||
rhino.evaluateString(
|
||||
scope,
|
||||
hideMyHtmlContent,
|
||||
@ -101,27 +103,37 @@ open class Vidguardto : ExtractorApi() {
|
||||
)
|
||||
val svgObject = scope.get("svg", scope)
|
||||
result = if (svgObject is NativeObject) {
|
||||
NativeJSON.stringify(Context.getCurrentContext(), scope, svgObject, null, null)
|
||||
.toString()
|
||||
NativeJSON.stringify(
|
||||
Context.getCurrentContext(),
|
||||
scope,
|
||||
svgObject,
|
||||
null,
|
||||
null
|
||||
).toString()
|
||||
} else {
|
||||
Context.toString(svgObject)
|
||||
}
|
||||
Log.d("runJS", "Result: $result")
|
||||
} catch (e: Exception) {
|
||||
Log.e("runJS", "Error executing JavaScript: ${e.message}")
|
||||
} finally {
|
||||
Context.exit()
|
||||
}
|
||||
}
|
||||
val t = Thread(ThreadGroup("A"), r, "thread_rhino", 2000000)// StackSize 2Mb: Run in a thread because rhino requires more stack size for large scripts.
|
||||
t.start();
|
||||
val t = Thread(ThreadGroup("A"), r, "thread_rhino", 8 * 1024 * 1024) // Increase stack size to 8MB
|
||||
t.start()
|
||||
t.join()
|
||||
t.interrupt()
|
||||
return result
|
||||
}
|
||||
|
||||
private fun getEmbedUrl(url: String): String {
|
||||
return url.takeIf { it.contains("/d/") }
|
||||
?.replace("/d/", "/e/") ?: url
|
||||
}
|
||||
|
||||
data class SvgObject(
|
||||
val stream: String,
|
||||
val hash: String
|
||||
)
|
||||
)
|
||||
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ import com.lagradost.cloudstream3.extractors.FileMoon
|
||||
import com.lagradost.cloudstream3.extractors.FileMoonIn
|
||||
import com.lagradost.cloudstream3.extractors.FileMoonSx
|
||||
import com.lagradost.cloudstream3.extractors.Filesim
|
||||
import com.lagradost.cloudstream3.extractors.Filegram
|
||||
import com.lagradost.cloudstream3.extractors.Fplayer
|
||||
import com.lagradost.cloudstream3.extractors.Geodailymotion
|
||||
import com.lagradost.cloudstream3.extractors.GMPlayer
|
||||
@ -1011,6 +1012,7 @@ val extractorApis: MutableList<ExtractorApi> = arrayListOf(
|
||||
Boosterx(),
|
||||
Ds2play(),
|
||||
Ds2video(),
|
||||
Filegram(),
|
||||
|
||||
)
|
||||
|
||||
|
Reference in New Issue
Block a user