added some sources

This commit is contained in:
hexated 2022-10-17 11:24:09 +07:00
parent 5a21406afd
commit 6835865b6b
2 changed files with 181 additions and 72 deletions

View file

@ -0,0 +1,103 @@
package com.hexated
import android.util.Log
import com.lagradost.cloudstream3.APIHolder
import com.lagradost.cloudstream3.SubtitleFile
import com.lagradost.cloudstream3.apmap
import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.utils.AppUtils
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.Qualities
import com.lagradost.cloudstream3.utils.loadExtractor
object SoraExtractor : SoraStream() {
suspend fun invokeLocalSources(
url: String,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
) {
val doc = app.get(
url,
headers = mapOf("User-Agent" to RandomUserAgent.getRandomUserAgent())
).document
val script = doc.select("script").find { it.data().contains("\"sources\":[") }?.data()
val sourcesData = script?.substringAfter("\"sources\":[")?.substringBefore("],")
val subData = script?.substringAfter("\"subtitles\":[")?.substringBefore("],")
AppUtils.tryParseJson<List<Sources>>("[$sourcesData]")?.map { source ->
callback.invoke(
ExtractorLink(
this.name,
this.name,
source.url ?: return@map null,
"$mainServerAPI/",
source.quality?.toIntOrNull() ?: Qualities.Unknown.value,
isM3u8 = source.isM3U8,
headers = mapOf("Origin" to mainServerAPI)
)
)
}
AppUtils.tryParseJson<List<Subtitles>>("[$subData]")?.map { sub ->
subtitleCallback.invoke(
SubtitleFile(
sub.lang.toString(),
sub.url ?: return@map null
)
)
}
}
suspend fun invokeTwoEmbed(
id: Int? = null,
season: Int? = null,
episode: Int? = null,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
) {
val url = if (season == null) {
"$twoEmbedAPI/embed/tmdb/movie?id=$id"
} else {
"$twoEmbedAPI/embed/tmdb/tv?id=$id&s=$season&e=$episode"
}
val document = app.get(url).document
val captchaKey =
document.select("script[src*=https://www.google.com/recaptcha/api.js?render=]")
.attr("src").substringAfter("render=")
document.select(".dropdown-menu a[data-id]").map { it.attr("data-id") }.apmap { serverID ->
val token = APIHolder.getCaptchaToken(url, captchaKey)
app.get(
"$twoEmbedAPI/ajax/embed/play?id=$serverID&_token=$token",
referer = url
).parsedSafe<EmbedJson>()?.let { source ->
Log.i("hexated", "${source.link}")
loadExtractor(
source.link ?: return@let null,
twoEmbedAPI,
subtitleCallback,
callback
)
}
}
}
suspend fun invokeVidSrcSources(
id: Int? = null,
season: Int? = null,
episode: Int? = null,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
) {
val url = if (season == null) {
"$vidSrcAPI/embed/id=$id"
} else {
"$mainUrl/embed/$id/${season}-${episode}"
}
loadExtractor(url, null, subtitleCallback, callback)
}
}

View file

@ -3,9 +3,11 @@ package com.hexated
import android.util.Log import android.util.Log
import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.annotation.JsonProperty
import com.hexated.RandomUserAgent.getRandomUserAgent import com.hexated.RandomUserAgent.getRandomUserAgent
import com.hexated.SoraExtractor.invokeLocalSources
import com.hexated.SoraExtractor.invokeTwoEmbed
import com.hexated.SoraExtractor.invokeVidSrcSources
import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.metaproviders.TmdbProvider import com.lagradost.cloudstream3.metaproviders.TmdbProvider
import com.lagradost.cloudstream3.mvvm.safeApiCall
import com.lagradost.cloudstream3.utils.AppUtils import com.lagradost.cloudstream3.utils.AppUtils
import com.lagradost.cloudstream3.utils.AppUtils.parseJson import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.AppUtils.toJson import com.lagradost.cloudstream3.utils.AppUtils.toJson
@ -14,7 +16,7 @@ import com.lagradost.cloudstream3.utils.Qualities
import com.lagradost.cloudstream3.utils.loadExtractor import com.lagradost.cloudstream3.utils.loadExtractor
import kotlin.math.roundToInt import kotlin.math.roundToInt
class SoraStream : TmdbProvider() { open class SoraStream : TmdbProvider() {
override var name = "SoraStream" override var name = "SoraStream"
override val hasMainPage = true override val hasMainPage = true
override val hasDownloadSupport = true override val hasDownloadSupport = true
@ -31,8 +33,9 @@ class SoraStream : TmdbProvider() {
private const val tmdbAPI = "https://api.themoviedb.org/3" private const val tmdbAPI = "https://api.themoviedb.org/3"
private const val apiKey = "b030404650f279792a8d3287232358e3" // PLEASE DON'T STEAL private const val apiKey = "b030404650f279792a8d3287232358e3" // PLEASE DON'T STEAL
private var mainAPI = base64Decode("aHR0cHM6Ly94cHdhdGNoLnZlcmNlbC5hcHA=") private var mainAPI = base64Decode("aHR0cHM6Ly94cHdhdGNoLnZlcmNlbC5hcHA=")
private var mainServerAPI = base64Decode("aHR0cHM6Ly9zb3JhLW1vdmllLnZlcmNlbC5hcHA=") var mainServerAPI = base64Decode("aHR0cHM6Ly9zb3JhLW1vdmllLnZlcmNlbC5hcHA=")
private const val twoEmbedAPI = "https://www.2embed.to" const val twoEmbedAPI = "https://www.2embed.to"
const val vidSrcAPI = "https://v2.vidsrc.me"
fun getType(t: String?): TvType { fun getType(t: String?): TvType {
return when (t) { return when (t) {
@ -186,74 +189,74 @@ class SoraStream : TmdbProvider() {
} }
} }
private suspend fun invokeTwoEmbed( // private suspend fun invokeTwoEmbed(
id: Int? = null, // id: Int? = null,
season: Int? = null, // season: Int? = null,
episode: Int? = null, // episode: Int? = null,
subtitleCallback: (SubtitleFile) -> Unit, // subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit // callback: (ExtractorLink) -> Unit
) { // ) {
val url = if (season == null) { // val url = if (season == null) {
"$twoEmbedAPI/embed/tmdb/movie?id=$id" // "$twoEmbedAPI/embed/tmdb/movie?id=$id"
} else { // } else {
"$twoEmbedAPI/embed/tmdb/tv?id=$id&s=$season&e=$episode" // "$twoEmbedAPI/embed/tmdb/tv?id=$id&s=$season&e=$episode"
} // }
val document = app.get(url).document // val document = app.get(url).document
val captchaKey = // val captchaKey =
document.select("script[src*=https://www.google.com/recaptcha/api.js?render=]") // document.select("script[src*=https://www.google.com/recaptcha/api.js?render=]")
.attr("src").substringAfter("render=") // .attr("src").substringAfter("render=")
//
document.select(".dropdown-menu a[data-id]").map { it.attr("data-id") }.apmap { serverID -> // document.select(".dropdown-menu a[data-id]").map { it.attr("data-id") }.apmap { serverID ->
val token = APIHolder.getCaptchaToken(url, captchaKey) // val token = APIHolder.getCaptchaToken(url, captchaKey)
app.get( // app.get(
"$twoEmbedAPI/ajax/embed/play?id=$serverID&_token=$token", // "$twoEmbedAPI/ajax/embed/play?id=$serverID&_token=$token",
referer = url // referer = url
).parsedSafe<EmbedJson>()?.let { source -> // ).parsedSafe<EmbedJson>()?.let { source ->
Log.i("hexated", "${source.link}") // Log.i("hexated", "${source.link}")
loadExtractor( // loadExtractor(
source.link ?: return@let null, // source.link ?: return@let null,
twoEmbedAPI, // twoEmbedAPI,
subtitleCallback, // subtitleCallback,
callback // callback
) // )
} // }
} // }
} // }
//
private suspend fun invokeLocalSources( // private suspend fun invokeLocalSources(
url: String, // url: String,
subtitleCallback: (SubtitleFile) -> Unit, // subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit // callback: (ExtractorLink) -> Unit
) { // ) {
val doc = app.get(url, headers = mapOf("User-Agent" to getRandomUserAgent())).document // val doc = app.get(url, headers = mapOf("User-Agent" to getRandomUserAgent())).document
val script = doc.select("script").find { it.data().contains("\"sources\":[") }?.data() // val script = doc.select("script").find { it.data().contains("\"sources\":[") }?.data()
val sourcesData = script?.substringAfter("\"sources\":[")?.substringBefore("],") // val sourcesData = script?.substringAfter("\"sources\":[")?.substringBefore("],")
val subData = script?.substringAfter("\"subtitles\":[")?.substringBefore("],") // val subData = script?.substringAfter("\"subtitles\":[")?.substringBefore("],")
//
AppUtils.tryParseJson<List<Sources>>("[$sourcesData]")?.map { source -> // AppUtils.tryParseJson<List<Sources>>("[$sourcesData]")?.map { source ->
callback.invoke( // callback.invoke(
ExtractorLink( // ExtractorLink(
this.name, // this.name,
this.name, // this.name,
source.url ?: return@map null, // source.url ?: return@map null,
"$mainServerAPI/", // "$mainServerAPI/",
source.quality?.toIntOrNull() ?: Qualities.Unknown.value, // source.quality?.toIntOrNull() ?: Qualities.Unknown.value,
isM3u8 = source.isM3U8, // isM3u8 = source.isM3U8,
headers = mapOf("Origin" to mainServerAPI) // headers = mapOf("Origin" to mainServerAPI)
) // )
) // )
} // }
//
AppUtils.tryParseJson<List<Subtitles>>("[$subData]")?.map { sub -> // AppUtils.tryParseJson<List<Subtitles>>("[$subData]")?.map { sub ->
subtitleCallback.invoke( // subtitleCallback.invoke(
SubtitleFile( // SubtitleFile(
sub.lang.toString(), // sub.lang.toString(),
sub.url ?: return@map null // sub.url ?: return@map null
) // )
) // )
} // }
//
} // }
override suspend fun loadLinks( override suspend fun loadLinks(
data: String, data: String,
@ -311,6 +314,9 @@ class SoraStream : TmdbProvider() {
) )
} }
} }
},
{
invokeVidSrcSources(res.id, res.season, res.episode, subtitleCallback, callback)
}) })