Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.android.lint) apply false
alias(libs.plugins.android.multiplatform.library) apply false
alias(libs.plugins.buildkonfig) apply false // Universal build config
alias(libs.plugins.dokka) apply false
Expand Down
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ work-runtime-ktx = { module = "androidx.work:work-runtime-ktx", version.ref = "w

[plugins]
android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }
android-lint = { id = "com.android.lint", version.ref = "androidGradlePlugin" }
android-multiplatform-library = { id = "com.android.kotlin.multiplatform.library", version.ref = "androidGradlePlugin" }
buildkonfig = { id = "com.codingfeline.buildkonfig", version.ref = "buildkonfigGradlePlugin" }
dokka = { id = "org.jetbrains.dokka", version.ref = "dokkaGradlePlugin" }
Expand Down
1 change: 1 addition & 0 deletions library/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile

plugins {
id("maven-publish") // Gradle core plugin
alias(libs.plugins.android.lint)
alias(libs.plugins.kotlin.multiplatform)
alias(libs.plugins.android.multiplatform.library)
alias(libs.plugins.buildkonfig)
Expand Down
6 changes: 6 additions & 0 deletions library/lint.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<lint>
<issue id="TrulyRandom">
<ignore path="**/CryptoJS.class" />
</issue>
</lint>
Original file line number Diff line number Diff line change
Expand Up @@ -2502,7 +2502,7 @@ constructor(

fun Episode.addDate(date: String?, format: String = "yyyy-MM-dd") {
try {
this.date = SimpleDateFormat(format).parse(date ?: return)?.time
this.date = SimpleDateFormat(format, Locale.getDefault()).parse(date ?: return)?.time
} catch (e: Exception) {
logError(e)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ open class ContentX : ExtractorApi() {
val iSource = app.get(url, referer=extRef).text
val iExtract = Regex("""window\.openPlayer\('([^']+)'""").find(iSource)!!.groups[1]?.value ?: throw ErrorLoadingException("iExtract is null")

val subUrls = mutableSetOf<String>()
val subUrls = mutableSetOf<String>()
Regex("""\"file\":\"([^\"]+)\",\"label\":\"([^\"]+)\"""").findAll(iSource).forEach {
val (subUrl, subLang) = it.destructured

if (subUrl in subUrls) { return@forEach }
subUrls.add(subUrl)
if (subUrl in subUrls) { return@forEach }
subUrls.add(subUrl)

subtitleCallback.invoke(
newSubtitleFile(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ open class DoodLaExtractor : ExtractorApi() {
override var name = "DoodStream"
override var mainUrl = "https://dood.la"
override val requiresReferer = false

private val alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"

override suspend fun getUrl(
Expand All @@ -87,18 +87,17 @@ open class DoodLaExtractor : ExtractorApi() {
callback: (ExtractorLink) -> Unit
) {
val embedUrl = url.replace("/d/", "/e/")
val req = app.get(embedUrl)
val req = app.get(embedUrl)
val host = getBaseUrl(req.url)
val response0 = req.text
val md5 = host + (Regex("/pass_md5/[^']*").find(response0)?.value ?: return)
val md5 = host + (Regex("/pass_md5/[^']*").find(response0)?.value ?: return)
val trueUrl = app.get(md5, referer = req.url).text + createHashTable() + "?token=" + md5.substringAfterLast("/")

val quality = Regex("\\d{3,4}p")
val quality = Regex("\\d{3,4}p")
.find(response0.substringAfter("<title>").substringBefore("</title>"))
?.groupValues
?.getOrNull(0)
callback.invoke(

callback.invoke(
newExtractorLink(
this.name,
this.name,
Expand All @@ -108,19 +107,17 @@ open class DoodLaExtractor : ExtractorApi() {
this.quality = getQualityFromName(quality)
}
)

}

private fun createHashTable(): String {
return buildString {
repeat(10) {
append(alphabet.random())

private fun createHashTable(): String {
return buildString {
repeat(10) {
append(alphabet.random())
}
}
}
}


private fun getBaseUrl(url: String): String {
private fun getBaseUrl(url: String): String {
return URI(url).let {
"${it.scheme}://${it.host}"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,32 +32,29 @@ open class Filegram : ExtractorApi() {
"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)
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)
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
}
}
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
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ open class RapidVid : ExtractorApi() {
val extRef = referer ?: ""
val videoReq = app.get(url, referer=extRef).text

val subUrls = mutableSetOf<String>()
val subUrls = mutableSetOf<String>()
Regex("""captions\",\"file\":\"([^\"]+)\",\"label\":\"([^\"]+)\"""").findAll(videoReq).forEach {
val (subUrl, subLang) = it.destructured

if (subUrl in subUrls) { return@forEach }
subUrls.add(subUrl)
if (subUrl in subUrls) { return@forEach }
subUrls.add(subUrl)

subtitleCallback.invoke(
newSubtitleFile(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,29 +29,28 @@ open class TRsTX : ExtractorApi() {
)
}

val vidLinks = mutableSetOf<String>()
val vidLinks = mutableSetOf<String>()
val vidMap = mutableListOf<Map<String, String>>()
for (item in postJson) {
if (item.file == null || item.title == null) continue

val fileUrl = "${mainUrl}/playlist/" + item.file.substring(1) + ".txt"
val videoData = app.post(fileUrl, referer=extRef).text

if (videoData in vidLinks) { continue }
vidLinks.add(videoData)
if (videoData in vidLinks) { continue }
vidLinks.add(videoData)

vidMap.add(mapOf(
"title" to item.title,
"videoData" to videoData
))
}


for (mapEntry in vidMap) {
val title = mapEntry["title"] ?: continue
val m3uLink = mapEntry["videoData"] ?: continue

callback.invoke(
callback.invoke(
newExtractorLink(
source = this.name,
name = "${this.name} - ${title}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ open class VidMoxy : ExtractorApi() {
val extRef = referer ?: ""
val videoReq = app.get(url, referer=extRef).text

val subUrls = mutableSetOf<String>()
val subUrls = mutableSetOf<String>()
Regex("""captions\",\"file\":\"([^\"]+)\",\"label\":\"([^\"]+)\"""").findAll(videoReq).forEach {
val (subUrl, subLang) = it.destructured

if (subUrl in subUrls) { return@forEach }
subUrls.add(subUrl)
if (subUrl in subUrls) { return@forEach }
subUrls.add(subUrl)

subtitleCallback.invoke(
newSubtitleFile(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,20 @@ open class Vtbe : ExtractorApi() {
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
val response = app.get(url,referer=mainUrl).document
val extractedpack =response.selectFirst("script:containsData(function(p,a,c,k,e,d))")?.data().toString()
JsUnpacker(extractedpack).unpack()?.let { unPacked ->
Regex("sources:\\[\\{file:\"(.*?)\"").find(unPacked)?.groupValues?.get(1)?.let { link ->
return listOf(
newExtractorLink(
this.name,
this.name,
link,
) {
this.referer = referer ?: ""
this.quality = Qualities.Unknown.value
}
)
}
JsUnpacker(extractedpack).unpack()?.let { unPacked ->
Regex("sources:\\[\\{file:\"(.*?)\"").find(unPacked)?.groupValues?.get(1)?.let { link ->
return listOf(
newExtractorLink(
this.name,
this.name,
link,
) {
this.referer = referer ?: ""
this.quality = Qualities.Unknown.value
}
)
}
return null
}
return null
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package com.lagradost.cloudstream3.extractors.helper

import com.lagradost.cloudstream3.base64DecodeArray
import com.lagradost.cloudstream3.base64Encode
import java.util.Arrays
import java.util.Base64
import java.security.MessageDigest
import java.security.SecureRandom
import javax.crypto.Cipher
Expand Down Expand Up @@ -51,8 +52,7 @@ object CryptoJS {
System.arraycopy(saltBytes, 0, b, sBytes.size, saltBytes.size)
System.arraycopy(cipherText, 0, b, sBytes.size + saltBytes.size, cipherText.size)

val bEncode = Base64.getEncoder().encode(b)
return String(bEncode)
return base64Encode(b)
}

/**
Expand All @@ -62,7 +62,7 @@ object CryptoJS {
* @param cipherText encrypted string
*/
fun decrypt(password: String, cipherText: String): String {
val ctBytes = Base64.getDecoder().decode(cipherText.toByteArray())
val ctBytes = base64DecodeArray(cipherText)
val saltBytes = Arrays.copyOfRange(ctBytes, 8, 16)
val cipherTextBytes = Arrays.copyOfRange(ctBytes, 16, ctBytes.size)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ object HlsPlaylistParser {
if (codecs.isNullOrEmpty()) {
return arrayOf()
}
return split(codecs.trim { it <= ' ' }, "(\\s*,\\s*)")
return split(codecs.trim(), "(\\s*,\\s*)")
}

fun getCodecsOfType(
Expand Down Expand Up @@ -928,7 +928,7 @@ object HlsPlaylistParser {

fun getMediaMimeType(codecOrNull: String?): String? {
var codec = codecOrNull ?: return null
codec = codec.trim { it <= ' ' }.lowercase()
codec = codec.trim().lowercase()
if (codec.startsWith("avc1") || codec.startsWith("avc3")) {
return MimeTypes.VIDEO_H264
} else if (codec.startsWith("hev1") || codec.startsWith("hvc1")) {
Expand Down