added extractors (#86)

This commit is contained in:
Hexated 2022-09-05 06:13:17 +07:00 committed by GitHub
parent abc9421fb1
commit ae137f4a34
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 195 additions and 20 deletions

View file

@ -0,0 +1,37 @@
package com.lagradost.cloudstream3.extractors
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.httpsify
class Embedgram : ExtractorApi() {
override val name = "Embedgram"
override val mainUrl = "https://embedgram.com"
override val requiresReferer = true
override suspend fun getUrl(
url: String,
referer: String?,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
) {
val document = app.get(url, referer = referer).document
val link = document.select("video source:last-child").attr("src")
val quality = document.select("video source:last-child").attr("title")
callback.invoke(
ExtractorLink(
this.name,
this.name,
httpsify(link),
"$mainUrl/",
getQualityFromName(quality),
headers = mapOf(
"Range" to "bytes=0-"
)
)
)
}
}

View file

@ -0,0 +1,47 @@
package com.lagradost.cloudstream3.extractors
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.Qualities
class Mvidoo : ExtractorApi() {
override val name = "Mvidoo"
override val mainUrl = "https://mvidoo.com"
override val requiresReferer = true
private fun String.decodeHex(): String {
require(length % 2 == 0) { "Must have an even length" }
return String(
chunked(2)
.map { it.toInt(16).toByte() }
.toByteArray()
)
}
override suspend fun getUrl(
url: String,
referer: String?,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
) {
val document = app.get(url, referer = referer).text
val data = Regex("""\{var\s*[^\s]+\s*=\s*(\[[^]]+])""").find(document)?.groupValues?.get(1)
?.removeSurrounding("[", "]")?.replace("\"", "")?.replace("\\x", "")?.split(",")?.map { it.decodeHex() }?.reversed()?.joinToString("") ?: return
Regex("source\\s*src=\"([^\"]+)").find(data)?.groupValues?.get(1)?.let { link ->
callback.invoke(
ExtractorLink(
this.name,
this.name,
link,
"$mainUrl/",
Qualities.Unknown.value,
headers = mapOf(
"Range" to "bytes=0-"
)
)
)
}
}
}

View file

@ -0,0 +1,81 @@
package com.lagradost.cloudstream3.extractors
import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.APIHolder.getCaptchaToken
import com.lagradost.cloudstream3.ErrorLoadingException
import com.lagradost.cloudstream3.SubtitleFile
import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.utils.*
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
import java.net.URI
class Streamplay : ExtractorApi() {
override val name = "Streamplay"
override val mainUrl = "https://streamplay.to"
override val requiresReferer = true
override suspend fun getUrl(
url: String,
referer: String?,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
) {
val request = app.get(url, referer = referer)
val redirectUrl = request.url
val mainServer = URI(redirectUrl).let {
"${it.scheme}://${it.host}"
}
val key = redirectUrl.substringAfter("embed-").substringBefore(".html")
val token =
request.document.select("script").find { it.data().contains("sitekey:") }?.data()
?.substringAfterLast("sitekey: '")?.substringBefore("',")?.let { captchaKey ->
getCaptchaToken(
redirectUrl,
captchaKey,
referer = "$mainServer/"
)
} ?: throw ErrorLoadingException("can't bypass captcha")
app.post(
"$mainServer/player-$key-488x286.html", data = mapOf(
"op" to "embed",
"token" to token
),
referer = redirectUrl,
headers = mapOf(
"Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Content-Type" to "application/x-www-form-urlencoded"
)
).document.select("script").find { script ->
script.data().contains("eval(function(p,a,c,k,e,d)")
}?.let {
val data = getAndUnpack(it.data()).substringAfter("sources=[").substringBefore(",desc")
.replace("file", "\"file\"")
.replace("label", "\"label\"")
tryParseJson<List<Source>>("[$data}]")?.map { res ->
callback.invoke(
ExtractorLink(
this.name,
this.name,
res.file ?: return@map null,
"$mainServer/",
when (res.label) {
"HD" -> Qualities.P720.value
"SD" -> Qualities.P480.value
else -> Qualities.Unknown.value
},
headers = mapOf(
"Range" to "bytes=0-"
)
)
)
}
}
}
data class Source(
@JsonProperty("file") val file: String? = null,
@JsonProperty("label") val label: String? = null,
)
}

View file

@ -1,19 +1,23 @@
package com.lagradost.cloudstream3.extractors package com.lagradost.cloudstream3.extractors
import com.lagradost.cloudstream3.SubtitleFile
import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.utils.ExtractorApi import com.lagradost.cloudstream3.utils.ExtractorApi
import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.Qualities import com.lagradost.cloudstream3.utils.M3u8Helper
class UpstreamExtractor: ExtractorApi() { class UpstreamExtractor : ExtractorApi() {
override val name: String = "Upstream.to" override val name: String = "Upstream"
override val mainUrl: String = "https://upstream.to" override val mainUrl: String = "https://upstream.to"
override val requiresReferer = true override val requiresReferer = true
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> { override suspend fun getUrl(
// WIP: m3u8 link fetched but sometimes not playing url: String,
referer: String?,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
) {
//Log.i(this.name, "Result => (no extractor) ${url}") //Log.i(this.name, "Result => (no extractor) ${url}")
val sources: MutableList<ExtractorLink> = mutableListOf()
val doc = app.get(url, referer = referer).text val doc = app.get(url, referer = referer).text
if (doc.isNotBlank()) { if (doc.isNotBlank()) {
var reg = Regex("(?<=master)(.*)(?=hls)") var reg = Regex("(?<=master)(.*)(?=hls)")
@ -30,7 +34,9 @@ class UpstreamExtractor: ExtractorApi() {
domName = "${part}.${domName}" domName = "${part}.${domName}"
} }
domName.trimEnd('.') domName.trimEnd('.')
} else { "" } } else {
""
}
} }
false -> "" false -> ""
} }
@ -42,18 +48,13 @@ class UpstreamExtractor: ExtractorApi() {
result?.forEach { result?.forEach {
val linkUrl = "https://${domain}/hls/${it}/master.m3u8" val linkUrl = "https://${domain}/hls/${it}/master.m3u8"
sources.add( M3u8Helper.generateM3u8(
ExtractorLink( this.name,
name = "Upstream m3u8", linkUrl,
source = this.name, "$mainUrl/",
url = linkUrl, headers = mapOf("Origin" to mainUrl)
quality = Qualities.Unknown.value, ).forEach(callback)
referer = referer ?: linkUrl,
isM3u8 = true
)
)
} }
} }
return sources
} }
} }

View file

@ -7,6 +7,11 @@ import com.lagradost.cloudstream3.utils.ExtractorApi
import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.getQualityFromName import com.lagradost.cloudstream3.utils.getQualityFromName
class FEnet: XStreamCdn() {
override val name: String = "FEnet"
override val mainUrl: String = "https://fembed.net"
}
class Rasacintaku: XStreamCdn() { class Rasacintaku: XStreamCdn() {
override val mainUrl: String = "https://rasa-cintaku-semakin-berantai.xyz" override val mainUrl: String = "https://rasa-cintaku-semakin-berantai.xyz"
} }

View file

@ -246,13 +246,14 @@ val extractorApis: MutableList<ExtractorApi> = arrayListOf(
Luxubu(), Luxubu(),
LayarKaca(), LayarKaca(),
Rasacintaku(), Rasacintaku(),
FEnet(),
// WatchSB(), 'cause StreamSB.kt works // WatchSB(), 'cause StreamSB.kt works
Uqload(), Uqload(),
Uqload1(), Uqload1(),
Evoload(), Evoload(),
Evoload1(), Evoload1(),
VoeExtractor(), VoeExtractor(),
// UpstreamExtractor(), GenericM3U8.kt works UpstreamExtractor(),
Tomatomatela(), Tomatomatela(),
Cinestart(), Cinestart(),
@ -316,6 +317,9 @@ val extractorApis: MutableList<ExtractorApi> = arrayListOf(
Acefile(), Acefile(),
SpeedoStream(), SpeedoStream(),
Zorofile(), Zorofile(),
Embedgram(),
Mvidoo(),
Streamplay(),
YoutubeExtractor(), YoutubeExtractor(),
YoutubeShortLinkExtractor(), YoutubeShortLinkExtractor(),