From 34ecb1041e04aee7bc01b5232fd98f8e38ea4ff6 Mon Sep 17 00:00:00 2001 From: darkizone Date: Sun, 12 Apr 2026 20:26:15 +0100 Subject: [PATCH] Add Darkibox video extractor Add extractor for darkibox.com, an XFileSharing-based video hosting platform. Follows the same pattern as Hxfile. Extraction flow: - POSTs to embed endpoint to get player page - Unpacks Dean Edwards packed JavaScript via getAndUnpack() - Extracts video URLs from PlayerJS file: parameter - Supports HLS (m3u8), multi-quality [label]url, and direct MP4 Co-Authored-By: Claude Opus 4.6 (1M context) --- .../cloudstream3/extractors/Darkibox.kt | 80 +++++++++++++++++++ .../cloudstream3/utils/ExtractorApi.kt | 2 + 2 files changed, 82 insertions(+) create mode 100644 library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Darkibox.kt diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Darkibox.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Darkibox.kt new file mode 100644 index 0000000000..5ef8ebf6f3 --- /dev/null +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Darkibox.kt @@ -0,0 +1,80 @@ +package com.lagradost.cloudstream3.extractors + +import com.lagradost.cloudstream3.app +import com.lagradost.cloudstream3.utils.* + +open class Darkibox : ExtractorApi() { + override val name = "Darkibox" + override val mainUrl = "https://darkibox.com" + override val requiresReferer = false + + override suspend fun getUrl(url: String, referer: String?): List? { + val sources = mutableListOf() + + // Extract file code from embed URL + // URL format: https://darkibox.com/embed-FILECODE.html + val fileCode = Regex("""embed-(.+?)\.html""").find(url)?.groupValues?.get(1) + ?: url.substringAfterLast("/").substringBefore(".") + + // POST to /dl endpoint with form data + val response = app.post( + "$mainUrl/dl", + data = mapOf( + "op" to "embed", + "file_code" to fileCode, + "auto" to "1" + ), + referer = url + ).document + + response.select("script").forEach { script -> + if (script.data().contains("eval(function(p,a,c,k,e,d)")) { + val unpacked = getAndUnpack(script.data()) + + // Look for file parameter in PlayerJS format + // Can be: file:"URL" or file:"[label]url,[label]url" + val fileContent = Regex("""file\s*:\s*"([^"]+)"""").find(unpacked) + ?.groupValues?.get(1) ?: return@forEach + + if (fileContent.contains("[") && fileContent.contains("]")) { + // Multi-quality format: [label]url,[label]url + Regex("""\[([^\]]*)]([^,\s]+)""").findAll(fileContent).forEach { match -> + val label = match.groupValues[1] + val videoUrl = match.groupValues[2] + sources.add( + newExtractorLink( + name, + name, + videoUrl, + ) { + this.referer = mainUrl + this.quality = getQualityFromName(label) + } + ) + } + } else if (fileContent.contains(".m3u8")) { + // HLS m3u8 URL + val m3u8Links = M3u8Helper.generateM3u8( + name, + fileContent, + "$mainUrl/", + ) + sources.addAll(m3u8Links) + } else { + // Direct video URL + sources.add( + newExtractorLink( + name, + name, + fileContent, + ) { + this.referer = mainUrl + } + ) + } + } + } + + return sources + } +} 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 4f3f05df6e..2e0508e2c0 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/ExtractorApi.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/ExtractorApi.kt @@ -32,6 +32,7 @@ import com.lagradost.cloudstream3.extractors.D0000d import com.lagradost.cloudstream3.extractors.D000dCom import com.lagradost.cloudstream3.extractors.DBfilm import com.lagradost.cloudstream3.extractors.Dailymotion +import com.lagradost.cloudstream3.extractors.Darkibox import com.lagradost.cloudstream3.extractors.DatabaseGdrive import com.lagradost.cloudstream3.extractors.DatabaseGdrive2 import com.lagradost.cloudstream3.extractors.DesuArcg @@ -1131,6 +1132,7 @@ val extractorApis: MutableList = arrayListOf( Cda(), Dailymotion(), + Darkibox(), Ztreamhub(), Rabbitstream(), Dokicloud(),