mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
TrailersToProvider
This commit is contained in:
parent
cea1839b5c
commit
4cfb7c38c0
6 changed files with 255 additions and 46 deletions
|
@ -10,6 +10,7 @@ import com.lagradost.cloudstream3.animeproviders.ShiroProvider
|
||||||
import com.lagradost.cloudstream3.movieproviders.HDMProvider
|
import com.lagradost.cloudstream3.movieproviders.HDMProvider
|
||||||
import com.lagradost.cloudstream3.movieproviders.LookMovieProvider
|
import com.lagradost.cloudstream3.movieproviders.LookMovieProvider
|
||||||
import com.lagradost.cloudstream3.movieproviders.MeloMovieProvider
|
import com.lagradost.cloudstream3.movieproviders.MeloMovieProvider
|
||||||
|
import com.lagradost.cloudstream3.movieproviders.TrailersToProvider
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
@ -33,6 +34,7 @@ object APIHolder {
|
||||||
DubbedAnimeProvider(),
|
DubbedAnimeProvider(),
|
||||||
HDMProvider(),
|
HDMProvider(),
|
||||||
LookMovieProvider(),
|
LookMovieProvider(),
|
||||||
|
TrailersToProvider(),
|
||||||
)
|
)
|
||||||
|
|
||||||
fun getApiFromName(apiName: String?): MainAPI {
|
fun getApiFromName(apiName: String?): MainAPI {
|
||||||
|
@ -61,7 +63,7 @@ abstract class MainAPI {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun quickSearch(query: String) : ArrayList<SearchResponse>? {
|
open fun quickSearch(query: String): ArrayList<SearchResponse>? {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,23 +77,22 @@ abstract class MainAPI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun parseRating(ratingString : String?) : Int? {
|
fun parseRating(ratingString: String?): Int? {
|
||||||
if(ratingString == null) return null
|
if (ratingString == null) return null
|
||||||
val floatRating = ratingString.toFloatOrNull() ?: return null
|
val floatRating = ratingString.toFloatOrNull() ?: return null
|
||||||
return (floatRating * 10).toInt()
|
return (floatRating * 10).toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MainAPI.fixUrl(url: String): String {
|
fun MainAPI.fixUrl(url: String): String {
|
||||||
if(url.startsWith("http")) {
|
if (url.startsWith("http")) {
|
||||||
return url
|
return url
|
||||||
}
|
}
|
||||||
|
|
||||||
val startsWithNoHttp = url.startsWith("//")
|
val startsWithNoHttp = url.startsWith("//")
|
||||||
if(startsWithNoHttp) {
|
if (startsWithNoHttp) {
|
||||||
return "https:$url"
|
return "https:$url"
|
||||||
}
|
} else {
|
||||||
else {
|
if (url.startsWith('/')) {
|
||||||
if(url.startsWith('/')) {
|
|
||||||
return mainUrl + url
|
return mainUrl + url
|
||||||
}
|
}
|
||||||
return "$mainUrl/$url"
|
return "$mainUrl/$url"
|
||||||
|
@ -176,7 +177,10 @@ interface LoadResponse {
|
||||||
val posterUrl: String?
|
val posterUrl: String?
|
||||||
val year: Int?
|
val year: Int?
|
||||||
val plot: String?
|
val plot: String?
|
||||||
val rating : Int? // 0-100
|
val rating: Int? // 0-100
|
||||||
|
val tags: ArrayList<String>?
|
||||||
|
val duration: String?
|
||||||
|
val trailerUrl: String?
|
||||||
}
|
}
|
||||||
|
|
||||||
fun LoadResponse?.isEpisodeBased(): Boolean {
|
fun LoadResponse?.isEpisodeBased(): Boolean {
|
||||||
|
@ -189,7 +193,7 @@ fun LoadResponse?.isAnimeBased(): Boolean {
|
||||||
return (this.type == TvType.Anime || this.type == TvType.ONA) // && (this is AnimeLoadResponse)
|
return (this.type == TvType.Anime || this.type == TvType.ONA) // && (this is AnimeLoadResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
data class AnimeEpisode(val url: String, val name : String? = null)
|
data class AnimeEpisode(val url: String, val name: String? = null)
|
||||||
|
|
||||||
data class AnimeLoadResponse(
|
data class AnimeLoadResponse(
|
||||||
val engName: String?,
|
val engName: String?,
|
||||||
|
@ -207,12 +211,14 @@ data class AnimeLoadResponse(
|
||||||
val showStatus: ShowStatus?,
|
val showStatus: ShowStatus?,
|
||||||
|
|
||||||
override val plot: String?,
|
override val plot: String?,
|
||||||
val tags: ArrayList<String>? = null,
|
override val tags: ArrayList<String>? = null,
|
||||||
val synonyms: ArrayList<String>? = null,
|
val synonyms: ArrayList<String>? = null,
|
||||||
|
|
||||||
val malId: Int? = null,
|
val malId: Int? = null,
|
||||||
val anilistId: Int? = null,
|
val anilistId: Int? = null,
|
||||||
override val rating: Int? = null,
|
override val rating: Int? = null,
|
||||||
|
override val duration: String? = null,
|
||||||
|
override val trailerUrl: String? = null,
|
||||||
) : LoadResponse
|
) : LoadResponse
|
||||||
|
|
||||||
data class MovieLoadResponse(
|
data class MovieLoadResponse(
|
||||||
|
@ -226,11 +232,23 @@ data class MovieLoadResponse(
|
||||||
override val year: Int?,
|
override val year: Int?,
|
||||||
override val plot: String?,
|
override val plot: String?,
|
||||||
|
|
||||||
val imdbId: Int?,
|
val imdbUrl: String?,
|
||||||
override val rating: Int? = null,
|
override val rating: Int? = null,
|
||||||
|
override val tags: ArrayList<String>? = null,
|
||||||
|
override val duration: String? = null,
|
||||||
|
override val trailerUrl: String? = null,
|
||||||
) : LoadResponse
|
) : LoadResponse
|
||||||
|
|
||||||
data class TvSeriesEpisode(val name: String?, val season: Int?, val episode: Int?, val data: String)
|
data class TvSeriesEpisode(
|
||||||
|
val name: String?,
|
||||||
|
val season: Int?,
|
||||||
|
val episode: Int?,
|
||||||
|
val data: String,
|
||||||
|
val posterUrl: String? = null,
|
||||||
|
val date: String? = null,
|
||||||
|
val rating: Int? = null,
|
||||||
|
val descript: String? = null,
|
||||||
|
)
|
||||||
|
|
||||||
data class TvSeriesLoadResponse(
|
data class TvSeriesLoadResponse(
|
||||||
override val name: String,
|
override val name: String,
|
||||||
|
@ -244,6 +262,9 @@ data class TvSeriesLoadResponse(
|
||||||
override val plot: String?,
|
override val plot: String?,
|
||||||
|
|
||||||
val showStatus: ShowStatus?,
|
val showStatus: ShowStatus?,
|
||||||
val imdbId: Int?,
|
val imdbUrl: String?,
|
||||||
override val rating: Int? = null,
|
override val rating: Int? = null,
|
||||||
|
override val tags: ArrayList<String>? = null,
|
||||||
|
override val duration: String? = null,
|
||||||
|
override val trailerUrl: String? = null,
|
||||||
) : LoadResponse
|
) : LoadResponse
|
|
@ -6,9 +6,11 @@ import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.APIHolder.unixTime
|
import com.lagradost.cloudstream3.APIHolder.unixTime
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.Qualities
|
import com.lagradost.cloudstream3.utils.Qualities
|
||||||
|
import com.lagradost.cloudstream3.utils.extractors.M3u8Manifest
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
|
|
||||||
|
//BE AWARE THAT weboas.is is a clone of lookmovie
|
||||||
class LookMovieProvider : MainAPI() {
|
class LookMovieProvider : MainAPI() {
|
||||||
override val hasQuickSearch: Boolean
|
override val hasQuickSearch: Boolean
|
||||||
get() = true
|
get() = true
|
||||||
|
@ -62,7 +64,7 @@ class LookMovieProvider : MainAPI() {
|
||||||
@JsonProperty("season") var season: String,
|
@JsonProperty("season") var season: String,
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun quickSearch(query: String): ArrayList<SearchResponse>? {
|
override fun quickSearch(query: String): ArrayList<SearchResponse> {
|
||||||
val movieUrl = "$mainUrl/api/v1/movies/search/?q=$query"
|
val movieUrl = "$mainUrl/api/v1/movies/search/?q=$query"
|
||||||
val movieResponse = khttp.get(movieUrl)
|
val movieResponse = khttp.get(movieUrl)
|
||||||
val movies = mapper.readValue<LookMovieSearchResultRoot>(movieResponse.text).result
|
val movies = mapper.readValue<LookMovieSearchResultRoot>(movieResponse.text).result
|
||||||
|
@ -138,12 +140,13 @@ class LookMovieProvider : MainAPI() {
|
||||||
|
|
||||||
override fun loadLinks(data: String, isCasting: Boolean, callback: (ExtractorLink) -> Unit): Boolean {
|
override fun loadLinks(data: String, isCasting: Boolean, callback: (ExtractorLink) -> Unit): Boolean {
|
||||||
val response = khttp.get(data.replace("\$unixtime", unixTime.toString()))
|
val response = khttp.get(data.replace("\$unixtime", unixTime.toString()))
|
||||||
|
M3u8Manifest.extractLinks(response.text).forEach {
|
||||||
"\"(.*?)\":\"(.*?)\"".toRegex().findAll(response.text).forEach {
|
callback.invoke(ExtractorLink(this.name,
|
||||||
var quality = it.groupValues[1].replace("auto", "Auto")
|
"${this.name} - ${it.second}",
|
||||||
if (quality != "Auto") quality += "p"
|
fixUrl(it.first),
|
||||||
val url = it.groupValues[2]
|
"",
|
||||||
callback.invoke(ExtractorLink(this.name, "${this.name} - $quality", url, "", getQualityFromName(quality),true))
|
getQualityFromName(it.second),
|
||||||
|
true))
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -174,9 +177,6 @@ class LookMovieProvider : MainAPI() {
|
||||||
val root = mapper.readValue<LookMovieTokenRoot>(tokenResponse.text)
|
val root = mapper.readValue<LookMovieTokenRoot>(tokenResponse.text)
|
||||||
val accessToken = root.data?.accessToken ?: return null
|
val accessToken = root.data?.accessToken ?: return null
|
||||||
|
|
||||||
//https://lookmovie.io/api/v1/security/show-access?slug=9140554-loki-2021&token=&sk=null&step=1
|
|
||||||
//https://lookmovie.io/api/v1/security/movie-access?id_movie=11582&token=1&sk=&step=1
|
|
||||||
|
|
||||||
if (isMovie) {
|
if (isMovie) {
|
||||||
return MovieLoadResponse(name,
|
return MovieLoadResponse(name,
|
||||||
slug,
|
slug,
|
||||||
|
@ -198,10 +198,6 @@ class LookMovieProvider : MainAPI() {
|
||||||
return this.replace("$replace:", "\"$replace\":")
|
return this.replace("$replace:", "\"$replace\":")
|
||||||
}
|
}
|
||||||
|
|
||||||
//https://lookmovie.io/api/v1/security/show-access?slug=9140554-loki-2021&token=&sk=null&step=1
|
|
||||||
//https://lookmovie.io/manifests/shows/json/TGv3dO0pcwomftMrywOnmw/1624571222/128848/master.m3u8
|
|
||||||
//https://lookmovie.io/api/v1/shows/episode-subtitles/?id_episode=128848
|
|
||||||
|
|
||||||
val json = season
|
val json = season
|
||||||
.replace("\'", "\"")
|
.replace("\'", "\"")
|
||||||
.fixSeasonJson("title")
|
.fixSeasonJson("title")
|
||||||
|
@ -230,6 +226,5 @@ class LookMovieProvider : MainAPI() {
|
||||||
null,
|
null,
|
||||||
rating)
|
rating)
|
||||||
}
|
}
|
||||||
//watch-heading
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -109,7 +109,7 @@ class MeloMovieProvider : MainAPI() {
|
||||||
return src.toRegex().find(response)?.groups?.get(1)?.value ?: return null
|
return src.toRegex().find(response)?.groups?.get(1)?.value ?: return null
|
||||||
}
|
}
|
||||||
|
|
||||||
val imdbId = findUsingRegex("var imdb = \"(tt[0-9]*)\"")?.toIntOrNull()
|
val imdbUrl = findUsingRegex("var imdb = \"(.*?)\"")
|
||||||
val document = Jsoup.parse(response)
|
val document = Jsoup.parse(response)
|
||||||
val poster = document.selectFirst("img.img-fluid").attr("src")
|
val poster = document.selectFirst("img.img-fluid").attr("src")
|
||||||
val type = findUsingRegex("var posttype = ([0-9]*)")?.toInt() ?: return null
|
val type = findUsingRegex("var posttype = ([0-9]*)")?.toInt() ?: return null
|
||||||
|
@ -128,7 +128,7 @@ class MeloMovieProvider : MainAPI() {
|
||||||
poster,
|
poster,
|
||||||
year,
|
year,
|
||||||
plot,
|
plot,
|
||||||
imdbId)
|
imdbUrl)
|
||||||
} else if (type == 2) {
|
} else if (type == 2) {
|
||||||
val episodes = ArrayList<TvSeriesEpisode>()
|
val episodes = ArrayList<TvSeriesEpisode>()
|
||||||
val seasons = document.select("div.accordion__card")
|
val seasons = document.select("div.accordion__card")
|
||||||
|
@ -154,7 +154,7 @@ class MeloMovieProvider : MainAPI() {
|
||||||
year,
|
year,
|
||||||
plot,
|
plot,
|
||||||
null,
|
null,
|
||||||
imdbId)
|
imdbUrl)
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,176 @@
|
||||||
|
package com.lagradost.cloudstream3.movieproviders
|
||||||
|
|
||||||
|
import com.lagradost.cloudstream3.*
|
||||||
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
|
import com.lagradost.cloudstream3.utils.Qualities
|
||||||
|
import org.jsoup.Jsoup
|
||||||
|
|
||||||
|
// referer = https://trailers.to, USERAGENT ALSO REQUIRED
|
||||||
|
class TrailersToProvider : MainAPI() {
|
||||||
|
override val mainUrl: String
|
||||||
|
get() = "https://trailers.to"
|
||||||
|
override val name: String
|
||||||
|
get() = "Trailers.to"
|
||||||
|
|
||||||
|
override val hasQuickSearch: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
|
override fun quickSearch(query: String): ArrayList<SearchResponse> {
|
||||||
|
val url = "https://trailers.to/en/quick-search?q=$query"
|
||||||
|
val response = khttp.get(url)
|
||||||
|
val document = Jsoup.parse(response.text)
|
||||||
|
val items = document.select("div.group-post-minimal > a.post-minimal")
|
||||||
|
if (items.isNullOrEmpty()) return ArrayList()
|
||||||
|
|
||||||
|
val returnValue = ArrayList<SearchResponse>()
|
||||||
|
for (item in items) {
|
||||||
|
val href = fixUrl(item.attr("href"))
|
||||||
|
val poster = item.selectFirst("> div.post-minimal-media > img").attr("src")
|
||||||
|
val header = item.selectFirst("> div.post-minimal-main")
|
||||||
|
val name = header.selectFirst("> span.link-black").text()
|
||||||
|
val info = header.select("> p")
|
||||||
|
val year = info?.get(1)?.text()?.toIntOrNull()
|
||||||
|
val isTvShow = href.contains("/tvshow/")
|
||||||
|
|
||||||
|
returnValue.add(
|
||||||
|
if (isTvShow) {
|
||||||
|
TvSeriesSearchResponse(name, href, href, this.name, TvType.TvSeries, poster, year, null)
|
||||||
|
} else {
|
||||||
|
MovieSearchResponse(name, href, href, this.name, TvType.Movie, poster, year)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return returnValue
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun search(query: String): ArrayList<SearchResponse> {
|
||||||
|
val url = "https://trailers.to/en/popular/movies-tvshows-collections?q=$query"
|
||||||
|
val response = khttp.get(url)
|
||||||
|
val document = Jsoup.parse(response.text)
|
||||||
|
val items = document.select("div.col-lg-8 > article.list-item")
|
||||||
|
if (items.isNullOrEmpty()) return ArrayList()
|
||||||
|
val returnValue = ArrayList<SearchResponse>()
|
||||||
|
for (item in items) {
|
||||||
|
val poster = item.selectFirst("> div.tour-modern-media > a.tour-modern-figure > img").attr("src")
|
||||||
|
val infoDiv = item.selectFirst("> div.tour-modern-main")
|
||||||
|
val nameHeader = infoDiv.select("> h5.tour-modern-title > a").last()
|
||||||
|
val name = nameHeader.text()
|
||||||
|
val href = fixUrl(nameHeader.attr("href"))
|
||||||
|
val year = infoDiv.selectFirst("> div > span.small-text")?.text()?.takeLast(4)?.toIntOrNull()
|
||||||
|
val isTvShow = href.contains("/tvshow/")
|
||||||
|
|
||||||
|
returnValue.add(
|
||||||
|
if (isTvShow) {
|
||||||
|
TvSeriesSearchResponse(name, href, href, this.name, TvType.TvSeries, poster, year, null)
|
||||||
|
} else {
|
||||||
|
MovieSearchResponse(name, href, href, this.name, TvType.Movie, poster, year)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return returnValue
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadLink(data: String, callback: (ExtractorLink) -> Unit): Boolean {
|
||||||
|
val response = khttp.get(data)
|
||||||
|
val url = "<source src='(.*?)'".toRegex().find(response.text)?.groupValues?.get(1)
|
||||||
|
if (url != null) {
|
||||||
|
callback.invoke(ExtractorLink(this.name, this.name, url, mainUrl, Qualities.Unknown.value, false))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun loadLinks(data: String, isCasting: Boolean, callback: (ExtractorLink) -> Unit): Boolean {
|
||||||
|
if (isCasting) return false
|
||||||
|
val isMovie = data.contains("/web-sources/")
|
||||||
|
if (isMovie) {
|
||||||
|
return loadLink(data, callback)
|
||||||
|
} else if (data.contains("/episode/")) {
|
||||||
|
val response = khttp.get(data)
|
||||||
|
val document = Jsoup.parse(response.text)
|
||||||
|
val subData = fixUrl(document.selectFirst("content").attr("data-url") ?: return false)
|
||||||
|
if (subData.contains("/web-sources/")) {
|
||||||
|
return loadLink(subData, callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun load(slug: String): LoadResponse? {
|
||||||
|
val response = khttp.get(slug)
|
||||||
|
val document = Jsoup.parse(response.text)
|
||||||
|
val metaInfo = document.select("div.post-info-meta > ul.post-info-meta-list > li")
|
||||||
|
val year = metaInfo?.get(0)?.selectFirst("> span.small-text")?.text()?.takeLast(4)?.toIntOrNull()
|
||||||
|
val rating = parseRating(metaInfo?.get(1)?.selectFirst("> span.small-text")?.text()?.replace("/ 10", ""))
|
||||||
|
val duration = metaInfo?.get(2)?.selectFirst("> span.small-text")?.text()
|
||||||
|
val imdbUrl = metaInfo?.get(3)?.selectFirst("> a")?.attr("href")
|
||||||
|
val trailer = metaInfo?.get(4)?.selectFirst("> a")?.attr("href")
|
||||||
|
val poster = document.selectFirst("div.slider-image > a > img").attr("src")
|
||||||
|
val descriptHeader = document.selectFirst("article.post-info")
|
||||||
|
var title = document.selectFirst("h2.breadcrumbs-custom-title > a").text()
|
||||||
|
title = title.substring(0, title.length - 6) // REMOVE YEAR
|
||||||
|
|
||||||
|
val descript = descriptHeader.select("> div > p").text()
|
||||||
|
val table = descriptHeader.select("> table.post-info-table > tbody > tr > td")
|
||||||
|
var generes: List<String>? = null
|
||||||
|
for (i in 0 until table.size / 2) {
|
||||||
|
val header = table[i * 2].text()
|
||||||
|
val info = table[i * 2 + 1]
|
||||||
|
when (header) {
|
||||||
|
"Genre" -> generes = info.text().split(",")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val tags = if (generes == null) null else ArrayList(generes)
|
||||||
|
|
||||||
|
val isTvShow = slug.contains("/tvshow/")
|
||||||
|
if (isTvShow) {
|
||||||
|
val episodes = document.select("article.tour-modern") ?: return null
|
||||||
|
val parsedEpisodes = episodes.map { item ->
|
||||||
|
val epPoster = item.selectFirst("> div.tour-modern-media > a.tour-modern-figure > img").attr("src")
|
||||||
|
val main = item.selectFirst("> div.tour-modern-main")
|
||||||
|
val titleHeader = main.selectFirst("> h5.tour-modern-title > a")
|
||||||
|
val titleName = titleHeader.text()
|
||||||
|
val href = fixUrl(titleHeader.attr("href"))
|
||||||
|
val gValues = ".*?Season ([0-9]*).*Episode ([0-9]*): (.*)".toRegex().find(titleName)?.groupValues
|
||||||
|
val season = gValues?.get(1)?.toIntOrNull()
|
||||||
|
val episode = gValues?.get(2)?.toIntOrNull()
|
||||||
|
val epName = gValues?.get(3)
|
||||||
|
val infoHeaders = main.select("> div > span.small-text")
|
||||||
|
val date = infoHeaders?.get(0)?.text()
|
||||||
|
val ratingText = infoHeaders?.get(1)?.text()?.replace("/ 10", "")
|
||||||
|
val epRating = if (ratingText == null) null else parseRating(ratingText)
|
||||||
|
val epDescript = main.selectFirst("> p")?.text()
|
||||||
|
TvSeriesEpisode(epName, season, episode, href, epPoster, date, epRating, epDescript)
|
||||||
|
}
|
||||||
|
return TvSeriesLoadResponse(title,
|
||||||
|
slug,
|
||||||
|
this.name,
|
||||||
|
TvType.TvSeries,
|
||||||
|
ArrayList(parsedEpisodes),
|
||||||
|
poster,
|
||||||
|
year,
|
||||||
|
descript,
|
||||||
|
null,
|
||||||
|
imdbUrl,
|
||||||
|
rating,
|
||||||
|
tags,
|
||||||
|
duration,
|
||||||
|
trailer)
|
||||||
|
} else {
|
||||||
|
val data = fixUrl(document.selectFirst("content").attr("data-url") ?: return null)
|
||||||
|
return MovieLoadResponse(title,
|
||||||
|
slug,
|
||||||
|
this.name,
|
||||||
|
TvType.Movie,
|
||||||
|
data,
|
||||||
|
poster,
|
||||||
|
year,
|
||||||
|
descript,
|
||||||
|
imdbUrl,
|
||||||
|
rating,
|
||||||
|
tags,
|
||||||
|
duration,
|
||||||
|
trailer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -483,6 +483,21 @@ activity?.startActivityForResult(vlcIntent, REQUEST_CODE)
|
||||||
result_tag_holder.visibility = GONE
|
result_tag_holder.visibility = GONE
|
||||||
result_status.visibility = GONE
|
result_status.visibility = GONE
|
||||||
|
|
||||||
|
val tags = d.tags
|
||||||
|
if (tags == null) {
|
||||||
|
result_tag_holder.visibility = GONE
|
||||||
|
} else {
|
||||||
|
result_tag_holder.visibility = VISIBLE
|
||||||
|
|
||||||
|
for ((index, tag) in tags.withIndex()) {
|
||||||
|
val viewBtt = layoutInflater.inflate(R.layout.result_tag, null)
|
||||||
|
val btt = viewBtt.findViewById<MaterialButton>(R.id.result_tag_card)
|
||||||
|
btt.text = tag
|
||||||
|
|
||||||
|
result_tag.addView(viewBtt, index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
when (d.type) {
|
when (d.type) {
|
||||||
TvType.Movie -> {
|
TvType.Movie -> {
|
||||||
result_play_movie.visibility = VISIBLE
|
result_play_movie.visibility = VISIBLE
|
||||||
|
@ -525,20 +540,6 @@ activity?.startActivityForResult(vlcIntent, REQUEST_CODE)
|
||||||
val titleName = d.name
|
val titleName = d.name
|
||||||
result_title.text = titleName
|
result_title.text = titleName
|
||||||
result_toolbar.title = titleName
|
result_toolbar.title = titleName
|
||||||
|
|
||||||
if (d.tags == null) {
|
|
||||||
result_tag_holder.visibility = GONE
|
|
||||||
} else {
|
|
||||||
result_tag_holder.visibility = VISIBLE
|
|
||||||
|
|
||||||
for ((index, tag) in d.tags.withIndex()) {
|
|
||||||
val viewBtt = layoutInflater.inflate(R.layout.result_tag, null)
|
|
||||||
val btt = viewBtt.findViewById<MaterialButton>(R.id.result_tag_card)
|
|
||||||
btt.text = tag
|
|
||||||
|
|
||||||
result_tag.addView(viewBtt, index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else -> result_title.text = d.name
|
else -> result_title.text = d.name
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.lagradost.cloudstream3.utils.extractors
|
||||||
|
|
||||||
|
//{"auto":"/manifests/movies/15559/1624728920/qDwu5BOsfAwfTmnnjmkmXA/master.m3u8","1080p":"https://vdoc3.sallenes.space/qDwu5BOsfAwfTmnnjmkmXA/1624728920/storage6/movies/the-man-with-the-iron-heart-2017/1080p/index.m3u8","720p":"https://vdoc3.sallenes.space/qDwu5BOsfAwfTmnnjmkmXA/1624728920/storage6/movies/the-man-with-the-iron-heart-2017/720p/index.m3u8","360p":"https://vdoc3.sallenes.space/qDwu5BOsfAwfTmnnjmkmXA/1624728920/storage6/movies/the-man-with-the-iron-heart-2017/360p/index.m3u8","480p":"https://vdoc3.sallenes.space/qDwu5BOsfAwfTmnnjmkmXA/1624728920/storage6/movies/the-man-with-the-iron-heart-2017/480p/index.m3u8"}
|
||||||
|
object M3u8Manifest {
|
||||||
|
// URL = first, QUALITY = second
|
||||||
|
fun extractLinks(m3u8Data: String): ArrayList<Pair<String, String>> {
|
||||||
|
val data: ArrayList<Pair<String, String>> = ArrayList()
|
||||||
|
"\"(.*?)\":\"(.*?)\"".toRegex().findAll(m3u8Data).forEach {
|
||||||
|
var quality = it.groupValues[1].replace("auto", "Auto")
|
||||||
|
if (quality != "Auto") quality += "p"
|
||||||
|
val url = it.groupValues[2]
|
||||||
|
data.add(Pair(url, quality))
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue