From 9fc732c68c0d0c34c8cd51691e487d711a9526c6 Mon Sep 17 00:00:00 2001 From: LagradOst Date: Thu, 1 Jul 2021 22:11:33 +0200 Subject: [PATCH] small subtitle support --- .../com/lagradost/cloudstream3/MainAPI.kt | 4 +- .../animeproviders/DubbedAnimeProvider.kt | 45 +++-- .../animeproviders/ShiroProvider.kt | 35 ++-- .../movieproviders/HDMProvider.kt | 31 ++-- .../movieproviders/LookMovieProvider.kt | 154 +++++++++++++----- .../movieproviders/MeloMovieProvider.kt | 59 ++++--- .../movieproviders/TrailersToProvider.kt | 19 ++- .../cloudstream3/ui/ControllerActivity.kt | 33 ++-- .../cloudstream3/ui/result/EpisodeAdapter.kt | 4 +- .../cloudstream3/ui/result/ResultViewModel.kt | 2 +- .../cloudstream3/ui/search/SearchFragment.kt | 2 +- .../utils/extractors/M3u8Manifest.kt | 2 +- 12 files changed, 266 insertions(+), 124 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt index bfdba811..9d474b81 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt @@ -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 diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/DubbedAnimeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/DubbedAnimeProvider.kt index 570892bb..037cb62b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/DubbedAnimeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/DubbedAnimeProvider.kt @@ -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) diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ShiroProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ShiroProvider.kt index 47de0223..9397e122 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ShiroProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ShiroProvider.kt @@ -167,12 +167,14 @@ class ShiroProvider : MainAPI() { override fun quickSearch(query: String): ArrayList { val returnValue: ArrayList = 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(it.text) } @@ -185,12 +187,14 @@ class ShiroProvider : MainAPI() { override fun search(query: String): ArrayList? { if (!autoLoadToken()) return null val returnValue: ArrayList = 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(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) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/HDMProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/HDMProvider.kt index 90511ec1..b0e4b5be 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/HDMProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/HDMProvider.kt @@ -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 + ) } } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/LookMovieProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/LookMovieProvider.kt index f4ed554d..cde12366 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/LookMovieProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/LookMovieProvider.kt @@ -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?, 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(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>(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(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(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>(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 + ) } } } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/MeloMovieProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/MeloMovieProvider.kt index 45c0dfba..402edc03 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/MeloMovieProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/MeloMovieProvider.kt @@ -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>(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() 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 } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TrailersToProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TrailersToProvider.kt index e4b979f1..36679146 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TrailersToProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TrailersToProvider.kt @@ -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 + ) } } } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt index d3102d49..6ff1c355 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt @@ -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() 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) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt index 4eb3a7fb..0b4980d4 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt @@ -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)) } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel.kt index 3d843a3d..ec98cce5 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel.kt @@ -206,7 +206,7 @@ class ResultViewModel : ViewModel() { } val links = ArrayList() 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 } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt index e656fc4b..b9a9643a 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt @@ -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, diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/M3u8Manifest.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/M3u8Manifest.kt index 13547bf6..2a8be68d 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/M3u8Manifest.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/M3u8Manifest.kt @@ -7,7 +7,7 @@ object M3u8Manifest { val data: ArrayList> = 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)) }