diff --git a/GDJioTVProvider/build.gradle.kts b/GDJioTVProvider/build.gradle.kts index 4b92f98..c20c7aa 100644 --- a/GDJioTVProvider/build.gradle.kts +++ b/GDJioTVProvider/build.gradle.kts @@ -15,7 +15,7 @@ cloudstream { * 2: Slow * 3: Beta only * */ - status = 1 // will be 3 if unspecified + status = 0 // will be 3 if unspecified tvTypes = listOf( "Live", ) diff --git a/NPJioTVProvider/build.gradle.kts b/NPJioTVProvider/build.gradle.kts index f5f3c77..995f0a0 100644 --- a/NPJioTVProvider/build.gradle.kts +++ b/NPJioTVProvider/build.gradle.kts @@ -15,7 +15,7 @@ cloudstream { * 2: Slow * 3: Beta only * */ - status = 1 // will be 3 if unspecified + status = 0 // will be 3 if unspecified tvTypes = listOf( "Live", ) diff --git a/SnehIPTVProvider/build.gradle.kts b/SnehIPTVProvider/build.gradle.kts index 30000d6..0472067 100644 --- a/SnehIPTVProvider/build.gradle.kts +++ b/SnehIPTVProvider/build.gradle.kts @@ -15,7 +15,7 @@ cloudstream { * 2: Slow * 3: Beta only * */ - status = 1 // will be 3 if unspecified + status = 0 // will be 3 if unspecified tvTypes = listOf( "Live", ) diff --git a/SoraJioTVProvider/build.gradle.kts b/SoraJioTVProvider/build.gradle.kts new file mode 100644 index 0000000..72df214 --- /dev/null +++ b/SoraJioTVProvider/build.gradle.kts @@ -0,0 +1,24 @@ +version = 1 + + +cloudstream { + language = "hi" + // All of these properties are optional, you can safely remove them + + description = " JioTV streams from different available sources" + authors = listOf("darkdemon") + + /** + * Status int as the following: + * 0: Down + * 1: Ok + * 2: Slow + * 3: Beta only + * */ + status = 1 // will be 3 if unspecified + tvTypes = listOf( + "Live", + ) + + iconUrl = "https://www.google.com/s2/favicons?domain=jiotv.com&sz=%size%" +} diff --git a/SoraJioTVProvider/src/main/AndroidManifest.xml b/SoraJioTVProvider/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7fbfe5f --- /dev/null +++ b/SoraJioTVProvider/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/SoraJioTVProvider/src/main/kotlin/com/darkdemon/SoraJioTVExtractor.kt b/SoraJioTVProvider/src/main/kotlin/com/darkdemon/SoraJioTVExtractor.kt new file mode 100644 index 0000000..271b34e --- /dev/null +++ b/SoraJioTVProvider/src/main/kotlin/com/darkdemon/SoraJioTVExtractor.kt @@ -0,0 +1,145 @@ +package com.darkdemon + +import com.lagradost.cloudstream3.app +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.Qualities + + +// credits: hexated +// +object SoraJioTVExtractor: SoraJioTVProvider() { + + suspend fun invokeNP( + id: Int? = null, + callback: (ExtractorLink) -> Unit + ){ + val document = app.get("$NPJioTV/play.php?id=$id").document + val link = "$NPJioTV/${document.selectFirst("source")?.attr("src")}" + callback.invoke( + ExtractorLink( + this.name, + "NPJioTV", + link, + referer = "", + quality = Qualities.Unknown.value, + isM3u8 = true, + ) + ) + } + suspend fun invokeS( + id: Int? = null, + callback: (ExtractorLink) -> Unit + ){ + val document = app.get("$SJioTV/play.php?id=$id").document + val link = "$SJioTV/${document.selectFirst("source")?.attr("src")}" + callback.invoke( + ExtractorLink( + this.name, + "SJioTV", + link, + referer = "", + quality = Qualities.Unknown.value, + isM3u8 = true, + ) + ) + } + + fun invokeGDL( + id: String? = null, + callback: (ExtractorLink) -> Unit + ){ + val link = "$GDLJioTV/autoq.php?c=$id" + callback.invoke( + ExtractorLink( + this.name, + "GDLJioTV", + link, + referer = "", + quality = Qualities.Unknown.value, + isM3u8 = true, + ) + ) + } + + fun invokeI( + id: String? = null, + callback: (ExtractorLink) -> Unit + ){ + val link = "$IJioTV/https://epic-austin.128-199-17-57.plesk.page/$id" + callback.invoke( + ExtractorLink( + this.name, + "IJioTV", + link, + referer = "", + quality = Qualities.Unknown.value, + isM3u8 = true, + ) + ) + } + + fun invokeFS( + id: String? = null, + callback: (ExtractorLink) -> Unit + ){ + val link = "$FSJioTV/autoq.php?c=$id" + callback.invoke( + ExtractorLink( + this.name, + "FSJioTV", + link, + referer = "", + quality = Qualities.Unknown.value, + isM3u8 = true, + ) + ) + } + fun invokeFH( + id: String? = null, + callback: (ExtractorLink) -> Unit + ){ + val link = "$FHJioTV/autoq.php?c=$id" + callback.invoke( + ExtractorLink( + this.name, + "FHJioTV", + link, + referer = "", + quality = Qualities.Unknown.value, + isM3u8 = true, + ) + ) + } + fun invokeTS( + id: String? = null, + callback: (ExtractorLink) -> Unit + ){ + val link = "$TSJioTV/jtv/autoqtv.php?c=$id" + callback.invoke( + ExtractorLink( + this.name, + "TSJioTV", + link, + referer = "", + quality = Qualities.Unknown.value, + isM3u8 = true, + ) + ) + } + fun invokeRPK( + id: String? = null, + callback: (ExtractorLink) -> Unit + ){ + val link = "$RPKJioTV/JIOTVx/autoq.php?c=$id" + callback.invoke( + ExtractorLink( + this.name, + "RPKJioTV", + link, + referer = "", + quality = Qualities.Unknown.value, + isM3u8 = true, + ) + ) + } +} \ No newline at end of file diff --git a/SoraJioTVProvider/src/main/kotlin/com/darkdemon/SoraJioTVPlugin.kt b/SoraJioTVProvider/src/main/kotlin/com/darkdemon/SoraJioTVPlugin.kt new file mode 100644 index 0000000..5d3e1cf --- /dev/null +++ b/SoraJioTVProvider/src/main/kotlin/com/darkdemon/SoraJioTVPlugin.kt @@ -0,0 +1,13 @@ +package com.darkdemon + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class SoraJioTVPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(SoraJioTVProvider()) + } +} diff --git a/SoraJioTVProvider/src/main/kotlin/com/darkdemon/SoraJioTVProvider.kt b/SoraJioTVProvider/src/main/kotlin/com/darkdemon/SoraJioTVProvider.kt new file mode 100644 index 0000000..6afa96c --- /dev/null +++ b/SoraJioTVProvider/src/main/kotlin/com/darkdemon/SoraJioTVProvider.kt @@ -0,0 +1,194 @@ +package com.darkdemon + +import com.darkdemon.SoraJioTVExtractor.invokeFH +import com.darkdemon.SoraJioTVExtractor.invokeFS +import com.darkdemon.SoraJioTVExtractor.invokeGDL +import com.darkdemon.SoraJioTVExtractor.invokeI +import com.fasterxml.jackson.annotation.JsonProperty +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.utils.AppUtils.parseJson +import com.lagradost.cloudstream3.utils.AppUtils.toJson +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.darkdemon.SoraJioTVExtractor.invokeNP +import com.darkdemon.SoraJioTVExtractor.invokeRPK +import com.darkdemon.SoraJioTVExtractor.invokeS +import com.darkdemon.SoraJioTVExtractor.invokeTS + +open class SoraJioTVProvider : MainAPI() { // all providers must be an instance of MainAPI + override var name = "SoraJioTV" + override val hasMainPage = true + override val hasChromecastSupport = true + override var lang = "hi" + override val supportedTypes = setOf( + TvType.Live + ) + + data class Channels( + @JsonProperty("result") var result: ArrayList = arrayListOf() + ) + + data class Result( + @JsonProperty("channel_id") var channelId: Int? = null, + @JsonProperty("channel_order") var channelOrder: String? = null, + @JsonProperty("channel_name") var channelName: String? = null, + @JsonProperty("channelCategoryId") var channelCategoryId: Int? = null, + @JsonProperty("channelLanguageId") var channelLanguageId: Int? = null, + @JsonProperty("isHD") var isHD: Boolean? = null, + @JsonProperty("broadcasterId") var broadcasterId: Int? = null, + @JsonProperty("logoUrl") var logoUrl: String? = null + + ) + + companion object { + private const val jsonUrl = + "https://raw.githubusercontent.com/daarkdemon/jiotvchannels/main/channels.json" + const val NPJioTV = "https://nayeemparvez.chadasaniya.cf" + const val GDLJioTV = "https://tv.googledrivelinks.com" + const val IJioTV = "https://epic-austin.128-199-17-57.plesk.page" + const val SJioTV = "https://the-nayeemparvez.ml" + const val FSJioTV = "https://tv.freeseries.eu.org" + const val FHJioTV = "https://filmyhub.ga" + const val TSJioTV = "https://tvstream.fun" + const val RPKJioTV = "http://ranapk-nxt.ml" + } + + override suspend fun getMainPage( + page: Int, + request: MainPageRequest + ): HomePageResponse { + val categories = mapOf( + "Sports" to 8, + "Entertainment" to 5, + "Movies" to 6, + "News" to 12, + "Music" to 13, + "Kids" to 7, + "Lifestyle" to 9, + "Infotainment" to 10, + "Devotional" to 15, + "Business" to 16, + "Educational" to 17, + "Shopping" to 18, + "JioDarshan" to 19 + ) + val items = ArrayList() + val response = app.get(jsonUrl).parsed().result + categories.forEach { cat -> + val results: MutableList = mutableListOf() + val filtered = response.filter { it.channelCategoryId == cat.value } + filtered.forEach { + val title = it.channelName.toString() + val posterUrl = "http://jiotv.catchup.cdn.jio.com/dare_images/images/${it.logoUrl}" + val quality = if (it.isHD == true) "HD" else "" + results.add( + newMovieSearchResponse(title, title, TvType.Live) { + this.posterUrl = posterUrl + this.quality = getQualityFromString(quality) + } + ) + } + items.add( + HomePageList( + capitalizeString(cat.key), + results, + isHorizontalImages = true + ) + ) + } + return HomePageResponse(items) + } + + override suspend fun search(query: String): List { + val response = app.get(jsonUrl).parsed().result + val searchResults = + response.filter { it.channelName?.lowercase()?.contains(query.lowercase()) == true } + + return searchResults.map { + val title = it.channelName.toString() + val posterUrl = "http://jiotv.catchup.cdn.jio.com/dare_images/images/${it.logoUrl}" + newMovieSearchResponse(title, title, TvType.Live) { + this.posterUrl = posterUrl + } + } + } + + override suspend fun load(url: String): LoadResponse { + val response = app.get(jsonUrl).parsed().result + val searchResults = + response.filter { it.channelName?.contains(url.substringAfterLast("/")) == true } + val title = searchResults[0].channelName.toString() + val posterUrl = + "http://jiotv.catchup.cdn.jio.com/dare_images/images/${searchResults[0].logoUrl}" + return newMovieLoadResponse( + title, title, TvType.Live, Result( + channelId = searchResults[0].channelId, + channelName = title, + logoUrl = searchResults[0].logoUrl + ).toJson() + ) { + this.posterUrl = posterUrl + } + } + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + + val result = parseJson(data) + argamap( + { + invokeNP( + result.channelId, + callback + ) + }, + { + invokeS( + result.channelId, + callback + ) + }, + { + invokeGDL( + result.logoUrl?.substringBefore(".png"), + callback + ) + }, + { + invokeI( + result.logoUrl?.substringBefore(".png"), + callback + ) + }, + { + invokeFS( + result.logoUrl?.substringBefore(".png"), + callback + ) + }, + { + invokeFH( + result.logoUrl?.substringBefore(".png"), + callback + ) + }, + { + invokeTS( + result.logoUrl?.substringBefore(".png"), + callback + ) + }, + { + invokeRPK( + result.logoUrl?.substringBefore(".png"), + callback + ) + } + ) + + return true + } +} diff --git a/SoraJioTVProvider/src/main/kotlin/com/darkdemon/SoraJioTVUtils.kt b/SoraJioTVProvider/src/main/kotlin/com/darkdemon/SoraJioTVUtils.kt new file mode 100644 index 0000000..e69de29