forked from recloudstream/cloudstream
small subtitle support
This commit is contained in:
parent
672dc8c8d1
commit
9fc732c68c
12 changed files with 266 additions and 124 deletions
|
@ -72,7 +72,7 @@ abstract class MainAPI {
|
|||
}
|
||||
|
||||
// callback is fired once a link is found, will return true if method is executed successfully
|
||||
open fun loadLinks(data: String, isCasting: Boolean, callback: (ExtractorLink) -> Unit): Boolean {
|
||||
open fun loadLinks(data: String, isCasting: Boolean, subtitleCallback : (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit): Boolean {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -120,6 +120,8 @@ enum class TvType {
|
|||
ONA,
|
||||
}
|
||||
|
||||
data class SubtitleFile(val lang : String, val url : String)
|
||||
|
||||
interface SearchResponse {
|
||||
val name: String
|
||||
val url: String // PUBLIC URL FOR OPEN IN APP
|
||||
|
|
|
@ -86,7 +86,8 @@ class DubbedAnimeProvider : MainAPI() {
|
|||
title, href, getSlug(href), this.name, TvType.Movie, img, null
|
||||
)
|
||||
} else {
|
||||
AnimeSearchResponse(title,
|
||||
AnimeSearchResponse(
|
||||
title,
|
||||
href,
|
||||
getSlug(href),
|
||||
this.name,
|
||||
|
@ -96,8 +97,10 @@ class DubbedAnimeProvider : MainAPI() {
|
|||
null,
|
||||
EnumSet.of(DubStatus.Dubbed),
|
||||
null,
|
||||
null)
|
||||
})
|
||||
null
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
return returnValue
|
||||
}
|
||||
|
@ -121,7 +124,8 @@ class DubbedAnimeProvider : MainAPI() {
|
|||
title, href, getSlug(href), this.name, TvType.Movie, img, null
|
||||
)
|
||||
} else {
|
||||
AnimeSearchResponse(title,
|
||||
AnimeSearchResponse(
|
||||
title,
|
||||
href,
|
||||
getSlug(href),
|
||||
this.name,
|
||||
|
@ -131,14 +135,21 @@ class DubbedAnimeProvider : MainAPI() {
|
|||
null,
|
||||
EnumSet.of(DubStatus.Dubbed),
|
||||
null,
|
||||
null)
|
||||
})
|
||||
null
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
return returnValue
|
||||
}
|
||||
|
||||
override fun loadLinks(data: String, isCasting: Boolean, callback: (ExtractorLink) -> Unit): Boolean {
|
||||
override fun loadLinks(
|
||||
data: String,
|
||||
isCasting: Boolean,
|
||||
subtitleCallback: (SubtitleFile) -> Unit,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
): Boolean {
|
||||
val serversHTML = (if (data.startsWith(mainUrl)) { // CLASSIC EPISODE
|
||||
val slug = getSlug(data)
|
||||
getAnimeEpisode(slug, false).serversHTML
|
||||
|
@ -154,11 +165,15 @@ class DubbedAnimeProvider : MainAPI() {
|
|||
val find = "src=\"(.*?)\".*?label=\"(.*?)\"".toRegex().find(txt)
|
||||
if (find != null) {
|
||||
val quality = find.groupValues[2]
|
||||
callback.invoke(ExtractorLink(this.name,
|
||||
this.name + " " + quality + if (quality.endsWith('p')) "" else 'p',
|
||||
fixUrl(find.groupValues[1]),
|
||||
this.mainUrl,
|
||||
getQualityFromName(quality)))
|
||||
callback.invoke(
|
||||
ExtractorLink(
|
||||
this.name,
|
||||
this.name + " " + quality + if (quality.endsWith('p')) "" else 'p',
|
||||
fixUrl(find.groupValues[1]),
|
||||
this.mainUrl,
|
||||
getQualityFromName(quality)
|
||||
)
|
||||
)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
//IDK
|
||||
|
@ -172,7 +187,8 @@ class DubbedAnimeProvider : MainAPI() {
|
|||
val realSlug = slug.replace("movies/", "")
|
||||
val episode = getAnimeEpisode(realSlug, true)
|
||||
val poster = episode.previewImg ?: episode.wideImg
|
||||
return MovieLoadResponse(episode.title,
|
||||
return MovieLoadResponse(
|
||||
episode.title,
|
||||
realSlug,
|
||||
this.name,
|
||||
TvType.Movie,
|
||||
|
@ -180,7 +196,8 @@ class DubbedAnimeProvider : MainAPI() {
|
|||
if (poster == null) null else fixUrl(poster),
|
||||
episode.year?.toIntOrNull(),
|
||||
episode.desc,
|
||||
null)
|
||||
null
|
||||
)
|
||||
} else {
|
||||
val response = khttp.get("$mainUrl/$slug")
|
||||
val document = Jsoup.parse(response.text)
|
||||
|
|
|
@ -167,12 +167,14 @@ class ShiroProvider : MainAPI() {
|
|||
override fun quickSearch(query: String): ArrayList<SearchResponse> {
|
||||
val returnValue: ArrayList<SearchResponse> = ArrayList()
|
||||
|
||||
val response = khttp.get("https://tapi.shiro.is/anime/auto-complete/${
|
||||
URLEncoder.encode(
|
||||
query,
|
||||
"UTF-8"
|
||||
)
|
||||
}?token=$token".replace("+", "%20"))
|
||||
val response = khttp.get(
|
||||
"https://tapi.shiro.is/anime/auto-complete/${
|
||||
URLEncoder.encode(
|
||||
query,
|
||||
"UTF-8"
|
||||
)
|
||||
}?token=$token".replace("+", "%20")
|
||||
)
|
||||
if (response.text == "{\"status\":\"Found\",\"data\":[]}") return returnValue // OR ELSE WILL CAUSE WEIRD ERROR
|
||||
|
||||
val mapped = response.let { mapper.readValue<ShiroSearchResponse>(it.text) }
|
||||
|
@ -185,12 +187,14 @@ class ShiroProvider : MainAPI() {
|
|||
override fun search(query: String): ArrayList<SearchResponse>? {
|
||||
if (!autoLoadToken()) return null
|
||||
val returnValue: ArrayList<SearchResponse> = ArrayList()
|
||||
val response = khttp.get("https://tapi.shiro.is/advanced?search=${
|
||||
URLEncoder.encode(
|
||||
query,
|
||||
"UTF-8"
|
||||
)
|
||||
}&token=$token".replace("+", "%20"))
|
||||
val response = khttp.get(
|
||||
"https://tapi.shiro.is/advanced?search=${
|
||||
URLEncoder.encode(
|
||||
query,
|
||||
"UTF-8"
|
||||
)
|
||||
}&token=$token".replace("+", "%20")
|
||||
)
|
||||
if (response.text == "{\"status\":\"Found\",\"data\":[]}") return returnValue // OR ELSE WILL CAUSE WEIRD ERROR
|
||||
|
||||
val mapped = response.let { mapper.readValue<ShiroFullSearchResponse>(it.text) }
|
||||
|
@ -235,7 +239,12 @@ class ShiroProvider : MainAPI() {
|
|||
)
|
||||
}
|
||||
|
||||
override fun loadLinks(data: String, isCasting: Boolean, callback: (ExtractorLink) -> Unit): Boolean {
|
||||
override fun loadLinks(
|
||||
data: String,
|
||||
isCasting: Boolean,
|
||||
subtitleCallback: (SubtitleFile) -> Unit,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
): Boolean {
|
||||
return Vidstream().getUrl(data, isCasting) {
|
||||
callback.invoke(it)
|
||||
}
|
||||
|
|
|
@ -29,17 +29,26 @@ class HDMProvider : MainAPI() {
|
|||
return returnValue
|
||||
}
|
||||
|
||||
override fun loadLinks(data: String, isCasting: Boolean, callback: (ExtractorLink) -> Unit): Boolean {
|
||||
override fun loadLinks(
|
||||
data: String,
|
||||
isCasting: Boolean,
|
||||
subtitleCallback: (SubtitleFile) -> Unit,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
): Boolean {
|
||||
if (data == "") return false
|
||||
val slug = ".*/(.*?)\\.mp4".toRegex().find(data)?.groupValues?.get(1) ?: return false
|
||||
val response = khttp.get(data)
|
||||
val key = "playlist\\.m3u8(.*?)\"".toRegex().find(response.text)?.groupValues?.get(1) ?: return false
|
||||
callback.invoke(ExtractorLink(this.name,
|
||||
this.name,
|
||||
"https://hls.1o.to/vod/$slug/playlist.m3u8$key",
|
||||
"",
|
||||
Qualities.HD.value,
|
||||
true))
|
||||
callback.invoke(
|
||||
ExtractorLink(
|
||||
this.name,
|
||||
this.name,
|
||||
"https://hls.1o.to/vod/$slug/playlist.m3u8$key",
|
||||
"",
|
||||
Qualities.HD.value,
|
||||
true
|
||||
)
|
||||
)
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -51,9 +60,11 @@ class HDMProvider : MainAPI() {
|
|||
val descript = document.selectFirst("div.synopsis > p").text()
|
||||
val year = document.select("div.movieInfoAll > div.row > div.col-md-6")?.get(1)?.selectFirst("> p > a")?.text()
|
||||
?.toIntOrNull()
|
||||
val data = "src/player/\\?v=(.*?)\"".toRegex().find(response.text)?.groupValues?.get(1) ?: return null
|
||||
val data = "src/player/\\?v=(.*?)\"".toRegex().find(response.text)?.groupValues?.get(1) ?: return null
|
||||
|
||||
return MovieLoadResponse(title, slug, this.name, TvType.Movie,
|
||||
"$mainUrl/src/player/?v=$data", poster, year, descript, null)
|
||||
return MovieLoadResponse(
|
||||
title, slug, this.name, TvType.Movie,
|
||||
"$mainUrl/src/player/?v=$data", poster, year, descript, null
|
||||
)
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@ import com.fasterxml.jackson.module.kotlin.readValue
|
|||
import com.lagradost.cloudstream3.*
|
||||
import com.lagradost.cloudstream3.APIHolder.unixTime
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
import com.lagradost.cloudstream3.utils.Qualities
|
||||
import com.lagradost.cloudstream3.utils.extractors.M3u8Manifest
|
||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||
import org.jsoup.Jsoup
|
||||
|
@ -43,7 +42,7 @@ class LookMovieProvider : MainAPI() {
|
|||
|
||||
data class LookMovieTokenSubtitle(
|
||||
@JsonProperty("language") val language: String,
|
||||
//@JsonProperty("source") val source: String,
|
||||
@JsonProperty("source") val source: String?,
|
||||
//@JsonProperty("source_id") val source_id: String,
|
||||
//@JsonProperty("kind") val kind: String,
|
||||
//@JsonProperty("id") val id: String,
|
||||
|
@ -77,26 +76,34 @@ class LookMovieProvider : MainAPI() {
|
|||
if (!movies.isNullOrEmpty()) {
|
||||
for (m in movies) {
|
||||
val url = "$mainUrl/movies/view/${m.slug}"
|
||||
returnValue.add(MovieSearchResponse(m.title,
|
||||
url,
|
||||
url,//m.slug,
|
||||
this.name,
|
||||
TvType.Movie,
|
||||
m.poster ?: m.backdrop,
|
||||
m.year?.toIntOrNull()))
|
||||
returnValue.add(
|
||||
MovieSearchResponse(
|
||||
m.title,
|
||||
url,
|
||||
url,//m.slug,
|
||||
this.name,
|
||||
TvType.Movie,
|
||||
m.poster ?: m.backdrop,
|
||||
m.year?.toIntOrNull()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (!shows.isNullOrEmpty()) {
|
||||
for (s in shows) {
|
||||
val url = "$mainUrl/shows/view/${s.slug}"
|
||||
returnValue.add(MovieSearchResponse(s.title,
|
||||
url,
|
||||
url,//s.slug,
|
||||
this.name,
|
||||
TvType.TvSeries,
|
||||
s.poster ?: s.backdrop,
|
||||
s.year?.toIntOrNull()))
|
||||
returnValue.add(
|
||||
MovieSearchResponse(
|
||||
s.title,
|
||||
url,
|
||||
url,//s.slug,
|
||||
this.name,
|
||||
TvType.TvSeries,
|
||||
s.poster ?: s.backdrop,
|
||||
s.year?.toIntOrNull()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,14 +126,15 @@ class LookMovieProvider : MainAPI() {
|
|||
val poster = posterHolder.selectFirst("> img")?.attr("data-src")
|
||||
val year = posterHolder.selectFirst("> p.year")?.text()?.toIntOrNull()
|
||||
|
||||
returnValue.add(if (isMovie) {
|
||||
MovieSearchResponse(
|
||||
name, href, href, this.name, TvType.Movie, poster, year
|
||||
)
|
||||
} else
|
||||
TvSeriesSearchResponse(
|
||||
name, href, href, this.name, TvType.TvSeries, poster, year, null
|
||||
)
|
||||
returnValue.add(
|
||||
if (isMovie) {
|
||||
MovieSearchResponse(
|
||||
name, href, href, this.name, TvType.Movie, poster, year
|
||||
)
|
||||
} else
|
||||
TvSeriesSearchResponse(
|
||||
name, href, href, this.name, TvType.TvSeries, poster, year, null
|
||||
)
|
||||
)
|
||||
}
|
||||
return returnValue
|
||||
|
@ -138,15 +146,52 @@ class LookMovieProvider : MainAPI() {
|
|||
return movieList
|
||||
}
|
||||
|
||||
override fun loadLinks(data: String, isCasting: Boolean, callback: (ExtractorLink) -> Unit): Boolean {
|
||||
val response = khttp.get(data.replace("\$unixtime", unixTime.toString()))
|
||||
data class LookMovieLinkLoad(val url: String, val extraUrl: String, val isMovie: Boolean)
|
||||
|
||||
private fun addSubtitles(subs: List<LookMovieTokenSubtitle>?, subtitleCallback: (SubtitleFile) -> Unit) {
|
||||
if (subs == null) return
|
||||
subs.forEach {
|
||||
if (it.source != "opensubtitle")
|
||||
subtitleCallback.invoke(SubtitleFile(it.language, fixUrl(it.file)))
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadCurrentLinks(url: String, callback: (ExtractorLink) -> Unit) {
|
||||
val response = khttp.get(url.replace("\$unixtime", unixTime.toString()))
|
||||
M3u8Manifest.extractLinks(response.text).forEach {
|
||||
callback.invoke(ExtractorLink(this.name,
|
||||
"${this.name} - ${it.second}",
|
||||
fixUrl(it.first),
|
||||
"",
|
||||
getQualityFromName(it.second),
|
||||
true))
|
||||
callback.invoke(
|
||||
ExtractorLink(
|
||||
this.name,
|
||||
"${this.name} - ${it.second}",
|
||||
fixUrl(it.first),
|
||||
"",
|
||||
getQualityFromName(it.second),
|
||||
true
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun loadLinks(
|
||||
data: String,
|
||||
isCasting: Boolean,
|
||||
subtitleCallback: (SubtitleFile) -> Unit,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
): Boolean {
|
||||
val localData: LookMovieLinkLoad = mapper.readValue(data)
|
||||
|
||||
if (localData.isMovie) {
|
||||
val tokenResponse = khttp.get(localData.url)
|
||||
val root = mapper.readValue<LookMovieTokenRoot>(tokenResponse.text)
|
||||
val accessToken = root.data?.accessToken ?: return false
|
||||
addSubtitles(root.data.subtitles, subtitleCallback)
|
||||
loadCurrentLinks(localData.extraUrl.replace("\$accessToken", accessToken), callback)
|
||||
return true
|
||||
} else {
|
||||
loadCurrentLinks(localData.url, callback)
|
||||
val subResponse = khttp.get(localData.extraUrl)
|
||||
val subs = mapper.readValue<List<LookMovieTokenSubtitle>>(subResponse.text)
|
||||
addSubtitles(subs, subtitleCallback)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -159,7 +204,7 @@ class LookMovieProvider : MainAPI() {
|
|||
val watchHeader = document.selectFirst("div.watch-heading")
|
||||
val nameHeader = watchHeader.selectFirst("> h1.bd-hd")
|
||||
val year = nameHeader.selectFirst("> span")?.text()?.toIntOrNull()
|
||||
val name = nameHeader.ownText()
|
||||
val title = nameHeader.ownText()
|
||||
val rating = parseRating(watchHeader.selectFirst("> div.movie-rate > div.rate > p > span").text())
|
||||
val imgElement = document.selectFirst("div.movie-img > p.movie__poster")
|
||||
val img = imgElement?.attr("style")
|
||||
|
@ -173,22 +218,31 @@ class LookMovieProvider : MainAPI() {
|
|||
val realUrl =
|
||||
"$mainUrl/api/v1/security/${if (isMovie) "movie" else "show"}-access?${if (isMovie) "id_movie=$id" else "slug=$realSlug"}&token=1&sk=&step=1"
|
||||
|
||||
val tokenResponse = khttp.get(realUrl)
|
||||
val root = mapper.readValue<LookMovieTokenRoot>(tokenResponse.text)
|
||||
val accessToken = root.data?.accessToken ?: return null
|
||||
|
||||
if (isMovie) {
|
||||
return MovieLoadResponse(name,
|
||||
val localData = mapper.writeValueAsString(
|
||||
LookMovieLinkLoad(
|
||||
realUrl,
|
||||
"$mainUrl/manifests/movies/json/$id/\$unixtime/\$accessToken/master.m3u8",
|
||||
true
|
||||
)
|
||||
)
|
||||
return MovieLoadResponse(
|
||||
title,
|
||||
slug,
|
||||
this.name,
|
||||
TvType.Movie,
|
||||
"$mainUrl/manifests/movies/json/$id/\$unixtime/$accessToken/master.m3u8",
|
||||
localData,
|
||||
poster,
|
||||
year,
|
||||
descript,
|
||||
null,
|
||||
rating)
|
||||
rating
|
||||
)
|
||||
} else {
|
||||
val tokenResponse = khttp.get(realUrl)
|
||||
val root = mapper.readValue<LookMovieTokenRoot>(tokenResponse.text)
|
||||
val accessToken = root.data?.accessToken ?: return null
|
||||
|
||||
val window =
|
||||
"window\\[\\'show_storage\\'\\] =((.|\\n)*?\\<)".toRegex().find(response.text)?.groupValues?.get(1)
|
||||
?: return null
|
||||
|
@ -208,13 +262,24 @@ class LookMovieProvider : MainAPI() {
|
|||
val realJson = "[" + json.substring(0, json.lastIndexOf(',')) + "]"
|
||||
|
||||
val episodes = mapper.readValue<List<LookMovieEpisode>>(realJson).map {
|
||||
TvSeriesEpisode(it.title,
|
||||
val localData = mapper.writeValueAsString(
|
||||
LookMovieLinkLoad(
|
||||
"$mainUrl/manifests/shows/json/$accessToken/\$unixtime/${it.idEpisode}/master.m3u8",
|
||||
"https://lookmovie.io/api/v1/shows/episode-subtitles/?id_episode=${it.idEpisode}",
|
||||
false
|
||||
)
|
||||
)
|
||||
|
||||
TvSeriesEpisode(
|
||||
it.title,
|
||||
it.season.toIntOrNull(),
|
||||
it.episode.toIntOrNull(),
|
||||
"$mainUrl/manifests/shows/json/$accessToken/\$unixtime/${it.idEpisode}/master.m3u8")
|
||||
localData
|
||||
)
|
||||
}.toList()
|
||||
|
||||
return TvSeriesLoadResponse(name,
|
||||
return TvSeriesLoadResponse(
|
||||
title,
|
||||
slug,
|
||||
this.name,
|
||||
TvType.TvSeries,
|
||||
|
@ -224,7 +289,8 @@ class LookMovieProvider : MainAPI() {
|
|||
descript,
|
||||
null,
|
||||
null,
|
||||
rating)
|
||||
rating
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -44,22 +44,30 @@ class MeloMovieProvider : MainAPI() {
|
|||
val currentUrl = "$mainUrl/movie/${i.id}"
|
||||
val currentPoster = "$mainUrl/assets/images/poster/${i.imdbId}.jpg"
|
||||
if (i.type == 2) { // TV-SERIES
|
||||
returnValue.add(TvSeriesSearchResponse(i.title,
|
||||
currentUrl,
|
||||
currentUrl,
|
||||
this.name,
|
||||
TvType.TvSeries,
|
||||
currentPoster,
|
||||
i.year,
|
||||
null))
|
||||
returnValue.add(
|
||||
TvSeriesSearchResponse(
|
||||
i.title,
|
||||
currentUrl,
|
||||
currentUrl,
|
||||
this.name,
|
||||
TvType.TvSeries,
|
||||
currentPoster,
|
||||
i.year,
|
||||
null
|
||||
)
|
||||
)
|
||||
} else if (i.type == 1) { // MOVIE
|
||||
returnValue.add(MovieSearchResponse(i.title,
|
||||
currentUrl,
|
||||
currentUrl,
|
||||
this.name,
|
||||
TvType.Movie,
|
||||
currentUrl,
|
||||
i.year))
|
||||
returnValue.add(
|
||||
MovieSearchResponse(
|
||||
i.title,
|
||||
currentUrl,
|
||||
currentUrl,
|
||||
this.name,
|
||||
TvType.Movie,
|
||||
currentUrl,
|
||||
i.year
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
return returnValue
|
||||
|
@ -67,7 +75,7 @@ class MeloMovieProvider : MainAPI() {
|
|||
|
||||
// http not https, the links are not https!
|
||||
private fun fixUrl(url: String): String {
|
||||
if(url.isEmpty()) return ""
|
||||
if (url.isEmpty()) return ""
|
||||
|
||||
if (url.startsWith("//")) {
|
||||
return "http:$url"
|
||||
|
@ -93,7 +101,12 @@ class MeloMovieProvider : MainAPI() {
|
|||
return mapper.writeValueAsString(parsed)
|
||||
}
|
||||
|
||||
override fun loadLinks(data: String, isCasting: Boolean, callback: (ExtractorLink) -> Unit): Boolean {
|
||||
override fun loadLinks(
|
||||
data: String,
|
||||
isCasting: Boolean,
|
||||
subtitleCallback: (SubtitleFile) -> Unit,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
): Boolean {
|
||||
val links = mapper.readValue<List<MeloMovieLink>>(data)
|
||||
for (link in links) {
|
||||
callback.invoke(ExtractorLink(this.name, link.name, link.link, "", getQualityFromName(link.name), false))
|
||||
|
@ -120,7 +133,8 @@ class MeloMovieProvider : MainAPI() {
|
|||
|
||||
if (type == 1) { // MOVIE
|
||||
val serialize = document.selectFirst("table.accordion__list")
|
||||
return MovieLoadResponse(title,
|
||||
return MovieLoadResponse(
|
||||
title,
|
||||
slug,
|
||||
this.name,
|
||||
TvType.Movie,
|
||||
|
@ -128,7 +142,8 @@ class MeloMovieProvider : MainAPI() {
|
|||
poster,
|
||||
year,
|
||||
plot,
|
||||
imdbUrl)
|
||||
imdbUrl
|
||||
)
|
||||
} else if (type == 2) {
|
||||
val episodes = ArrayList<TvSeriesEpisode>()
|
||||
val seasons = document.select("div.accordion__card")
|
||||
|
@ -145,7 +160,8 @@ class MeloMovieProvider : MainAPI() {
|
|||
}
|
||||
}
|
||||
episodes.reverse()
|
||||
return TvSeriesLoadResponse(title,
|
||||
return TvSeriesLoadResponse(
|
||||
title,
|
||||
slug,
|
||||
this.name,
|
||||
TvType.TvSeries,
|
||||
|
@ -154,7 +170,8 @@ class MeloMovieProvider : MainAPI() {
|
|||
year,
|
||||
plot,
|
||||
null,
|
||||
imdbUrl)
|
||||
imdbUrl
|
||||
)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
|
|
@ -80,7 +80,12 @@ class TrailersToProvider : MainAPI() {
|
|||
return false
|
||||
}
|
||||
|
||||
override fun loadLinks(data: String, isCasting: Boolean, callback: (ExtractorLink) -> Unit): Boolean {
|
||||
override fun loadLinks(
|
||||
data: String,
|
||||
isCasting: Boolean,
|
||||
subtitleCallback: (SubtitleFile) -> Unit,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
): Boolean {
|
||||
if (isCasting) return false
|
||||
val isMovie = data.contains("/web-sources/")
|
||||
if (isMovie) {
|
||||
|
@ -142,7 +147,8 @@ class TrailersToProvider : MainAPI() {
|
|||
val epDescript = main.selectFirst("> p")?.text()
|
||||
TvSeriesEpisode(epName, season, episode, href, epPoster, date, epRating, epDescript)
|
||||
}
|
||||
return TvSeriesLoadResponse(title,
|
||||
return TvSeriesLoadResponse(
|
||||
title,
|
||||
slug,
|
||||
this.name,
|
||||
TvType.TvSeries,
|
||||
|
@ -155,10 +161,12 @@ class TrailersToProvider : MainAPI() {
|
|||
rating,
|
||||
tags,
|
||||
duration,
|
||||
trailer)
|
||||
trailer
|
||||
)
|
||||
} else {
|
||||
val data = fixUrl(document.selectFirst("content").attr("data-url") ?: return null)
|
||||
return MovieLoadResponse(title,
|
||||
return MovieLoadResponse(
|
||||
title,
|
||||
slug,
|
||||
this.name,
|
||||
TvType.Movie,
|
||||
|
@ -170,7 +178,8 @@ class TrailersToProvider : MainAPI() {
|
|||
rating,
|
||||
tags,
|
||||
duration,
|
||||
trailer)
|
||||
trailer
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -128,7 +128,8 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi
|
|||
epData,
|
||||
holder,
|
||||
index,
|
||||
remoteMediaClient?.mediaInfo?.customData)
|
||||
remoteMediaClient?.mediaInfo?.customData
|
||||
)
|
||||
|
||||
val startAt = remoteMediaClient?.approximateStreamPosition ?: 0
|
||||
|
||||
|
@ -139,12 +140,17 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi
|
|||
val nextId = remoteMediaClient.mediaQueue.itemIds?.get(currentIdIndex?.plus(1) ?: 0)
|
||||
|
||||
if (currentIdIndex == null && nextId != null) {
|
||||
awaitLinks(remoteMediaClient?.queueInsertAndPlayItem(MediaQueueItem.Builder(
|
||||
mediaItem)
|
||||
.build(),
|
||||
nextId,
|
||||
startAt,
|
||||
JSONObject())) {
|
||||
awaitLinks(
|
||||
remoteMediaClient?.queueInsertAndPlayItem(
|
||||
MediaQueueItem.Builder(
|
||||
mediaItem
|
||||
)
|
||||
.build(),
|
||||
nextId,
|
||||
startAt,
|
||||
JSONObject()
|
||||
)
|
||||
) {
|
||||
loadMirror(index + 1)
|
||||
}
|
||||
} else {
|
||||
|
@ -204,7 +210,7 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi
|
|||
val links = ArrayList<ExtractorLink>()
|
||||
|
||||
val res = safeApiCall {
|
||||
getApiFromName(meta.apiName).loadLinks(epData.data, true) {
|
||||
getApiFromName(meta.apiName).loadLinks(epData.data, true, { subtitleFile -> }) {
|
||||
for (i in links) {
|
||||
if (i.url == it.url) return@loadLinks
|
||||
}
|
||||
|
@ -225,7 +231,8 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi
|
|||
epData,
|
||||
jsonCopy,
|
||||
0,
|
||||
done)
|
||||
done
|
||||
)
|
||||
|
||||
/*fun loadIndex(index: Int) {
|
||||
println("LOAD INDEX::::: $index")
|
||||
|
@ -240,8 +247,12 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi
|
|||
}
|
||||
}*/
|
||||
|
||||
awaitLinks(remoteMediaClient?.queueAppendItem(MediaQueueItem.Builder(mediaInfo).build(),
|
||||
JSONObject())) {
|
||||
awaitLinks(
|
||||
remoteMediaClient?.queueAppendItem(
|
||||
MediaQueueItem.Builder(mediaInfo).build(),
|
||||
JSONObject()
|
||||
)
|
||||
) {
|
||||
println("FAILED TO LOAD NEXT ITEM")
|
||||
// loadIndex(1)
|
||||
}
|
||||
|
|
|
@ -147,11 +147,11 @@ class EpisodeAdapter(
|
|||
clickCallback.invoke(EpisodeClickEvent(ACTION_CHROME_CAST_EPISODE, card))
|
||||
} else {
|
||||
// clickCallback.invoke(EpisodeClickEvent(ACTION_PLAY_EPISODE_IN_PLAYER, card))
|
||||
clickCallback.invoke(EpisodeClickEvent(ACTION_DOWNLOAD_EPISODE, card))
|
||||
clickCallback.invoke(EpisodeClickEvent(ACTION_PLAY_EPISODE_IN_PLAYER, card))
|
||||
}
|
||||
} else {
|
||||
// clickCallback.invoke(EpisodeClickEvent(ACTION_PLAY_EPISODE_IN_PLAYER, card))
|
||||
clickCallback.invoke(EpisodeClickEvent(ACTION_DOWNLOAD_EPISODE, card))
|
||||
clickCallback.invoke(EpisodeClickEvent(ACTION_PLAY_EPISODE_IN_PLAYER, card))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -206,7 +206,7 @@ class ResultViewModel : ViewModel() {
|
|||
}
|
||||
val links = ArrayList<ExtractorLink>()
|
||||
val localData = safeApiCall {
|
||||
getApiFromName(_apiName.value).loadLinks(data, isCasting) {
|
||||
getApiFromName(_apiName.value).loadLinks(data, isCasting, { subtitleFile -> }) {
|
||||
for (i in links) {
|
||||
if (i.url == it.url) return@loadLinks
|
||||
}
|
||||
|
|
|
@ -148,7 +148,7 @@ class SearchFragment : Fragment() {
|
|||
allApi.providersActive = requireActivity().getApiSettings()
|
||||
|
||||
//searchViewModel.search("iron man")
|
||||
(activity as AppCompatActivity).loadResult("https://shiro.is/overlord-dubbed", "overlord-dubbed", "Shiro")
|
||||
//(activity as AppCompatActivity).loadResult("https://shiro.is/overlord-dubbed", "overlord-dubbed", "Shiro")
|
||||
/*
|
||||
(requireActivity() as AppCompatActivity).supportFragmentManager.beginTransaction()
|
||||
.setCustomAnimations(R.anim.enter_anim,
|
||||
|
|
|
@ -7,7 +7,7 @@ object M3u8Manifest {
|
|||
val data: ArrayList<Pair<String, String>> = ArrayList()
|
||||
"\"(.*?)\":\"(.*?)\"".toRegex().findAll(m3u8Data).forEach {
|
||||
var quality = it.groupValues[1].replace("auto", "Auto")
|
||||
if (quality != "Auto") quality += "p"
|
||||
if (quality != "Auto" && !quality.endsWith('p')) quality += "p"
|
||||
val url = it.groupValues[2]
|
||||
data.add(Pair(url, quality))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue