forked from recloudstream/cloudstream
refactor on m3u8
This commit is contained in:
parent
615b81f600
commit
510411a9bc
15 changed files with 189 additions and 249 deletions
|
@ -8,7 +8,7 @@ import com.lagradost.cloudstream3.mvvm.safeApiCall
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.M3u8Helper
|
import com.lagradost.cloudstream3.utils.M3u8Helper
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
import com.lagradost.cloudstream3.utils.Qualities
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import org.mozilla.javascript.Context
|
import org.mozilla.javascript.Context
|
||||||
import org.mozilla.javascript.Scriptable
|
import org.mozilla.javascript.Scriptable
|
||||||
|
@ -22,8 +22,6 @@ class AllAnimeProvider : MainAPI() {
|
||||||
override val hasQuickSearch = false
|
override val hasQuickSearch = false
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
|
|
||||||
private val hlsHelper = M3u8Helper()
|
|
||||||
|
|
||||||
private fun getStatus(t: String): ShowStatus {
|
private fun getStatus(t: String): ShowStatus {
|
||||||
return when (t) {
|
return when (t) {
|
||||||
"Finished" -> ShowStatus.Completed
|
"Finished" -> ShowStatus.Completed
|
||||||
|
@ -125,7 +123,7 @@ class AllAnimeProvider : MainAPI() {
|
||||||
val ranlink = app.get(random).text
|
val ranlink = app.get(random).text
|
||||||
val jsonran = parseJson<RandomMain>(ranlink)
|
val jsonran = parseJson<RandomMain>(ranlink)
|
||||||
val ranhome = jsonran.data?.queryRandomRecommendation?.map {
|
val ranhome = jsonran.data?.queryRandomRecommendation?.map {
|
||||||
newAnimeSearchResponse(it.name!!,"$mainUrl/anime/${it.Id}", fix = false) {
|
newAnimeSearchResponse(it.name!!, "$mainUrl/anime/${it.Id}", fix = false) {
|
||||||
this.posterUrl = it.thumbnail
|
this.posterUrl = it.thumbnail
|
||||||
this.otherName = it.nativeName
|
this.otherName = it.nativeName
|
||||||
}
|
}
|
||||||
|
@ -319,18 +317,12 @@ class AllAnimeProvider : MainAPI() {
|
||||||
referer: String,
|
referer: String,
|
||||||
qualityName: String,
|
qualityName: String,
|
||||||
): List<ExtractorLink> {
|
): List<ExtractorLink> {
|
||||||
return hlsHelper.m3u8Generation(M3u8Helper.M3u8Stream(m3u8Link, null), true).map { stream ->
|
return M3u8Helper.generateM3u8(
|
||||||
val qualityString = if ((stream.quality ?: 0) == 0) "" else "${stream.quality}p"
|
this.name,
|
||||||
ExtractorLink(
|
m3u8Link,
|
||||||
this.name,
|
referer,
|
||||||
"${this.name} - $qualityName $qualityString",
|
name = "${this.name} - $qualityName"
|
||||||
stream.streamUrl,
|
)
|
||||||
referer,
|
|
||||||
getQualityFromName(stream.quality.toString()),
|
|
||||||
true,
|
|
||||||
stream.headers
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun loadLinks(
|
override suspend fun loadLinks(
|
||||||
|
@ -366,7 +358,7 @@ class AllAnimeProvider : MainAPI() {
|
||||||
"",
|
"",
|
||||||
link,
|
link,
|
||||||
data,
|
data,
|
||||||
getQualityFromName("1080"),
|
Qualities.P1080.value,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -396,7 +388,7 @@ class AllAnimeProvider : MainAPI() {
|
||||||
"$apiEndPoint/player?uri=" + (if (URI(server.link).host.isNotEmpty()) server.link else apiEndPoint + URI(
|
"$apiEndPoint/player?uri=" + (if (URI(server.link).host.isNotEmpty()) server.link else apiEndPoint + URI(
|
||||||
server.link
|
server.link
|
||||||
).path),
|
).path),
|
||||||
getQualityFromName("1080"),
|
Qualities.P1080.value,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -124,35 +124,21 @@ class GogoanimeProvider : MainAPI() {
|
||||||
) {
|
) {
|
||||||
when {
|
when {
|
||||||
source.file.contains("m3u8") -> {
|
source.file.contains("m3u8") -> {
|
||||||
M3u8Helper().m3u8Generation(
|
M3u8Helper.generateM3u8(
|
||||||
M3u8Helper.M3u8Stream(
|
mainApiName,
|
||||||
source.file,
|
source.file,
|
||||||
headers = mapOf("Referer" to "https://gogoplay4.com")
|
mainUrl,
|
||||||
), true
|
headers = mapOf("Referer" to "https://gogoplay4.com")
|
||||||
)
|
).forEach (sourceCallback)
|
||||||
.map { stream ->
|
|
||||||
val qualityString =
|
|
||||||
if ((stream.quality ?: 0) == 0) "" else "${stream.quality}p"
|
|
||||||
sourceCallback(
|
|
||||||
ExtractorLink(
|
|
||||||
mainApiName,
|
|
||||||
"$mainApiName $qualityString",
|
|
||||||
stream.streamUrl,
|
|
||||||
mainUrl,
|
|
||||||
getQualityFromName(stream.quality.toString()),
|
|
||||||
true
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
source.file.contains("vidstreaming") -> {
|
source.file.contains("vidstreaming") -> {
|
||||||
sourceCallback.invoke(
|
sourceCallback.invoke(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
mainApiName,
|
mainApiName,
|
||||||
"$mainApiName ${source.label?.replace("0 P", "0p") ?: ""}",
|
mainApiName,
|
||||||
source.file,
|
source.file,
|
||||||
mainUrl,
|
mainUrl,
|
||||||
getQualityFromName(source.label ?: ""),
|
getQualityFromName(source.label),
|
||||||
isM3u8 = source.type == "hls"
|
isM3u8 = source.type == "hls"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -161,10 +147,10 @@ class GogoanimeProvider : MainAPI() {
|
||||||
sourceCallback.invoke(
|
sourceCallback.invoke(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
mainApiName,
|
mainApiName,
|
||||||
"$mainApiName ${source.label?.replace("0 P", "0p") ?: ""}",
|
mainApiName,
|
||||||
source.file,
|
source.file,
|
||||||
mainUrl,
|
mainUrl,
|
||||||
getQualityFromName(source.label ?: ""),
|
getQualityFromName(source.label),
|
||||||
isM3u8 = source.type == "hls"
|
isM3u8 = source.type == "hls"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -372,7 +358,7 @@ class GogoanimeProvider : MainAPI() {
|
||||||
callback(
|
callback(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
"Gogoanime",
|
"Gogoanime",
|
||||||
if (qual == "null") "Gogoanime" else "Gogoanime - " + qual + "p",
|
"Gogoanime",
|
||||||
it.attr("href"),
|
it.attr("href"),
|
||||||
page.url,
|
page.url,
|
||||||
getQualityFromName(qual),
|
getQualityFromName(qual),
|
||||||
|
|
|
@ -150,7 +150,7 @@ class KawaiifuProvider : MainAPI() {
|
||||||
callback(
|
callback(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
"Kawaiifu",
|
"Kawaiifu",
|
||||||
"${it.first} - ${source.second}",
|
it.first,
|
||||||
source.first,
|
source.first,
|
||||||
"",
|
"",
|
||||||
getQualityFromName(source.second),
|
getQualityFromName(source.second),
|
||||||
|
|
|
@ -333,7 +333,7 @@ class TenshiProvider : MainAPI() {
|
||||||
sources.addAll(qualities.map {
|
sources.addAll(qualities.map {
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
this.name,
|
this.name,
|
||||||
"${this.name} $release - " + it.size + "p",
|
"${this.name} $release",
|
||||||
fixUrl(it.src),
|
fixUrl(it.src),
|
||||||
this.mainUrl,
|
this.mainUrl,
|
||||||
getQualityFromName("${it.size}"),
|
getQualityFromName("${it.size}"),
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package com.lagradost.cloudstream3.extractors
|
package com.lagradost.cloudstream3.extractors
|
||||||
|
|
||||||
import com.lagradost.cloudstream3.app
|
import com.lagradost.cloudstream3.app
|
||||||
import com.lagradost.cloudstream3.utils.*
|
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||||
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
|
import com.lagradost.cloudstream3.utils.M3u8Helper
|
||||||
|
import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
|
||||||
class AsianLoad : ExtractorApi() {
|
class AsianLoad : ExtractorApi() {
|
||||||
|
@ -17,32 +20,22 @@ class AsianLoad : ExtractorApi() {
|
||||||
val extractedUrl = sourceMatch.groupValues[1]
|
val extractedUrl = sourceMatch.groupValues[1]
|
||||||
// Trusting this isn't mp4, may fuck up stuff
|
// Trusting this isn't mp4, may fuck up stuff
|
||||||
if (URI(extractedUrl).path.endsWith(".m3u8")) {
|
if (URI(extractedUrl).path.endsWith(".m3u8")) {
|
||||||
M3u8Helper().m3u8Generation(
|
M3u8Helper.generateM3u8(
|
||||||
M3u8Helper.M3u8Stream(
|
name,
|
||||||
extractedUrl,
|
extractedUrl,
|
||||||
headers = mapOf("referer" to this.url)
|
url,
|
||||||
), true
|
headers = mapOf("referer" to this.url)
|
||||||
)
|
).forEach { link ->
|
||||||
.forEach { stream ->
|
extractedLinksList.add(link)
|
||||||
extractedLinksList.add(
|
}
|
||||||
ExtractorLink(
|
|
||||||
name,
|
|
||||||
name = name,
|
|
||||||
stream.streamUrl,
|
|
||||||
url,
|
|
||||||
getQualityFromName(stream.quality?.toString()),
|
|
||||||
true
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else if (extractedUrl.endsWith(".mp4")) {
|
} else if (extractedUrl.endsWith(".mp4")) {
|
||||||
extractedLinksList.add(
|
extractedLinksList.add(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
name,
|
name,
|
||||||
"$name ${sourceMatch.groupValues[2]}",
|
name,
|
||||||
extractedUrl,
|
extractedUrl,
|
||||||
url.replace(" ", "%20"),
|
url.replace(" ", "%20"),
|
||||||
Qualities.Unknown.value,
|
getQualityFromName(sourceMatch.groupValues[2]),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
package com.lagradost.cloudstream3.extractors
|
package com.lagradost.cloudstream3.extractors
|
||||||
|
|
||||||
import com.lagradost.cloudstream3.apmap
|
|
||||||
import com.lagradost.cloudstream3.app
|
import com.lagradost.cloudstream3.app
|
||||||
import com.lagradost.cloudstream3.network.WebViewResolver
|
import com.lagradost.cloudstream3.network.WebViewResolver
|
||||||
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.M3u8Helper
|
import com.lagradost.cloudstream3.utils.M3u8Helper
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
open class GenericM3U8 : ExtractorApi() {
|
open class GenericM3U8 : ExtractorApi() {
|
||||||
|
@ -23,21 +19,14 @@ open class GenericM3U8 : ExtractorApi() {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
val sources = mutableListOf<ExtractorLink>()
|
val sources = mutableListOf<ExtractorLink>()
|
||||||
if (response.url.contains("m3u8")) M3u8Helper().m3u8Generation(
|
if (response.url.contains("m3u8"))
|
||||||
M3u8Helper.M3u8Stream(
|
M3u8Helper.generateM3u8(
|
||||||
|
name,
|
||||||
response.url,
|
response.url,
|
||||||
|
url,
|
||||||
headers = response.headers.toMap()
|
headers = response.headers.toMap()
|
||||||
), true
|
).forEach { link ->
|
||||||
)
|
sources.add(link)
|
||||||
.map { stream ->
|
|
||||||
sources.add( ExtractorLink(
|
|
||||||
name,
|
|
||||||
name = name,
|
|
||||||
stream.streamUrl,
|
|
||||||
url,
|
|
||||||
getQualityFromName(stream.quality?.toString()),
|
|
||||||
true
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
return sources
|
return sources
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package com.lagradost.cloudstream3.extractors
|
package com.lagradost.cloudstream3.extractors
|
||||||
|
|
||||||
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.ExtractorLink
|
||||||
|
import com.lagradost.cloudstream3.utils.M3u8Helper
|
||||||
|
|
||||||
|
|
||||||
open class Jawcloud : ExtractorApi() {
|
open class Jawcloud : ExtractorApi() {
|
||||||
|
@ -14,22 +15,13 @@ open class Jawcloud : ExtractorApi() {
|
||||||
val doc = app.get(url).document
|
val doc = app.get(url).document
|
||||||
val urlString = doc.select("html body div source").attr("src")
|
val urlString = doc.select("html body div source").attr("src")
|
||||||
val sources = mutableListOf<ExtractorLink>()
|
val sources = mutableListOf<ExtractorLink>()
|
||||||
if (urlString.contains("m3u8")) M3u8Helper().m3u8Generation(
|
if (urlString.contains("m3u8"))
|
||||||
M3u8Helper.M3u8Stream(
|
M3u8Helper.generateM3u8(
|
||||||
|
name,
|
||||||
urlString,
|
urlString,
|
||||||
|
url,
|
||||||
headers = app.get(url).headers.toMap()
|
headers = app.get(url).headers.toMap()
|
||||||
), true
|
).forEach { link -> sources.add(link) }
|
||||||
)
|
|
||||||
.map { stream ->
|
|
||||||
sources.add( ExtractorLink(
|
|
||||||
name,
|
|
||||||
name = name,
|
|
||||||
stream.streamUrl,
|
|
||||||
url,
|
|
||||||
getQualityFromName(stream.quality?.toString()),
|
|
||||||
true
|
|
||||||
))
|
|
||||||
}
|
|
||||||
return sources
|
return sources
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,7 +8,6 @@ import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
||||||
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.M3u8Helper
|
import com.lagradost.cloudstream3.utils.M3u8Helper
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
|
||||||
|
|
||||||
open class Mcloud : ExtractorApi() {
|
open class Mcloud : ExtractorApi() {
|
||||||
override var name = "Mcloud"
|
override var name = "Mcloud"
|
||||||
|
@ -56,24 +55,14 @@ open class Mcloud : ExtractorApi() {
|
||||||
if (mapped.success)
|
if (mapped.success)
|
||||||
mapped.media.sources.apmap {
|
mapped.media.sources.apmap {
|
||||||
if (it.file.contains("m3u8")) {
|
if (it.file.contains("m3u8")) {
|
||||||
M3u8Helper().m3u8Generation(
|
M3u8Helper.generateM3u8(
|
||||||
M3u8Helper.M3u8Stream(
|
name,
|
||||||
it.file,
|
it.file,
|
||||||
headers = app.get(url).headers.toMap()
|
url,
|
||||||
), true
|
headers = app.get(url).headers.toMap()
|
||||||
)
|
).forEach { link ->
|
||||||
.map { stream ->
|
sources.add(link)
|
||||||
sources.add(
|
}
|
||||||
ExtractorLink(
|
|
||||||
name,
|
|
||||||
name = name,
|
|
||||||
stream.streamUrl,
|
|
||||||
url,
|
|
||||||
getQualityFromName(stream.quality?.toString()),
|
|
||||||
true
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sources
|
return sources
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package com.lagradost.cloudstream3.extractors
|
package com.lagradost.cloudstream3.extractors
|
||||||
|
|
||||||
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.ExtractorLink
|
||||||
|
import com.lagradost.cloudstream3.utils.M3u8Helper
|
||||||
|
|
||||||
|
|
||||||
open class PlayerVoxzer : ExtractorApi() {
|
open class PlayerVoxzer : ExtractorApi() {
|
||||||
|
@ -16,21 +17,14 @@ open class PlayerVoxzer : ExtractorApi() {
|
||||||
val m3u8regex = Regex("((https:|http:)\\/\\/.*\\.m3u8)")
|
val m3u8regex = Regex("((https:|http:)\\/\\/.*\\.m3u8)")
|
||||||
val sources = mutableListOf<ExtractorLink>()
|
val sources = mutableListOf<ExtractorLink>()
|
||||||
val listm3 = m3u8regex.find(urltext)?.value
|
val listm3 = m3u8regex.find(urltext)?.value
|
||||||
if (listm3?.contains("m3u8") == true) M3u8Helper().m3u8Generation(
|
if (listm3?.contains("m3u8") == true)
|
||||||
M3u8Helper.M3u8Stream(
|
M3u8Helper.generateM3u8(
|
||||||
|
name,
|
||||||
listm3,
|
listm3,
|
||||||
|
url,
|
||||||
headers = app.get(url).headers.toMap()
|
headers = app.get(url).headers.toMap()
|
||||||
), true
|
).forEach { link ->
|
||||||
)
|
sources.add(link)
|
||||||
.map { stream ->
|
|
||||||
sources.add( ExtractorLink(
|
|
||||||
name,
|
|
||||||
name = name,
|
|
||||||
stream.streamUrl,
|
|
||||||
url,
|
|
||||||
getQualityFromName(stream.quality?.toString()),
|
|
||||||
true
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
return sources
|
return sources
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
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.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.AppUtils.parseJson
|
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
||||||
|
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||||
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
|
import com.lagradost.cloudstream3.utils.M3u8Helper
|
||||||
|
|
||||||
|
|
||||||
class StreamSB1 : StreamSB() {
|
class StreamSB1 : StreamSB() {
|
||||||
|
@ -103,23 +103,13 @@ open class StreamSB : ExtractorApi() {
|
||||||
val mapped = urltext.let { parseJson<Main>(it) }
|
val mapped = urltext.let { parseJson<Main>(it) }
|
||||||
val testurl = app.get(mapped.streamData.file, headers = headers).text
|
val testurl = app.get(mapped.streamData.file, headers = headers).text
|
||||||
// val urlmain = mapped.streamData.file.substringBefore("/hls/")
|
// val urlmain = mapped.streamData.file.substringBefore("/hls/")
|
||||||
if (urltext.contains("m3u8") && testurl.contains("EXTM3U")) return M3u8Helper().m3u8Generation(
|
if (urltext.contains("m3u8") && testurl.contains("EXTM3U"))
|
||||||
M3u8Helper.M3u8Stream(
|
return M3u8Helper.generateM3u8(
|
||||||
|
name,
|
||||||
mapped.streamData.file,
|
mapped.streamData.file,
|
||||||
|
url,
|
||||||
headers = headers
|
headers = headers
|
||||||
), true
|
)
|
||||||
)
|
|
||||||
.map { stream ->
|
|
||||||
// val cleanstreamurl = stream.streamUrl.replace(Regex("https://.*/hls/"), "$urlmain/hls/")
|
|
||||||
ExtractorLink(
|
|
||||||
name,
|
|
||||||
name = name,
|
|
||||||
stream.streamUrl,
|
|
||||||
url,
|
|
||||||
getQualityFromName(stream.quality?.toString()),
|
|
||||||
true
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,8 +4,7 @@ import com.lagradost.cloudstream3.app
|
||||||
import com.lagradost.cloudstream3.network.WebViewResolver
|
import com.lagradost.cloudstream3.network.WebViewResolver
|
||||||
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.M3u8Helper
|
import com.lagradost.cloudstream3.utils.M3u8Helper.Companion.generateM3u8
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
|
||||||
|
|
||||||
open class WatchSB : ExtractorApi() {
|
open class WatchSB : ExtractorApi() {
|
||||||
override var name = "WatchSB"
|
override var name = "WatchSB"
|
||||||
|
@ -19,21 +18,6 @@ open class WatchSB : ExtractorApi() {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
return M3u8Helper().m3u8Generation(
|
return generateM3u8(name, response.url, url, headers = response.headers.toMap())
|
||||||
M3u8Helper.M3u8Stream(
|
|
||||||
response.url,
|
|
||||||
headers = response.headers.toMap()
|
|
||||||
), true
|
|
||||||
)
|
|
||||||
.map { stream ->
|
|
||||||
ExtractorLink(
|
|
||||||
name,
|
|
||||||
name = name,
|
|
||||||
stream.streamUrl,
|
|
||||||
url,
|
|
||||||
getQualityFromName(stream.quality?.toString()),
|
|
||||||
true
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,11 +5,16 @@ import com.fasterxml.jackson.module.kotlin.readValue
|
||||||
import com.lagradost.cloudstream3.apmap
|
import com.lagradost.cloudstream3.apmap
|
||||||
import com.lagradost.cloudstream3.app
|
import com.lagradost.cloudstream3.app
|
||||||
import com.lagradost.cloudstream3.mapper
|
import com.lagradost.cloudstream3.mapper
|
||||||
import com.lagradost.cloudstream3.utils.*
|
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||||
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
|
import com.lagradost.cloudstream3.utils.M3u8Helper.Companion.generateM3u8
|
||||||
|
import com.lagradost.cloudstream3.utils.Qualities
|
||||||
|
import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
|
|
||||||
class Vidstreamz : WcoStream() {
|
class Vidstreamz : WcoStream() {
|
||||||
override var mainUrl = "https://vidstreamz.online"
|
override var mainUrl = "https://vidstreamz.online"
|
||||||
}
|
}
|
||||||
|
|
||||||
class Vizcloud : WcoStream() {
|
class Vizcloud : WcoStream() {
|
||||||
override var mainUrl = "https://vizcloud2.ru"
|
override var mainUrl = "https://vizcloud2.ru"
|
||||||
}
|
}
|
||||||
|
@ -46,14 +51,16 @@ open class WcoStream : ExtractorApi() {
|
||||||
override var name = "VidStream" //Cause works for animekisa and wco
|
override var name = "VidStream" //Cause works for animekisa and wco
|
||||||
override var mainUrl = "https://vidstream.pro"
|
override var mainUrl = "https://vidstream.pro"
|
||||||
override val requiresReferer = false
|
override val requiresReferer = false
|
||||||
private val hlsHelper = M3u8Helper()
|
|
||||||
|
|
||||||
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> {
|
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> {
|
||||||
val baseUrl = url.split("/e/")[0]
|
val baseUrl = url.split("/e/")[0]
|
||||||
|
|
||||||
val html = app.get(url, headers = mapOf("Referer" to "https://wcostream.cc/")).text
|
val html = app.get(url, headers = mapOf("Referer" to "https://wcostream.cc/")).text
|
||||||
val (Id) = (Regex("/e/(.*?)?domain").find(url)?.destructured ?: Regex("""/e/(.*)""").find(url)?.destructured) ?: return emptyList()
|
val (Id) = (Regex("/e/(.*?)?domain").find(url)?.destructured ?: Regex("""/e/(.*)""").find(
|
||||||
val (skey) = Regex("""skey\s=\s['"](.*?)['"];""").find(html)?.destructured ?: return emptyList()
|
url
|
||||||
|
)?.destructured) ?: return emptyList()
|
||||||
|
val (skey) = Regex("""skey\s=\s['"](.*?)['"];""").find(html)?.destructured
|
||||||
|
?: return emptyList()
|
||||||
|
|
||||||
val apiLink = "$baseUrl/info/$Id?domain=wcostream.cc&skey=$skey"
|
val apiLink = "$baseUrl/info/$Id?domain=wcostream.cc&skey=$skey"
|
||||||
val referrer = "$baseUrl/e/$Id?domain=wcostream.cc"
|
val referrer = "$baseUrl/e/$Id?domain=wcostream.cc"
|
||||||
|
@ -82,17 +89,18 @@ open class WcoStream : ExtractorApi() {
|
||||||
if (mainUrl == "https://vizcloud2.ru" || mainUrl == "https://vizcloud.online") {
|
if (mainUrl == "https://vizcloud2.ru" || mainUrl == "https://vizcloud.online") {
|
||||||
if (it.file.contains("vizcloud2.ru") || it.file.contains("vizcloud.online")) {
|
if (it.file.contains("vizcloud2.ru") || it.file.contains("vizcloud.online")) {
|
||||||
//Had to do this thing 'cause "list.m3u8#.mp4" gives 404 error so no quality is added
|
//Had to do this thing 'cause "list.m3u8#.mp4" gives 404 error so no quality is added
|
||||||
val link1080 = it.file.replace("list.m3u8#.mp4","H4/v.m3u8")
|
val link1080 = it.file.replace("list.m3u8#.mp4", "H4/v.m3u8")
|
||||||
val link720 = it.file.replace("list.m3u8#.mp4","H3/v.m3u8")
|
val link720 = it.file.replace("list.m3u8#.mp4", "H3/v.m3u8")
|
||||||
val link480 = it.file.replace("list.m3u8#.mp4","H2/v.m3u8")
|
val link480 = it.file.replace("list.m3u8#.mp4", "H2/v.m3u8")
|
||||||
val link360 = it.file.replace("list.m3u8#.mp4","H1/v.m3u8")
|
val link360 = it.file.replace("list.m3u8#.mp4", "H1/v.m3u8")
|
||||||
val linkauto = it.file.replace("#.mp4","")
|
val linkauto = it.file.replace("#.mp4", "")
|
||||||
listOf(
|
listOf(
|
||||||
link1080,
|
link1080,
|
||||||
link720,
|
link720,
|
||||||
link480,
|
link480,
|
||||||
link360,
|
link360,
|
||||||
linkauto).apmap { serverurl ->
|
linkauto
|
||||||
|
).apmap { serverurl ->
|
||||||
val testurl = app.get(serverurl, headers = mapOf("Referer" to url)).text
|
val testurl = app.get(serverurl, headers = mapOf("Referer" to url)).text
|
||||||
if (testurl.contains("EXTM3")) {
|
if (testurl.contains("EXTM3")) {
|
||||||
val quality = if (serverurl.contains("H4")) "1080p"
|
val quality = if (serverurl.contains("H4")) "1080p"
|
||||||
|
@ -116,34 +124,27 @@ open class WcoStream : ExtractorApi() {
|
||||||
}
|
}
|
||||||
if (mainUrl == "https://vidstream.pro" || mainUrl == "https://vidstreamz.online" || mainUrl == "https://vizcloud2.online"
|
if (mainUrl == "https://vidstream.pro" || mainUrl == "https://vidstreamz.online" || mainUrl == "https://vizcloud2.online"
|
||||||
|| mainUrl == "https://vizcloud.xyz" || mainUrl == "https://vizcloud.live" || mainUrl == "https://vizcloud.info"
|
|| mainUrl == "https://vizcloud.xyz" || mainUrl == "https://vizcloud.live" || mainUrl == "https://vizcloud.info"
|
||||||
|| mainUrl == "https://mwvn.vizcloud.info" || mainUrl == "https://vizcloud.digital") {
|
|| mainUrl == "https://mwvn.vizcloud.info" || mainUrl == "https://vizcloud.digital"
|
||||||
if (it.file.contains("m3u8")) {
|
) {
|
||||||
hlsHelper.m3u8Generation(M3u8Helper.M3u8Stream(it.file.replace("#.mp4",""), null,
|
if (it.file.contains("m3u8")) {
|
||||||
headers = mapOf("Referer" to url)), true)
|
generateM3u8(
|
||||||
.forEach { stream ->
|
|
||||||
sources.add(
|
|
||||||
ExtractorLink(
|
|
||||||
name,
|
|
||||||
name = name,
|
|
||||||
stream.streamUrl,
|
|
||||||
url,
|
|
||||||
getQualityFromName(stream.quality?.toString()),
|
|
||||||
true,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sources.add(
|
|
||||||
ExtractorLink(
|
|
||||||
name,
|
name,
|
||||||
name = name,
|
it.file.replace("#.mp4", ""),
|
||||||
it.file,
|
url,
|
||||||
"",
|
headers = mapOf("Referer" to url)
|
||||||
Qualities.P720.value,
|
|
||||||
false
|
|
||||||
)
|
)
|
||||||
)
|
} else {
|
||||||
}
|
sources.add(
|
||||||
|
ExtractorLink(
|
||||||
|
name,
|
||||||
|
name = name,
|
||||||
|
it.file,
|
||||||
|
"",
|
||||||
|
Qualities.P720.value,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,10 @@ package com.lagradost.cloudstream3.extractors
|
||||||
|
|
||||||
import com.lagradost.cloudstream3.apmap
|
import com.lagradost.cloudstream3.apmap
|
||||||
import com.lagradost.cloudstream3.app
|
import com.lagradost.cloudstream3.app
|
||||||
import com.lagradost.cloudstream3.utils.*
|
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||||
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
|
import com.lagradost.cloudstream3.utils.M3u8Helper
|
||||||
|
import com.lagradost.cloudstream3.utils.getAndUnpack
|
||||||
|
|
||||||
class Zplayer: ZplayerV2() {
|
class Zplayer: ZplayerV2() {
|
||||||
override var name: String = "Zplayer"
|
override var name: String = "Zplayer"
|
||||||
|
@ -37,22 +40,14 @@ open class ZplayerV2 : ExtractorApi() {
|
||||||
if (urlm3u8.contains("m3u8")) {
|
if (urlm3u8.contains("m3u8")) {
|
||||||
val testurl = app.get(urlm3u8, headers = mapOf("Referer" to url)).text
|
val testurl = app.get(urlm3u8, headers = mapOf("Referer" to url)).text
|
||||||
if (testurl.contains("EXTM3U")) {
|
if (testurl.contains("EXTM3U")) {
|
||||||
M3u8Helper().m3u8Generation(
|
M3u8Helper.generateM3u8(
|
||||||
M3u8Helper.M3u8Stream(
|
name,
|
||||||
urlm3u8,
|
urlm3u8,
|
||||||
headers = mapOf("Referer" to url)
|
url,
|
||||||
), true
|
headers = mapOf("Referer" to url)
|
||||||
)
|
).forEach { link ->
|
||||||
.map { stream ->
|
sources.add(link)
|
||||||
sources.add( ExtractorLink(
|
}
|
||||||
source = name,
|
|
||||||
name = name,
|
|
||||||
stream.streamUrl,
|
|
||||||
url,
|
|
||||||
getQualityFromName(stream.quality?.toString()),
|
|
||||||
true
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package com.lagradost.cloudstream3.movieproviders
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.M3u8Helper
|
import com.lagradost.cloudstream3.utils.M3u8Helper
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
|
||||||
import com.lagradost.cloudstream3.utils.loadExtractor
|
import com.lagradost.cloudstream3.utils.loadExtractor
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
|
|
||||||
|
@ -204,25 +203,14 @@ open class PelisplusProviderTemplate : MainAPI() {
|
||||||
val soup = app.get(link).text
|
val soup = app.get(link).text
|
||||||
val m3u8regex = Regex("((https:|http:)\\/\\/.*m3u8.*expiry=(\\d+))")
|
val m3u8regex = Regex("((https:|http:)\\/\\/.*m3u8.*expiry=(\\d+))")
|
||||||
val m3u8 = m3u8regex.find(soup)?.value ?: return false
|
val m3u8 = m3u8regex.find(soup)?.value ?: return false
|
||||||
M3u8Helper().m3u8Generation(
|
|
||||||
M3u8Helper.M3u8Stream(
|
M3u8Helper.generateM3u8(
|
||||||
m3u8,
|
name,
|
||||||
headers = mapOf("Referer" to mainUrl)
|
m3u8,
|
||||||
), true
|
mainUrl,
|
||||||
)
|
headers = mapOf("Referer" to mainUrl)
|
||||||
.map { stream ->
|
).forEach (callback)
|
||||||
val qualityString = if ((stream.quality ?: 0) == 0) "" else "${stream.quality}p"
|
|
||||||
callback(
|
|
||||||
ExtractorLink(
|
|
||||||
name,
|
|
||||||
"$name $qualityString",
|
|
||||||
stream.streamUrl,
|
|
||||||
mainUrl,
|
|
||||||
getQualityFromName(stream.quality.toString()),
|
|
||||||
true
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,13 +10,47 @@ import kotlin.math.pow
|
||||||
|
|
||||||
|
|
||||||
class M3u8Helper {
|
class M3u8Helper {
|
||||||
|
companion object {
|
||||||
|
private val generator = M3u8Helper()
|
||||||
|
fun generateM3u8(
|
||||||
|
source: String,
|
||||||
|
streamUrl: String,
|
||||||
|
referer: String,
|
||||||
|
quality: Int? = null,
|
||||||
|
headers: Map<String, String> = mapOf(),
|
||||||
|
name: String = source
|
||||||
|
): List<ExtractorLink> {
|
||||||
|
return generator.m3u8Generation(
|
||||||
|
M3u8Stream(
|
||||||
|
streamUrl = streamUrl,
|
||||||
|
quality = quality,
|
||||||
|
headers = headers,
|
||||||
|
), true
|
||||||
|
)
|
||||||
|
.map { stream ->
|
||||||
|
ExtractorLink(
|
||||||
|
source,
|
||||||
|
name = name,
|
||||||
|
stream.streamUrl,
|
||||||
|
referer,
|
||||||
|
stream.quality ?: Qualities.Unknown.value,
|
||||||
|
true,
|
||||||
|
stream.headers,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private val ENCRYPTION_DETECTION_REGEX = Regex("#EXT-X-KEY:METHOD=([^,]+),")
|
private val ENCRYPTION_DETECTION_REGEX = Regex("#EXT-X-KEY:METHOD=([^,]+),")
|
||||||
private val ENCRYPTION_URL_IV_REGEX = Regex("#EXT-X-KEY:METHOD=([^,]+),URI=\"([^\"]+)\"(?:,IV=(.*))?")
|
private val ENCRYPTION_URL_IV_REGEX =
|
||||||
|
Regex("#EXT-X-KEY:METHOD=([^,]+),URI=\"([^\"]+)\"(?:,IV=(.*))?")
|
||||||
private val QUALITY_REGEX =
|
private val QUALITY_REGEX =
|
||||||
Regex("""#EXT-X-STREAM-INF:(?:(?:.*?(?:RESOLUTION=\d+x(\d+)).*?\s+(.*))|(?:.*?\s+(.*)))""")
|
Regex("""#EXT-X-STREAM-INF:(?:(?:.*?(?:RESOLUTION=\d+x(\d+)).*?\s+(.*))|(?:.*?\s+(.*)))""")
|
||||||
private val TS_EXTENSION_REGEX = Regex("""(.*\.ts.*|.*\.jpg.*)""") //.jpg here 'case vizcloud uses .jpg instead of .ts
|
private val TS_EXTENSION_REGEX =
|
||||||
|
Regex("""(.*\.ts.*|.*\.jpg.*)""") //.jpg here 'case vizcloud uses .jpg instead of .ts
|
||||||
|
|
||||||
fun absoluteExtensionDetermination(url: String): String? {
|
private fun absoluteExtensionDetermination(url: String): String? {
|
||||||
val split = url.split("/")
|
val split = url.split("/")
|
||||||
val gg: String = split[split.size - 1].split("?")[0]
|
val gg: String = split[split.size - 1].split("?")[0]
|
||||||
return if (gg.contains(".")) {
|
return if (gg.contains(".")) {
|
||||||
|
@ -40,7 +74,11 @@ class M3u8Helper {
|
||||||
}
|
}
|
||||||
}.iterator()
|
}.iterator()
|
||||||
|
|
||||||
private fun getDecrypter(secretKey: ByteArray, data: ByteArray, iv: ByteArray = "".toByteArray()): ByteArray {
|
private fun getDecrypter(
|
||||||
|
secretKey: ByteArray,
|
||||||
|
data: ByteArray,
|
||||||
|
iv: ByteArray = "".toByteArray()
|
||||||
|
): ByteArray {
|
||||||
val ivKey = if (iv.isEmpty()) defaultIvGen.next() else iv
|
val ivKey = if (iv.isEmpty()) defaultIvGen.next() else iv
|
||||||
val c = Cipher.getInstance("AES/CBC/PKCS5Padding")
|
val c = Cipher.getInstance("AES/CBC/PKCS5Padding")
|
||||||
val skSpec = SecretKeySpec(secretKey, "AES")
|
val skSpec = SecretKeySpec(secretKey, "AES")
|
||||||
|
@ -135,7 +173,14 @@ class M3u8Helper {
|
||||||
)
|
)
|
||||||
|
|
||||||
fun hlsYield(qualities: List<M3u8Stream>, startIndex: Int = 0): Iterator<HlsDownloadData> {
|
fun hlsYield(qualities: List<M3u8Stream>, startIndex: Int = 0): Iterator<HlsDownloadData> {
|
||||||
if (qualities.isEmpty()) return listOf(HlsDownloadData(byteArrayOf(), 1, 1, true)).iterator()
|
if (qualities.isEmpty()) return listOf(
|
||||||
|
HlsDownloadData(
|
||||||
|
byteArrayOf(),
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
).iterator()
|
||||||
|
|
||||||
var selected = selectBest(qualities)
|
var selected = selectBest(qualities)
|
||||||
if (selected == null) {
|
if (selected == null) {
|
||||||
|
@ -148,7 +193,8 @@ class M3u8Helper {
|
||||||
|
|
||||||
val secondSelection = selectBest(streams.ifEmpty { listOf(selected) })
|
val secondSelection = selectBest(streams.ifEmpty { listOf(selected) })
|
||||||
if (secondSelection != null) {
|
if (secondSelection != null) {
|
||||||
val m3u8Response = runBlocking {app.get(secondSelection.streamUrl, headers = headers).text}
|
val m3u8Response =
|
||||||
|
runBlocking { app.get(secondSelection.streamUrl, headers = headers).text }
|
||||||
|
|
||||||
var encryptionUri: String?
|
var encryptionUri: String?
|
||||||
var encryptionIv = byteArrayOf()
|
var encryptionIv = byteArrayOf()
|
||||||
|
@ -166,7 +212,8 @@ class M3u8Helper {
|
||||||
}
|
}
|
||||||
|
|
||||||
encryptionIv = match.component3().toByteArray()
|
encryptionIv = match.component3().toByteArray()
|
||||||
val encryptionKeyResponse = runBlocking { app.get(encryptionUri, headers = headers) }
|
val encryptionKeyResponse =
|
||||||
|
runBlocking { app.get(encryptionUri, headers = headers) }
|
||||||
encryptionData = encryptionKeyResponse.body?.bytes() ?: byteArrayOf()
|
encryptionData = encryptionKeyResponse.body?.bytes() ?: byteArrayOf()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue