added sub to streamsb & xtreamCdn (#163)

This commit is contained in:
Hexated 2022-10-26 22:38:46 +07:00 committed by GitHub
parent 7cbcee4d48
commit ecd363992c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 159 additions and 40 deletions

View file

@ -3,6 +3,7 @@ package com.lagradost.cloudstream3.extractors
import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.*
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.security.DigestException import java.security.DigestException
import java.security.MessageDigest import java.security.MessageDigest
@ -10,43 +11,47 @@ import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec import javax.crypto.spec.SecretKeySpec
class DatabaseGdrive2 : Gdriveplayer() {
override var mainUrl = "https://databasegdriveplayer.co"
}
class DatabaseGdrive : Gdriveplayer() { class DatabaseGdrive : Gdriveplayer() {
override var mainUrl = "https://series.databasegdriveplayer.co" override var mainUrl = "https://series.databasegdriveplayer.co"
} }
class Gdriveplayerapi: Gdriveplayer() { class Gdriveplayerapi : Gdriveplayer() {
override val mainUrl: String = "https://gdriveplayerapi.com" override val mainUrl: String = "https://gdriveplayerapi.com"
} }
class Gdriveplayerapp: Gdriveplayer() { class Gdriveplayerapp : Gdriveplayer() {
override val mainUrl: String = "https://gdriveplayer.app" override val mainUrl: String = "https://gdriveplayer.app"
} }
class Gdriveplayerfun: Gdriveplayer() { class Gdriveplayerfun : Gdriveplayer() {
override val mainUrl: String = "https://gdriveplayer.fun" override val mainUrl: String = "https://gdriveplayer.fun"
} }
class Gdriveplayerio: Gdriveplayer() { class Gdriveplayerio : Gdriveplayer() {
override val mainUrl: String = "https://gdriveplayer.io" override val mainUrl: String = "https://gdriveplayer.io"
} }
class Gdriveplayerme: Gdriveplayer() { class Gdriveplayerme : Gdriveplayer() {
override val mainUrl: String = "https://gdriveplayer.me" override val mainUrl: String = "https://gdriveplayer.me"
} }
class Gdriveplayerbiz: Gdriveplayer() { class Gdriveplayerbiz : Gdriveplayer() {
override val mainUrl: String = "https://gdriveplayer.biz" override val mainUrl: String = "https://gdriveplayer.biz"
} }
class Gdriveplayerorg: Gdriveplayer() { class Gdriveplayerorg : Gdriveplayer() {
override val mainUrl: String = "https://gdriveplayer.org" override val mainUrl: String = "https://gdriveplayer.org"
} }
class Gdriveplayerus: Gdriveplayer() { class Gdriveplayerus : Gdriveplayer() {
override val mainUrl: String = "https://gdriveplayer.us" override val mainUrl: String = "https://gdriveplayer.us"
} }
class Gdriveplayerco: Gdriveplayer() { class Gdriveplayerco : Gdriveplayer() {
override val mainUrl: String = "https://gdriveplayer.co" override val mainUrl: String = "https://gdriveplayer.co"
} }
@ -136,6 +141,10 @@ open class Gdriveplayer : ExtractorApi() {
return find(str)?.groupValues?.getOrNull(1) return find(str)?.groupValues?.getOrNull(1)
} }
private fun String.addMarks(str: String): String {
return this.replace(Regex("\"?$str\"?"), "\"$str\"")
}
override suspend fun getUrl( override suspend fun getUrl(
url: String, url: String,
referer: String?, referer: String?,
@ -145,18 +154,19 @@ open class Gdriveplayer : ExtractorApi() {
val document = app.get(url).document val document = app.get(url).document
val eval = unpackJs(document)?.replace("\\", "") ?: return val eval = unpackJs(document)?.replace("\\", "") ?: return
val data = AppUtils.tryParseJson<AesData>(Regex("data='(\\S+?)'").first(eval)) ?: return val data = tryParseJson<AesData>(Regex("data='(\\S+?)'").first(eval)) ?: return
val password = Regex("null,['|\"](\\w+)['|\"]").first(eval) val password = Regex("null,['|\"](\\w+)['|\"]").first(eval)
?.split(Regex("\\D+")) ?.split(Regex("\\D+"))
?.joinToString("") { ?.joinToString("") {
Char(it.toInt()).toString() Char(it.toInt()).toString()
}.let { Regex("var pass = \"(\\S+?)\"").first(it ?: return)?.toByteArray() } }.let { Regex("var pass = \"(\\S+?)\"").first(it ?: return)?.toByteArray() }
?: throw ErrorLoadingException("can't find password") ?: throw ErrorLoadingException("can't find password")
val decryptedData = val decryptedData = cryptoAESHandler(data, password, false)?.let { getAndUnpack(it) }?.replace("\\", "")
cryptoAESHandler(data, password, false)?.let { getAndUnpack(it) }?.replace("\\", "")
?.substringAfter("sources:[")?.substringBefore("],")
Regex("\"file\":\"(\\S+?)\".*?res=(\\d+)").findAll(decryptedData ?: return).map { val sourceData = decryptedData?.substringAfter("sources:[")?.substringBefore("],")
val subData = decryptedData?.substringAfter("tracks:[")?.substringBefore("],")
Regex("\"file\":\"(\\S+?)\".*?res=(\\d+)").findAll(sourceData ?: return).map {
it.groupValues[1] to it.groupValues[2] it.groupValues[1] to it.groupValues[2]
}.toList().distinctBy { it.second }.map { (link, quality) -> }.toList().distinctBy { it.second }.map { (link, quality) ->
callback.invoke( callback.invoke(
@ -171,6 +181,17 @@ open class Gdriveplayer : ExtractorApi() {
) )
} }
subData?.addMarks("file")?.addMarks("kind")?.addMarks("label").let { dataSub ->
tryParseJson<List<Tracks>>("[$dataSub]")?.map { sub ->
subtitleCallback.invoke(
SubtitleFile(
sub.label,
httpsify(sub.file)
)
)
}
}
} }
data class AesData( data class AesData(
@ -179,4 +200,10 @@ open class Gdriveplayer : ExtractorApi() {
@JsonProperty("s") val s: String @JsonProperty("s") val s: String
) )
data class Tracks(
@JsonProperty("file") val file: String,
@JsonProperty("kind") val kind: String,
@JsonProperty("label") val label: String
)
} }

View file

@ -0,0 +1,40 @@
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.M3u8Helper
class Moviehab : ExtractorApi() {
override var name = "Moviehab"
override var mainUrl = "https://play.moviehab.com"
override val requiresReferer = false
override suspend fun getUrl(
url: String,
referer: String?,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
) {
val res = app.get(url)
res.document.select("video#player").let {
//should redirect first for making it works
val link = app.get("$mainUrl/${it.select("source").attr("src")}", referer = url).url
M3u8Helper.generateM3u8(
this.name,
link,
url
).forEach(callback)
Regex("src[\"|'],\\s[\"|'](\\S+)[\"|']\\)").find(res.text)?.groupValues?.get(1).let {sub ->
subtitleCallback.invoke(
SubtitleFile(
it.select("track").attr("label"),
"$mainUrl/$sub"
)
)
}
}
}
}

View file

@ -7,7 +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.M3u8Helper import com.lagradost.cloudstream3.utils.M3u8Helper
class SpeedoStream : ExtractorApi() { class SpeedoStream1 : SpeedoStream() {
override val mainUrl = "https://speedostream.nl"
}
open class SpeedoStream : ExtractorApi() {
override val name = "SpeedoStream" override val name = "SpeedoStream"
override val mainUrl = "https://speedostream.com" override val mainUrl = "https://speedostream.com"
override val requiresReferer = true override val requiresReferer = true

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.M3u8Helper import com.lagradost.cloudstream3.utils.M3u8Helper
class Sbspeed : StreamSB() {
override var name = "Sbspeed"
override var mainUrl = "https://sbspeed.com"
}
class Streamsss : StreamSB() { class Streamsss : StreamSB() {
override var mainUrl = "https://streamsss.net" override var mainUrl = "https://streamsss.net"
} }
@ -93,15 +98,15 @@ open class StreamSB : ExtractorApi() {
} }
data class Subs ( data class Subs (
@JsonProperty("file") val file: String, @JsonProperty("file") val file: String? = null,
@JsonProperty("label") val label: String, @JsonProperty("label") val label: String? = null,
) )
data class StreamData ( data class StreamData (
@JsonProperty("file") val file: String, @JsonProperty("file") val file: String,
@JsonProperty("cdn_img") val cdnImg: String, @JsonProperty("cdn_img") val cdnImg: String,
@JsonProperty("hash") val hash: String, @JsonProperty("hash") val hash: String,
@JsonProperty("subs") val subs: List<Subs>?, @JsonProperty("subs") val subs: ArrayList<Subs>? = arrayListOf(),
@JsonProperty("length") val length: String, @JsonProperty("length") val length: String,
@JsonProperty("id") val id: String, @JsonProperty("id") val id: String,
@JsonProperty("title") val title: String, @JsonProperty("title") val title: String,
@ -141,5 +146,14 @@ open class StreamSB : ExtractorApi() {
url, url,
headers = headers headers = headers
).forEach(callback) ).forEach(callback)
mapped.streamData.subs?.map {sub ->
subtitleCallback.invoke(
SubtitleFile(
sub.label.toString(),
sub.file ?: return@map null,
)
)
}
} }
} }

View file

@ -85,18 +85,12 @@ open class VidSrcExtractor : ExtractorApi() {
this.name, this.name,
this.name, this.name,
srcm3u8, srcm3u8,
this.mainUrl, "https://vidsrc.stream/",
Qualities.Unknown.value, Qualities.Unknown.value,
extractorData = pass, extractorData = pass,
isM3u8 = true isM3u8 = true
) )
) )
// M3u8Helper.generateM3u8(
// name,
// srcm3u8,
// absoluteUrl
// ).forEach(callback)
} else { } else {
loadExtractor(linkfixed, url, subtitleCallback, callback) loadExtractor(linkfixed, url, subtitleCallback, callback)
} }

View file

@ -1,12 +1,23 @@
package com.lagradost.cloudstream3.extractors package com.lagradost.cloudstream3.extractors
import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.SubtitleFile
import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.utils.AppUtils import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
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.getQualityFromName import com.lagradost.cloudstream3.utils.getQualityFromName
class Cdnplayer: XStreamCdn() {
override val name: String = "Cdnplayer"
override val mainUrl: String = "https://cdnplayer.online"
}
class Kotakajair: XStreamCdn() {
override val name: String = "Kotakajair"
override val mainUrl: String = "https://kotakajair.xyz"
}
class FEnet: XStreamCdn() { class FEnet: XStreamCdn() {
override val name: String = "FEnet" override val name: String = "FEnet"
override val mainUrl: String = "https://fembed.net" override val mainUrl: String = "https://fembed.net"
@ -59,44 +70,67 @@ open class XStreamCdn : ExtractorApi() {
//val type: String // Mp4 //val type: String // Mp4
) )
private data class Player(
@JsonProperty("poster_file") val poster_file: String? = null,
)
private data class ResponseJson( private data class ResponseJson(
@JsonProperty("success") val success: Boolean, @JsonProperty("success") val success: Boolean,
@JsonProperty("data") val data: List<ResponseData>? @JsonProperty("player") val player: Player? = null,
@JsonProperty("data") val data: List<ResponseData>?,
@JsonProperty("captions") val captions: List<Captions?>?,
)
private data class Captions(
@JsonProperty("id") val id: String,
@JsonProperty("hash") val hash: String,
@JsonProperty("language") val language: String,
@JsonProperty("extension") val extension: String
) )
override fun getExtractorUrl(id: String): String { override fun getExtractorUrl(id: String): String {
return "$domainUrl/api/source/$id" return "$domainUrl/api/source/$id"
} }
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> { override suspend fun getUrl(
url: String,
referer: String?,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
) {
val headers = mapOf( val headers = mapOf(
"Referer" to url, "Referer" to url,
"User-Agent" to "Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0", "User-Agent" to "Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0",
) )
val id = url.trimEnd('/').split("/").last() val id = url.trimEnd('/').split("/").last()
val newUrl = "https://${domainUrl}/api/source/${id}" val newUrl = "https://${domainUrl}/api/source/${id}"
val extractedLinksList: MutableList<ExtractorLink> = mutableListOf() app.post(newUrl, headers = headers).let { res ->
with(app.post(newUrl, headers = headers)) { val sources = tryParseJson<ResponseJson?>(res.text)
if (this.code != 200) return listOf() sources?.let {
val text = this.text
if (text.isEmpty()) return listOf()
if (text == """{"success":false,"data":"Video not found or has been removed"}""") return listOf()
AppUtils.parseJson<ResponseJson?>(text)?.let {
if (it.success && it.data != null) { if (it.success && it.data != null) {
it.data.forEach { data -> it.data.map { source ->
extractedLinksList.add( callback.invoke(
ExtractorLink( ExtractorLink(
name, name,
name = name, name = name,
data.file, source.file,
url, url,
getQualityFromName(data.label), getQualityFromName(source.label),
) )
) )
} }
} }
} }
val userData = sources?.player?.poster_file?.split("/")?.get(2)
sources?.captions?.map {
subtitleCallback.invoke(
SubtitleFile(
it?.language.toString(),
"$mainUrl/asset/userdata/$userData/caption/${it?.hash}/${it?.id}.${it?.extension}"
)
)
}
} }
return extractedLinksList
} }
} }

View file

@ -235,6 +235,7 @@ val extractorApis: MutableList<ExtractorApi> = arrayListOf(
Vidgomunime(), Vidgomunime(),
Sbflix(), Sbflix(),
Streamsss(), Streamsss(),
Sbspeed(),
Fastream(), Fastream(),
@ -246,6 +247,8 @@ val extractorApis: MutableList<ExtractorApi> = arrayListOf(
LayarKaca(), LayarKaca(),
Rasacintaku(), Rasacintaku(),
FEnet(), FEnet(),
Kotakajair(),
Cdnplayer(),
// WatchSB(), 'cause StreamSB.kt works // WatchSB(), 'cause StreamSB.kt works
Uqload(), Uqload(),
Uqload1(), Uqload1(),
@ -317,6 +320,7 @@ val extractorApis: MutableList<ExtractorApi> = arrayListOf(
Linkbox(), Linkbox(),
Acefile(), Acefile(),
SpeedoStream(), SpeedoStream(),
SpeedoStream1(),
Zorofile(), Zorofile(),
Embedgram(), Embedgram(),
Mvidoo(), Mvidoo(),
@ -324,6 +328,7 @@ val extractorApis: MutableList<ExtractorApi> = arrayListOf(
Vidmoly(), Vidmoly(),
Vidmolyme(), Vidmolyme(),
Voe(), Voe(),
Moviehab(),
Gdriveplayerapi(), Gdriveplayerapi(),
Gdriveplayerapp(), Gdriveplayerapp(),
@ -336,6 +341,7 @@ val extractorApis: MutableList<ExtractorApi> = arrayListOf(
Gdriveplayerco(), Gdriveplayerco(),
Gdriveplayer(), Gdriveplayer(),
DatabaseGdrive(), DatabaseGdrive(),
DatabaseGdrive2(),
YoutubeExtractor(), YoutubeExtractor(),
YoutubeShortLinkExtractor(), YoutubeShortLinkExtractor(),