From 55db4c2c1b1916d3af68a327347528375846d42b Mon Sep 17 00:00:00 2001 From: hexated Date: Sat, 21 Jan 2023 13:25:04 +0700 Subject: [PATCH] [Sora] added smashyStream --- SoraStream/build.gradle.kts | 2 +- .../main/kotlin/com/hexated/SoraExtractor.kt | 33 +++++++++ .../src/main/kotlin/com/hexated/SoraStream.kt | 5 ++ .../src/main/kotlin/com/hexated/SoraUtils.kt | 68 +++++++++++++++++-- 4 files changed, 103 insertions(+), 5 deletions(-) diff --git a/SoraStream/build.gradle.kts b/SoraStream/build.gradle.kts index 2c00a686..f128b70c 100644 --- a/SoraStream/build.gradle.kts +++ b/SoraStream/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 75 +version = 76 cloudstream { diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt index 98411b82..b27af6ea 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt @@ -1999,6 +1999,29 @@ object SoraExtractor : SoraStream() { } + suspend fun invokeSmashyStream( + id: Int? = null, + season: Int? = null, + episode: Int? = null, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit, + ) { + val url = if (season == null) { + "$smashyStreamAPI/playere.php?tmdb=$id" + } else { + "$smashyStreamAPI/playere.php?tmdb=$id&season=$season&episode=$episode" + } + app.get(url).document.select("div.dropdown.servers a").map { + it.text() to it.attr("data-id") + }.apmap { (server, link) -> + when (val player = server.replace("Server", "Player").trim()) { + "Player 1" -> invokeSmashy1(player, link, subtitleCallback, callback) + "Player 2" -> invokeSmashy2(player, link, callback) + else -> return@apmap null + } + } + } + } class StreamM4u : XStreamCdn() { @@ -2267,4 +2290,14 @@ data class KamyrollAnimes( data class KamyrollToken( @JsonProperty("access_token") val access_token: String? = null, @JsonProperty("token_type") val token_type: String? = null, +) + +data class Smashy1Tracks( + @JsonProperty("file") val file: String? = null, + @JsonProperty("label") val label: String? = null, +) + +data class Smashy1Source( + @JsonProperty("file") val file: String? = null, + @JsonProperty("tracks") val tracks: ArrayList? = arrayListOf(), ) \ No newline at end of file diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt index 8bb3fd46..cfdc659e 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt @@ -32,6 +32,7 @@ import com.hexated.SoraExtractor.invokeMovie123 import com.hexated.SoraExtractor.invokeMoviesbay import com.hexated.SoraExtractor.invokeMoviezAdd import com.hexated.SoraExtractor.invokeRStream +import com.hexated.SoraExtractor.invokeSmashyStream import com.hexated.SoraExtractor.invokeSoraStream import com.hexated.SoraExtractor.invokeTvMovies import com.hexated.SoraExtractor.invokeUhdmovies @@ -103,6 +104,7 @@ open class SoraStream : TmdbProvider() { const val flixonAPI = "https://flixon.ru" const val animeKaizokuAPI = "https://animekaizoku.com" const val movie123NetAPI = "https://ww7.0123movie.net" + const val smashyStreamAPI = "https://embed.smashystream.com" fun getType(t: String?): TvType { return when (t) { @@ -525,6 +527,9 @@ open class SoraStream : TmdbProvider() { { invokeMovie123(res.title, res.season, res.episode, subtitleCallback, callback) }, + { + invokeSmashyStream(res.id, res.season, res.episode, subtitleCallback, callback) + } ) return true diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt b/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt index fa34422a..453287da 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt @@ -6,15 +6,13 @@ import com.hexated.SoraStream.Companion.gdbot import com.hexated.SoraStream.Companion.kamyrollAPI import com.hexated.SoraStream.Companion.tvMoviesAPI import com.lagradost.cloudstream3.APIHolder.getCaptchaToken +import com.lagradost.cloudstream3.SubtitleFile import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.base64Decode import com.lagradost.cloudstream3.base64Encode import com.lagradost.cloudstream3.network.WebViewResolver +import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson -import com.lagradost.cloudstream3.utils.ExtractorLink -import com.lagradost.cloudstream3.utils.Qualities -import com.lagradost.cloudstream3.utils.SubtitleHelper -import com.lagradost.cloudstream3.utils.getQualityFromName import com.lagradost.nicehttp.NiceResponse import com.lagradost.nicehttp.RequestBodyTypes import com.lagradost.nicehttp.requestCreator @@ -278,6 +276,68 @@ suspend fun extractCovyn(url: String?): Pair? { return Pair(videoLink, size) } +suspend fun invokeSmashy1( + player: String, + url: String?, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit, +) { + val doc = app.get(url ?: return).document + val script = doc.selectFirst("script:containsData(secret)")?.data() ?: return + val secret = script.substringAfter("secret = \"").substringBefore("\";").let { base64Decode(it) } + val key = script.substringAfter("token = \"").substringBefore("\";") + val source = app.get( + "$secret$key", + headers = mapOf( + "Accept" to "application/json, text/javascript, */*; q=0.01", + "X-Requested-With" to "XMLHttpRequest" + ) + ).parsedSafe() ?: return + + val videoUrl = base64Decode(source.file ?: return) + if(videoUrl.contains(".m3u8")) { + M3u8Helper.generateM3u8( + "Smashy ($player)", + videoUrl, + "" + ).forEach(callback) + source.tracks?.map { sub -> + subtitleCallback.invoke( + SubtitleFile( + sub.label ?: return@map null, + sub.file ?: return@map null + ) + ) + } + } else { + return + } +} + +suspend fun invokeSmashy2( + player: String, + url: String?, + callback: (ExtractorLink) -> Unit, +) { + val base = getBaseUrl(url ?: return) + val doc = app.get(url).document + val script = doc.selectFirst("script:containsData(playlist:)")?.data() ?: return + Regex("""file:[\n\s]+?"(\S+?.m3u8)",[\n\s]+label:"(\S+)",""").findAll(script).map { + it.groupValues[1] to it.groupValues[2] + }.toList().map { (link, quality) -> + callback.invoke( + ExtractorLink( + "Smashy ($player)", + "Smashy ($player)", + link, + base, + quality.toIntOrNull() ?: Qualities.Unknown.value, + isM3u8 = link.contains(".m3u8"), + ) + ) + } +} + fun getDirectGdrive(url: String): String { return if (url.contains("&export=download")) { url