diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt index 7e9a9d02..8aff2b49 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt @@ -86,6 +86,7 @@ object APIHolder { TheFlixToProvider(), StreamingcommunityProvider(), TantifilmProvider(), + HDMovie5(), // Metadata providers //TmdbProvider(), diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/BullStream.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/BullStream.kt new file mode 100644 index 00000000..d4f87f4c --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/BullStream.kt @@ -0,0 +1,29 @@ +package com.lagradost.cloudstream3.extractors + +import com.lagradost.cloudstream3.app +import com.lagradost.cloudstream3.utils.ExtractorApi +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.M3u8Helper + +class BullStream : ExtractorApi() { + override val name = "BullStream" + override val mainUrl = "https://bullstream.xyz" + override val requiresReferer = false + val regex = Regex("(?<=sniff\\()(.*)(?=\\)\\);)") + + override suspend fun getUrl(url: String, referer: String?): List? { + val data = regex.find(app.get(url).text)?.value + ?.replace("\"", "") + ?.split(",") + ?: return null + + val m3u8 = "$mainUrl/m3u8/${data[1]}/${data[2]}/master.txt?s=1&cache=${data[4]}" + println("shiv : $m3u8") + return M3u8Helper.generateM3u8( + name, + m3u8, + url, + headers = mapOf("referer" to url, "accept" to "*/*") + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/DoodExtractor.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/DoodExtractor.kt index b3b0d702..71a11d60 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/DoodExtractor.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/DoodExtractor.kt @@ -6,6 +6,14 @@ import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.Qualities import kotlinx.coroutines.delay +class DoodCxExtractor : DoodLaExtractor() { + override var mainUrl = "https://dood.cx" +} + +class DoodPmExtractor : DoodLaExtractor() { + override var mainUrl = "https://dood.pm" +} + class DoodToExtractor : DoodLaExtractor() { override var mainUrl = "https://dood.to" } diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/GMPlayer.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/GMPlayer.kt new file mode 100644 index 00000000..4bbff386 --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/GMPlayer.kt @@ -0,0 +1,39 @@ +package com.lagradost.cloudstream3.extractors + +import com.lagradost.cloudstream3.app +import com.lagradost.cloudstream3.utils.ExtractorApi +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.M3u8Helper + +class GMPlayer : ExtractorApi() { + override val name = "GM Player" + override val mainUrl = "https://gmplayer.xyz" + override val requiresReferer = true + + override suspend fun getUrl(url: String, referer: String?): List? { + val ref = referer ?: return null + val id = url.substringAfter("/video/").substringBefore("/") + + val m3u8 = app.post( + "$mainUrl/player/index.php?data=$id&do=getVideo", + mapOf( + "accept" to "*/*", + "referer" to ref, + "x-requested-with" to "XMLHttpRequest", + "origin" to mainUrl + ), + data = mapOf("hash" to id, "r" to ref) + ).also { println("shiv " + it.text) }.parsed().videoSource ?: return null + + return M3u8Helper.generateM3u8( + name, + m3u8, + ref, + headers = mapOf("accept" to "*/*") + ) + } + + private data class GmResponse( + val videoSource: String? = null + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/MixDrop.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/MixDrop.kt index 9b3f3847..e7ddd180 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/MixDrop.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/MixDrop.kt @@ -3,7 +3,15 @@ package com.lagradost.cloudstream3.extractors import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.utils.* -class MixDrop : ExtractorApi() { +class MixDropBz : MixDrop(){ + override var mainUrl = "https://mixdrop.bz" +} + +class MixDropCh : MixDrop(){ + override var mainUrl = "https://mixdrop.ch" +} + +open class MixDrop : ExtractorApi() { override var name = "MixDrop" override var mainUrl = "https://mixdrop.co" private val srcRegex = Regex("""wurl.*?=.*?"(.*?)";""") diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/OkRuExtractor.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/OkRuExtractor.kt index c3b6a023..70e87fbf 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/OkRuExtractor.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/OkRuExtractor.kt @@ -24,6 +24,10 @@ data class Videos ( @JsonProperty("disallowed") var disallowed : Boolean? = null ) +class OkRuHttps: OkRu(){ + override var mainUrl = "https://ok.ru" +} + open class OkRu : ExtractorApi() { override var name = "Okru" override var mainUrl = "http://ok.ru" diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/HDMovie5.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/HDMovie5.kt new file mode 100644 index 00000000..9001f2c2 --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/HDMovie5.kt @@ -0,0 +1,154 @@ +package com.lagradost.cloudstream3.movieproviders + +import com.fasterxml.jackson.annotation.JsonProperty +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.httpsify +import com.lagradost.cloudstream3.utils.loadExtractor +import okhttp3.Interceptor +import org.jsoup.Jsoup + +class HDMovie5 : MainAPI() { + override var mainUrl = "https://hdmovie5.tv" + override var name = "HDMovie" + override val lang = "hi" + + override val hasQuickSearch = true + override val hasMainPage = true + override val supportedTypes = setOf( + TvType.Movie, + TvType.TvSeries, + ) + + override suspend fun getMainPage(): HomePageResponse { + val doc = app.get(mainUrl).document.select("div.content") + val list = mapOf( + "Featured Movies" to "featured", + "Updated Movies" to "normal" + ) + return HomePageResponse(list.map { item -> + HomePageList(item.key, + doc.select("div.${item.value}>.item").map { + val data = it.select(".data") + val a = data.select("a") + MovieSearchResponse( + a.text(), + a.attr("href"), + this.name, + TvType.Movie, + it.select("img").attr("src"), + data.select("span").text().toIntOrNull() + ) + } + ) + }) + } + + private data class QuickSearchResponse( + val title: String, + val url: String, + val img: String, + val extra: Extra + ) { + data class Extra( + val date: String + ) + } + + override suspend fun quickSearch(query: String): List { + return app.get("$mainUrl/wp-json/dooplay/search/?keyword=$query&nonce=ddbde04d9c") + .parsed>().map { + val res = it.value + MovieSearchResponse( + res.title, + res.url, + this.name, + TvType.Movie, + res.img, + res.extra.date.toIntOrNull() + ) + } + } + + override suspend fun search(query: String): List { + return app.get("$mainUrl/?s=$query").document.select(".search-page>div.result-item").map { + val image = it.select(".image") + MovieSearchResponse( + image.select("img").attr("alt"), + image.select("a").attr("href"), + this.name, + TvType.Movie, + image.select("img").attr("src"), + it.select(".year").text().toIntOrNull() + ) + } + } + + override suspend fun load(url: String): LoadResponse { + val doc = app.get(url).document + val info = doc.select(".sheader") + val links = doc.select("#playeroptionsul>li") + val data = links.joinToString(",") { it.attr("data-post") } + return MovieLoadResponse( + info.select(".data>h1").text(), + url, + this.name, + TvType.Movie, + data, + info.select(".poster>img").attr("src"), + info.select(".date").text().substringAfter(", ").toIntOrNull(), + doc.select(".wp-content>p").let { it.getOrNull(it.size - 1)?.text() }, + (doc.select("#repimdb>strong").text().toFloatOrNull()?.times(1000))?.toInt(), + info.select(".sgeneros>a").map { it.text() }, + info.select(".runtime").text().substringBefore(" Min.").toIntOrNull(), + null, + doc.select("#single_relacionados>article>a").map { + val img = it.select("img") + MovieSearchResponse( + img.attr("alt"), + it.attr("href"), + this.name, + TvType.Movie, + img.attr("src") + ) + }, + doc.select("#cast>.persons>.person").mapNotNull { + if (it.attr("itemprop") != "director") { + ActorData( + Actor( + it.select("meta").attr("content"), + it.select("img").attr("src") + ) + ) + } else null + }, + ) + } + + private data class PlayerAjaxResponse( + @JsonProperty("embed_url") + val embedURL: String? = null + ) + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + return data.split(",").apmapIndexed { index, it -> + val html = app.post( + "$mainUrl/wp-admin/admin-ajax.php", + data = mapOf( + "action" to "doo_player_ajax", + "post" to it, + "nume" to "${index + 1}", + "type" to "movie" + ) + ).parsed().embedURL ?: return@apmapIndexed false + val doc = Jsoup.parse(html) + val link = doc.select("iframe").attr("src") + loadExtractor(httpsify(link), "$mainUrl/",callback) + }.contains(true) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt index 7d071a81..983adf36 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt @@ -5,6 +5,7 @@ import com.lagradost.cloudstream3.TvType import com.lagradost.cloudstream3.USER_AGENT import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.extractors.* +import com.lagradost.cloudstream3.extractors.BullStream import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall import kotlinx.coroutines.delay import org.jsoup.Jsoup @@ -119,9 +120,15 @@ val extractorApis: Array = arrayOf( VizcloudDigital(), Mp4Upload(), StreamTape(), + + //mixdrop extractors + MixDropBz(), + MixDropCh(), MixDrop(), + Mcloud(), XStreamCdn(), + StreamSB(), StreamSB1(), StreamSB2(), @@ -150,8 +157,11 @@ val extractorApis: Array = arrayOf( Tomatomatela(), Cinestart(), OkRu(), + OkRuHttps(), // dood extractors + DoodCxExtractor(), + DoodPmExtractor(), DoodToExtractor(), DoodSoExtractor(), DoodLaExtractor(), @@ -172,6 +182,9 @@ val extractorApis: Array = arrayOf( // SBPlay2(), PlayerVoxzer(), + + BullStream(), + GMPlayer() ) fun getExtractorApiFromName(name: String): ExtractorApi {