From c3bf08899a5fe915ebca3c4233f4f75ca7208019 Mon Sep 17 00:00:00 2001 From: Phisher98 Date: Sat, 20 Dec 2025 14:51:09 +0530 Subject: [PATCH 1/3] Improving Extractors and also Improved getQualityFromName() --- .../cloudstream3/extractors/BuzzServer.kt | 45 +++++++++++++++++++ .../cloudstream3/extractors/Krakenfiles.kt | 29 ++++++++---- .../cloudstream3/utils/ExtractorApi.kt | 29 ++++++++---- 3 files changed, 86 insertions(+), 17 deletions(-) create mode 100644 library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/BuzzServer.kt diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/BuzzServer.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/BuzzServer.kt new file mode 100644 index 00000000000..880d6329a97 --- /dev/null +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/BuzzServer.kt @@ -0,0 +1,45 @@ +package com.lagradost.cloudstream3.extractors + +import com.lagradost.api.Log +import com.lagradost.cloudstream3.SubtitleFile +import com.lagradost.cloudstream3.app +import com.lagradost.cloudstream3.utils.ExtractorApi +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.getQualityFromName +import com.lagradost.cloudstream3.utils.newExtractorLink + +class BuzzServer : ExtractorApi() { + override val name = "BuzzServer" + override val mainUrl = "https://buzzheavier.com" + override val requiresReferer = true + + override suspend fun getUrl( + url: String, + referer: String?, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ) { + try { + val qualityText = app.get(url).documentLarge.selectFirst("div.max-w-2xl > span")?.text() + val quality = getQualityFromName(qualityText) + val response = app.get("$url/download", referer = url, allowRedirects = false) + val redirectUrl = response.headers["hx-redirect"] ?: "" + + if (redirectUrl.isNotEmpty()) { + callback.invoke( + newExtractorLink( + "BuzzServer", + "BuzzServer", + redirectUrl, + ) { + this.quality = quality + } + ) + } else { + Log.w("BuzzServer", "No redirect URL found in headers.") + } + } catch (e: Exception) { + Log.e("BuzzServer", "Exception occurred: ${e.message}") + } + } +} \ No newline at end of file diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Krakenfiles.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Krakenfiles.kt index b605a39c6b4..ea59825f91f 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Krakenfiles.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Krakenfiles.kt @@ -5,6 +5,7 @@ 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 com.lagradost.cloudstream3.utils.httpsify import com.lagradost.cloudstream3.utils.newExtractorLink @@ -19,18 +20,28 @@ open class Krakenfiles : ExtractorApi() { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ) { - val id = Regex("/(?:view|embed-video)/([\\da-zA-Z]+)").find(url)?.groupValues?.get(1) + val id = Regex("/(?:view|embed-video)/([\\da-zA-Z]+)") + .find(url) + ?.groupValues + ?.get(1) + ?: return + val doc = app.get("$mainUrl/embed-video/$id").document - val link = doc.selectFirst("source")?.attr("src") + val title = doc.select("span.coin-name").text() + val link = doc.selectFirst("source")?.attr("src") ?: return + val quality = getQualityFromName(title) + - callback.invoke( + callback( newExtractorLink( - this.name, - this.name, - httpsify(link ?: return), - ) + name, + name, + httpsify(link) + ) { + this.quality = quality + } ) - } -} \ No newline at end of file +} + diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/ExtractorApi.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/ExtractorApi.kt index 641c913195e..f3ddb6694b1 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/ExtractorApi.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/ExtractorApi.kt @@ -18,6 +18,7 @@ import com.lagradost.cloudstream3.extractors.BigwarpArt import com.lagradost.cloudstream3.extractors.BigwarpIO import com.lagradost.cloudstream3.extractors.Blogger import com.lagradost.cloudstream3.extractors.BullStream +import com.lagradost.cloudstream3.extractors.BuzzServer import com.lagradost.cloudstream3.extractors.ByseSX import com.lagradost.cloudstream3.extractors.Bysezejataos import com.lagradost.cloudstream3.extractors.ByteShare @@ -791,15 +792,26 @@ enum class Qualities(var value: Int, val defaultPriority: Int) { } } +private val QUALITY_REGEX_MAP = listOf( + Regex("""\b(4k|2160p?|2160)\b""", RegexOption.IGNORE_CASE) to Qualities.P2160.value, + Regex("""\b1440p?|1440\b""", RegexOption.IGNORE_CASE) to Qualities.P1440.value, + Regex("""\b1080p?|1080\b""", RegexOption.IGNORE_CASE) to Qualities.P1080.value, + Regex("""\b720p?|720\b""", RegexOption.IGNORE_CASE) to Qualities.P720.value, + Regex("""\b480p?|480\b""", RegexOption.IGNORE_CASE) to Qualities.P480.value +) +private var lastResolvedQuality: Int = Qualities.Unknown.value + fun getQualityFromName(qualityName: String?): Int { - if (qualityName == null) - return Qualities.Unknown.value - - val match = qualityName.lowercase().replace("p", "").trim() - return when (match) { - "4k" -> Qualities.P2160 - else -> null - }?.value ?: match.toIntOrNull() ?: Qualities.Unknown.value + if (qualityName.isNullOrBlank()) + return lastResolvedQuality + + for ((regex, quality) in QUALITY_REGEX_MAP) { + if (regex.containsMatchIn(qualityName)) { + lastResolvedQuality = maxOf(lastResolvedQuality, quality) + return lastResolvedQuality + } + } + return lastResolvedQuality } private val packedRegex = Regex("""eval\(function\(p,a,c,k,e,.*\)\)""") @@ -1077,6 +1089,7 @@ val extractorApis: MutableList = arrayListOf( Fembed9hd(), StreamM4u(), Krakenfiles(), + BuzzServer(), Gofile(), Vicloud(), Uservideo(), From ff1c195e32bd7ee310c8ba5ccda95bf669dcd0dd Mon Sep 17 00:00:00 2001 From: Phisher98 Date: Sat, 20 Dec 2025 14:55:21 +0530 Subject: [PATCH 2/3] Improving Extractors and also Improved getQualityFromName() --- .../kotlin/com/lagradost/cloudstream3/extractors/BuzzServer.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/BuzzServer.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/BuzzServer.kt index 880d6329a97..9e0eb7f6098 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/BuzzServer.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/BuzzServer.kt @@ -1,6 +1,7 @@ package com.lagradost.cloudstream3.extractors import com.lagradost.api.Log +import com.lagradost.cloudstream3.Prerelease import com.lagradost.cloudstream3.SubtitleFile import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.utils.ExtractorApi @@ -8,6 +9,7 @@ import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.getQualityFromName import com.lagradost.cloudstream3.utils.newExtractorLink +@Prerelease class BuzzServer : ExtractorApi() { override val name = "BuzzServer" override val mainUrl = "https://buzzheavier.com" From a59a91c1b021c71d6f3e6ea0fdcd4c6816ec6d37 Mon Sep 17 00:00:00 2001 From: Phisher98 Date: Sun, 21 Dec 2025 11:29:49 +0530 Subject: [PATCH 3/3] Improving Extractors and also Improved getQualityFromName() --- .../cloudstream3/extractors/Krakenfiles.kt | 3 +-- .../cloudstream3/utils/ExtractorApi.kt | 26 ++++++------------- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Krakenfiles.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Krakenfiles.kt index ea59825f91f..53eb92259dc 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Krakenfiles.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Krakenfiles.kt @@ -31,8 +31,7 @@ open class Krakenfiles : ExtractorApi() { val link = doc.selectFirst("source")?.attr("src") ?: return val quality = getQualityFromName(title) - - callback( + callback.invoke( newExtractorLink( name, name, diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/ExtractorApi.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/ExtractorApi.kt index f3ddb6694b1..ec74e1a918c 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/ExtractorApi.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/ExtractorApi.kt @@ -792,26 +792,16 @@ enum class Qualities(var value: Int, val defaultPriority: Int) { } } -private val QUALITY_REGEX_MAP = listOf( - Regex("""\b(4k|2160p?|2160)\b""", RegexOption.IGNORE_CASE) to Qualities.P2160.value, - Regex("""\b1440p?|1440\b""", RegexOption.IGNORE_CASE) to Qualities.P1440.value, - Regex("""\b1080p?|1080\b""", RegexOption.IGNORE_CASE) to Qualities.P1080.value, - Regex("""\b720p?|720\b""", RegexOption.IGNORE_CASE) to Qualities.P720.value, - Regex("""\b480p?|480\b""", RegexOption.IGNORE_CASE) to Qualities.P480.value -) -private var lastResolvedQuality: Int = Qualities.Unknown.value - fun getQualityFromName(qualityName: String?): Int { - if (qualityName.isNullOrBlank()) - return lastResolvedQuality - - for ((regex, quality) in QUALITY_REGEX_MAP) { - if (regex.containsMatchIn(qualityName)) { - lastResolvedQuality = maxOf(lastResolvedQuality, quality) - return lastResolvedQuality - } + return when (qualityName?.lowercase()) { + "4k", "2160", "2160p" -> Qualities.P2160.value + "1440", "1440p" -> Qualities.P1440.value + "1080", "1080p" -> Qualities.P1080.value + "720", "720p" -> Qualities.P720.value + "480", "480p" -> Qualities.P480.value + "360", "360p" -> Qualities.P360.value + else -> Qualities.Unknown.value } - return lastResolvedQuality } private val packedRegex = Regex("""eval\(function\(p,a,c,k,e,.*\)\)""")