add stream support for catalog addons
This commit is contained in:
parent
a624eacbbe
commit
d778515969
|
@ -2,11 +2,10 @@ package com.lagradost
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
|
import com.lagradost.cloudstream3.utils.*
|
||||||
|
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.toJson
|
import com.lagradost.cloudstream3.utils.AppUtils.toJson
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
|
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
|
||||||
import com.lagradost.cloudstream3.utils.Qualities
|
|
||||||
import com.lagradost.cloudstream3.utils.loadExtractor
|
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import java.net.URLEncoder
|
import java.net.URLEncoder
|
||||||
|
|
||||||
|
@ -15,10 +14,20 @@ private const val TRACKER_LIST_URL =
|
||||||
|
|
||||||
class StremioProvider : MainAPI() {
|
class StremioProvider : MainAPI() {
|
||||||
override var mainUrl = "https://stremio.github.io/stremio-static-addon-example"
|
override var mainUrl = "https://stremio.github.io/stremio-static-addon-example"
|
||||||
|
|
||||||
|
/** add this as default stream because we don't support torrent yet
|
||||||
|
and this add ons is the best for http stream */
|
||||||
|
private var streamUrl = "https://2ecbbd610840-cinestream.baby-beamup.club"
|
||||||
|
|
||||||
override var name = "Stremio example"
|
override var name = "Stremio example"
|
||||||
override val supportedTypes = setOf(TvType.Others)
|
override val supportedTypes = setOf(TvType.Others)
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
|
|
||||||
|
// check if id is imdb/tmdb cause stremio addons like torrentio works base on imdbId
|
||||||
|
private fun isImdborTmdb(url: String?): Boolean {
|
||||||
|
return imdbUrlToIdNullable(url) != null || url?.startsWith("tmdb:") == true
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse? {
|
override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse? {
|
||||||
val res = tryParseJson<Manifest>(app.get("${mainUrl}/manifest.json").text) ?: return null
|
val res = tryParseJson<Manifest>(app.get("${mainUrl}/manifest.json").text) ?: return null
|
||||||
val lists = mutableListOf<HomePageList>()
|
val lists = mutableListOf<HomePageList>()
|
||||||
|
@ -43,8 +52,9 @@ class StremioProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun load(url: String): LoadResponse? {
|
override suspend fun load(url: String): LoadResponse? {
|
||||||
val res = tryParseJson<CatalogEntry>(url) ?: throw RuntimeException(url)
|
val res = parseJson<CatalogEntry>(url)
|
||||||
val json = app.get("${mainUrl}/meta/${res.type}/${res.id}.json").parsedSafe<CatalogResponse>()?.meta ?: throw RuntimeException(url)
|
val json = app.get("${mainUrl}/meta/${res.type}/${res.id}.json").parsedSafe<CatalogResponse>()?.meta ?: throw RuntimeException(url)
|
||||||
|
isMetaId = isImdborTmdb(res.id)
|
||||||
return json.toLoadResponse(this)
|
return json.toLoadResponse(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +126,7 @@ class StremioProvider : MainAPI() {
|
||||||
) {
|
) {
|
||||||
fun toSearchResponse(provider: StremioProvider): SearchResponse {
|
fun toSearchResponse(provider: StremioProvider): SearchResponse {
|
||||||
return provider.newMovieSearchResponse(
|
return provider.newMovieSearchResponse(
|
||||||
name,
|
fixTitle(name),
|
||||||
this.toJson(),
|
this.toJson(),
|
||||||
TvType.Others
|
TvType.Others
|
||||||
) {
|
) {
|
||||||
|
@ -130,7 +140,7 @@ class StremioProvider : MainAPI() {
|
||||||
name,
|
name,
|
||||||
"${provider.mainUrl}/meta/${type}/${id}.json",
|
"${provider.mainUrl}/meta/${type}/${id}.json",
|
||||||
TvType.Others,
|
TvType.Others,
|
||||||
"${provider.mainUrl}/stream/${type}/${id}.json"
|
if(isMetaId) "${provider.streamUrl}/stream/${type}/${id}.json" else "${provider.mainUrl}/stream/${type}/${id}.json"
|
||||||
) {
|
) {
|
||||||
posterUrl = poster
|
posterUrl = poster
|
||||||
plot = description
|
plot = description
|
||||||
|
@ -159,26 +169,36 @@ class StremioProvider : MainAPI() {
|
||||||
val overview: String?
|
val overview: String?
|
||||||
) {
|
) {
|
||||||
fun toEpisode(provider: StremioProvider, type: String?): Episode {
|
fun toEpisode(provider: StremioProvider, type: String?): Episode {
|
||||||
|
val ids = id.split(":")
|
||||||
return provider.newEpisode(
|
return provider.newEpisode(
|
||||||
"${provider.mainUrl}/stream/${type}/${id}.json"
|
if(isMetaId) "${provider.streamUrl}/stream/${type}/${id}.json" else "${provider.mainUrl}/stream/${type}/${id}.json"
|
||||||
) {
|
) {
|
||||||
this.name = title
|
this.name = title
|
||||||
this.posterUrl = thumbnail
|
this.posterUrl = thumbnail
|
||||||
this.description = overview
|
this.description = overview
|
||||||
|
this.episode = ids.lastOrNull()?.toIntOrNull()
|
||||||
|
this.season = ids.getOrNull(ids.lastIndex - 1)?.toIntOrNull()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class StreamsResponse(val streams: List<Stream>)
|
private data class StreamsResponse(val streams: List<Stream>)
|
||||||
|
private data class Subtitle(
|
||||||
|
val url: String?,
|
||||||
|
val lang: String?,
|
||||||
|
val id: String?,
|
||||||
|
)
|
||||||
private data class Stream(
|
private data class Stream(
|
||||||
val name: String?,
|
val name: String?,
|
||||||
val title: String?,
|
val title: String?,
|
||||||
val url: String?,
|
val url: String?,
|
||||||
|
val description: String?,
|
||||||
val ytId: String?,
|
val ytId: String?,
|
||||||
val externalUrl: String?,
|
val externalUrl: String?,
|
||||||
val behaviorHints: JSONObject?,
|
val behaviorHints: JSONObject?,
|
||||||
val infoHash: String?,
|
val infoHash: String?,
|
||||||
val sources: List<String> = emptyList()
|
val sources: List<String> = emptyList(),
|
||||||
|
val subtitles: List<Subtitle> = emptyList()
|
||||||
) {
|
) {
|
||||||
suspend fun runCallback(
|
suspend fun runCallback(
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
|
@ -202,7 +222,7 @@ class StremioProvider : MainAPI() {
|
||||||
title ?: name ?: "",
|
title ?: name ?: "",
|
||||||
url,
|
url,
|
||||||
referer ?: "",
|
referer ?: "",
|
||||||
Qualities.Unknown.value,
|
getQualityFromName(description),
|
||||||
isM3u8 = true
|
isM3u8 = true
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -218,6 +238,14 @@ class StremioProvider : MainAPI() {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
subtitles.map { sub ->
|
||||||
|
subtitleCallback.invoke(
|
||||||
|
SubtitleFile(
|
||||||
|
SubtitleHelper.fromThreeLettersToLanguage(sub.lang ?: "") ?: sub.lang ?: "",
|
||||||
|
sub.url ?: return@map
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ytId != null) {
|
if (ytId != null) {
|
||||||
loadExtractor("https://www.youtube.com/watch?v=$ytId", subtitleCallback, callback)
|
loadExtractor("https://www.youtube.com/watch?v=$ytId", subtitleCallback, callback)
|
||||||
|
@ -252,6 +280,7 @@ class StremioProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private var isMetaId = false
|
||||||
fun String.encodeUri(): String = URLEncoder.encode(this, "utf8")
|
fun String.encodeUri(): String = URLEncoder.encode(this, "utf8")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue