Extractors (#677)

* StreamSB fix and Jawcloud

* Fixes and referer for gogoanime

* streamsb fix

* Update StreamSB.kt

Co-authored-by: Osten <11805592+LagradOst@users.noreply.github.com>
This commit is contained in:
Stormunblessed 2022-02-20 16:25:44 +00:00 committed by GitHub
parent 8f9ac96de5
commit 6500d3d897
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 243 additions and 58 deletions

View file

@ -305,7 +305,7 @@ class GogoanimeProvider : MainAPI() {
this.name, this.name,
"${this.name} ${source.label?.replace("0 P", "0p") ?: ""}", "${this.name} ${source.label?.replace("0 P", "0p") ?: ""}",
source.file, source.file,
"", "https://gogoplay.io",
getQualityFromName(source.label ?: ""), getQualityFromName(source.label ?: ""),
isM3u8 = source.type == "hls" isM3u8 = source.type == "hls"
) )

View file

@ -0,0 +1,49 @@
package com.lagradost.cloudstream3.extractors
import com.lagradost.cloudstream3.apmap
import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.network.WebViewResolver
import com.lagradost.cloudstream3.utils.ExtractorApi
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.M3u8Helper
import com.lagradost.cloudstream3.utils.getQualityFromName
class ZplayerV2 : GenericM3U8() {
override val name = "Zplayer V2"
override val mainUrl = "https://v2.zplayer.live"
}
open class GenericM3U8 : ExtractorApi() {
override val name = "Upstream"
override val mainUrl = "https://upstream.to"
override val requiresReferer = false
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> {
val response = app.get(
url, interceptor = WebViewResolver(
Regex("""master\.m3u8""")
)
)
val sources = mutableListOf<ExtractorLink>()
if (response.url.contains("m3u8")) M3u8Helper().m3u8Generation(
M3u8Helper.M3u8Stream(
response.url,
headers = response.headers.toMap()
), true
)
.map { stream ->
val qualityString = if ((stream.quality ?: 0) == 0) "" else "${stream.quality}p"
sources.add( ExtractorLink(
name,
"$name $qualityString",
stream.streamUrl,
url,
getQualityFromName(stream.quality.toString()),
true
))
}
return sources
}
}

View file

@ -0,0 +1,36 @@
package com.lagradost.cloudstream3.extractors
import com.lagradost.cloudstream3.apmap
import com.lagradost.cloudstream3.utils.*
import com.lagradost.cloudstream3.app
open class Jawcloud : ExtractorApi() {
override val name = "Jawcloud"
override val mainUrl = "https://jawcloud.co"
override val requiresReferer = false
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
val doc = app.get(url).document
val urlString = doc.select("html body div source").attr("src")
val sources = mutableListOf<ExtractorLink>()
if (urlString.contains("m3u8")) M3u8Helper().m3u8Generation(
M3u8Helper.M3u8Stream(
urlString,
headers = app.get(url).headers.toMap()
), true
)
.map { stream ->
val qualityString = if ((stream.quality ?: 0) == 0) "" else "${stream.quality}p"
sources.add( ExtractorLink(
name,
"$name $qualityString",
stream.streamUrl,
url,
getQualityFromName(stream.quality.toString()),
true
))
}
return sources
}
}

View file

@ -9,17 +9,13 @@ import com.lagradost.cloudstream3.utils.Qualities
import com.lagradost.cloudstream3.utils.getPostForm import com.lagradost.cloudstream3.utils.getPostForm
import org.jsoup.Jsoup import org.jsoup.Jsoup
class SBPlay1 : SBPlay() { //class SBPlay1 : SBPlay() {
override val mainUrl = "https://sbplay1.com" // override val mainUrl = "https://sbplay1.com"
} //}
class SBPlay2 : SBPlay() { //class SBPlay2 : SBPlay() {
override val mainUrl = "https://sbplay2.com" // override val mainUrl = "https://sbplay2.com"
} //}
class SBPlay3 : SBPlay() {
override val mainUrl = "https://pelistop.co"
}
open class SBPlay : ExtractorApi() { open class SBPlay : ExtractorApi() {
override val mainUrl = "https://sbplay.one" override val mainUrl = "https://sbplay.one"

View file

@ -1,52 +1,142 @@
package com.lagradost.cloudstream3.extractors package com.lagradost.cloudstream3.extractors
import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.USER_AGENT
import com.lagradost.cloudstream3.apmap
import com.lagradost.cloudstream3.utils.*
import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.utils.ExtractorApi import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.getAndUnpack
import com.lagradost.cloudstream3.utils.getQualityFromName
class StreamSB : ExtractorApi() {
override val name = "StreamSB" class StreamSB1 : StreamSB() {
override val mainUrl = "https://sbplay1.com"
}
class StreamSB2 : StreamSB() {
override val mainUrl = "https://sbplay2.com"
}
class StreamSB3 : StreamSB() {
override val mainUrl = "https://sbplay.one"
}
class StreamSB4 : StreamSB() {
override val mainUrl = "https://cloudemb.com"
}
class StreamSB5 : StreamSB() {
override val mainUrl = "https://sbplay.org" override val mainUrl = "https://sbplay.org"
private val sourceRegex = Regex("""sources:[\W\w]*?file:\s*"(.*?)"""") }
//private val m3u8Regex = Regex(""".*?(\d*).m3u8""") class StreamSB6 : StreamSB() {
//private val urlRegex = Regex("""(.*?)([^/]+$)""") override val mainUrl = "https://embedsb.com"
}
// 1: Resolution 2: url class StreamSB7 : StreamSB() {
private val m3u8UrlRegex = Regex("""RESOLUTION=\d*x(\d*).*\n(http.*.m3u8)""") override val mainUrl = "https://pelistop.co"
}
class StreamSB8 : StreamSB() {
override val mainUrl = "https://streamsb.net"
}
class StreamSB9 : StreamSB() {
override val mainUrl = "https://sbplay.one"
}
// This is a modified version of https://github.com/jmir1/aniyomi-extensions/blob/master/src/en/genoanime/src/eu/kanade/tachiyomi/animeextension/en/genoanime/extractors/StreamSBExtractor.kt
// The following code is under the Apache License 2.0 https://github.com/jmir1/aniyomi-extensions/blob/master/LICENSE
open class StreamSB : ExtractorApi() {
override val name = "StreamSB"
override val mainUrl = "https://watchsb.com"
override val requiresReferer = false override val requiresReferer = false
// https://sbembed.com/embed-ns50b0cukf9j.html -> https://sbvideo.net/play/ns50b0cukf9j private val hexArray = "0123456789ABCDEF".toCharArray()
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> {
val extractedLinksList: MutableList<ExtractorLink> = mutableListOf() private fun bytesToHex(bytes: ByteArray): String {
val newUrl = url.replace("sbplay.org/embed-", "sbplay.org/play/").removeSuffix(".html") val hexChars = CharArray(bytes.size * 2)
with(app.get(newUrl, timeout = 10)) { for (j in bytes.indices) {
getAndUnpack(this.text).let { val v = bytes[j].toInt() and 0xFF
sourceRegex.findAll(it).forEach { sourceMatch ->
val extractedUrl = sourceMatch.groupValues[1] hexChars[j * 2] = hexArray[v ushr 4]
if (extractedUrl.contains(".m3u8")) { hexChars[j * 2 + 1] = hexArray[v and 0x0F]
with(app.get(extractedUrl)) { }
m3u8UrlRegex.findAll(this.text).forEach { match -> return String(hexChars)
val extractedUrlM3u8 = match.groupValues[2] }
val extractedRes = match.groupValues[1]
extractedLinksList.add(
data class StreamData (
@JsonProperty("file") val file: String,
@JsonProperty("cdn_img") val cdnImg: String,
@JsonProperty("hash") val hash: String,
@JsonProperty("subs") val subs: List<String>,
@JsonProperty("length") val length: String,
@JsonProperty("id") val id: String,
@JsonProperty("title") val title: String,
@JsonProperty("backup") val backup: String,
)
data class Main (
@JsonProperty("stream_data") val streamData: StreamData,
@JsonProperty("status_code") val statusCode: Int,
)
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
val regexID = Regex("(embed-[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+|\\/e\\/[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)")
val id = regexID.findAll(url).map {
it.value.replace(Regex("(embed-|\\/e\\/)"),"")
}.first()
val bytes = id.toByteArray()
val bytesToHex = bytesToHex(bytes)
val master = "$mainUrl/sources40/566d337678566f743674494a7c7c${bytesToHex}7c7c346b6767586d6934774855537c7c73747265616d7362/6565417268755339773461447c7c346133383438333436313335376136323337373433383634376337633465366534393338373136643732373736343735373237613763376334363733353737303533366236333463353333363534366137633763373337343732363536313664373336327c7c6b586c3163614468645a47617c7c73747265616d7362"
val headers = mapOf(
"Host" to url.substringAfter("https://").substringBefore("/"),
"User-Agent" to USER_AGENT,
"Accept" to "application/json, text/plain, */*",
"Accept-Language" to "en-US,en;q=0.5",
"Referer" to url,
"watchsb" to "streamsb",
"DNT" to "1",
"Connection" to "keep-alive",
"Sec-Fetch-Dest" to "empty",
"Sec-Fetch-Mode" to "no-cors",
"Sec-Fetch-Site" to "same-origin",
"TE" to "trailers",
"Pragma" to "no-cache",
"Cache-Control" to "no-cache",)
val urltext = app.get(master,
headers = headers,
allowRedirects = false
).text
val mapped = urltext.let { parseJson<Main>(it) }
if (urltext.contains("m3u8")) return M3u8Helper().m3u8Generation(
M3u8Helper.M3u8Stream(
mapped.streamData.file,
headers = mapOf(
"User-Agent" to USER_AGENT,
"Accept" to "*/*",
"Accept-Language" to "en-US,en;q=0.5",
"Accept-Encoding" to "gzip, deflate, br",
"Origin" to mainUrl,
"DNT" to "1",
"Connection" to "keep-alive",
"Referer" to "$mainUrl/",
"Sec-Fetch-Dest" to "empty",
"Sec-Fetch-Mode" to "cors",
"Sec-Fetch-Site" to "cross-site",),
), true
)
.map { stream ->
val qualityString = if ((stream.quality ?: 0) == 0) "" else "${stream.quality}p"
ExtractorLink( ExtractorLink(
name, name,
"$name ${extractedRes}p", "$name $qualityString",
extractedUrlM3u8, stream.streamUrl,
extractedUrl, url,
getQualityFromName(extractedRes), getQualityFromName(stream.quality.toString()),
true true
) )
) }
} return null
}
}
}
}
}
return extractedLinksList
} }
} }

View file

@ -100,18 +100,27 @@ val extractorApis: Array<ExtractorApi> = arrayOf(
Mcloud(), Mcloud(),
XStreamCdn(), XStreamCdn(),
StreamSB(), StreamSB(),
StreamSB1(),
StreamSB2(),
StreamSB3(),
StreamSB4(),
StreamSB5(),
StreamSB6(),
StreamSB7(),
StreamSB8(),
StreamSB9(),
Streamhub(), Streamhub(),
FEmbed(), FEmbed(),
FeHD(), FeHD(),
Fplayer(), Fplayer(),
WatchSB(), // WatchSB(), 'cause StreamSB.kt works
Uqload(), Uqload(),
Uqload1(), Uqload1(),
Evoload(), Evoload(),
Evoload1(), Evoload1(),
VoeExtractor(), VoeExtractor(),
UpstreamExtractor(), // UpstreamExtractor(), GenericM3U8.kt works
Tomatomatela(), Tomatomatela(),
Cinestart(), Cinestart(),
@ -125,10 +134,15 @@ val extractorApis: Array<ExtractorApi> = arrayOf(
AsianLoad(), AsianLoad(),
SBPlay(), ZplayerV2(),
SBPlay1(), GenericM3U8(),
SBPlay2(), Jawcloud(),
SBPlay3(),
// StreamSB.kt works
// SBPlay(),
// SBPlay1(),
// SBPlay2(),
) )
fun getExtractorApiFromName(name: String): ExtractorApi { fun getExtractorApiFromName(name: String): ExtractorApi {