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} ${source.label?.replace("0 P", "0p") ?: ""}",
source.file,
"",
"https://gogoplay.io",
getQualityFromName(source.label ?: ""),
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 org.jsoup.Jsoup
class SBPlay1 : SBPlay() {
override val mainUrl = "https://sbplay1.com"
}
//class SBPlay1 : SBPlay() {
// override val mainUrl = "https://sbplay1.com"
//}
class SBPlay2 : SBPlay() {
override val mainUrl = "https://sbplay2.com"
}
class SBPlay3 : SBPlay() {
override val mainUrl = "https://pelistop.co"
}
//class SBPlay2 : SBPlay() {
// override val mainUrl = "https://sbplay2.com"
//}
open class SBPlay : ExtractorApi() {
override val mainUrl = "https://sbplay.one"

View File

@ -1,52 +1,142 @@
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.utils.ExtractorApi
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.getAndUnpack
import com.lagradost.cloudstream3.utils.getQualityFromName
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
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"
private val sourceRegex = Regex("""sources:[\W\w]*?file:\s*"(.*?)"""")
}
//private val m3u8Regex = Regex(""".*?(\d*).m3u8""")
//private val urlRegex = Regex("""(.*?)([^/]+$)""")
class StreamSB6 : StreamSB() {
override val mainUrl = "https://embedsb.com"
}
// 1: Resolution 2: url
private val m3u8UrlRegex = Regex("""RESOLUTION=\d*x(\d*).*\n(http.*.m3u8)""")
class StreamSB7 : StreamSB() {
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
// https://sbembed.com/embed-ns50b0cukf9j.html -> https://sbvideo.net/play/ns50b0cukf9j
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> {
val extractedLinksList: MutableList<ExtractorLink> = mutableListOf()
val newUrl = url.replace("sbplay.org/embed-", "sbplay.org/play/").removeSuffix(".html")
with(app.get(newUrl, timeout = 10)) {
getAndUnpack(this.text).let {
sourceRegex.findAll(it).forEach { sourceMatch ->
val extractedUrl = sourceMatch.groupValues[1]
if (extractedUrl.contains(".m3u8")) {
with(app.get(extractedUrl)) {
m3u8UrlRegex.findAll(this.text).forEach { match ->
val extractedUrlM3u8 = match.groupValues[2]
val extractedRes = match.groupValues[1]
extractedLinksList.add(
ExtractorLink(
name,
"$name ${extractedRes}p",
extractedUrlM3u8,
extractedUrl,
getQualityFromName(extractedRes),
true
)
)
}
}
}
}
}
private val hexArray = "0123456789ABCDEF".toCharArray()
private fun bytesToHex(bytes: ByteArray): String {
val hexChars = CharArray(bytes.size * 2)
for (j in bytes.indices) {
val v = bytes[j].toInt() and 0xFF
hexChars[j * 2] = hexArray[v ushr 4]
hexChars[j * 2 + 1] = hexArray[v and 0x0F]
}
return extractedLinksList
return String(hexChars)
}
}
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(
name,
"$name $qualityString",
stream.streamUrl,
url,
getQualityFromName(stream.quality.toString()),
true
)
}
return null
}
}

View File

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