forked from recloudstream/cloudstream
WatchCartoonOnlineProvider
This commit is contained in:
parent
2839d59a28
commit
a0ad101605
18 changed files with 354 additions and 41 deletions
|
@ -94,4 +94,7 @@ dependencies {
|
|||
|
||||
// subtitle color picker
|
||||
implementation 'com.jaredrummler:colorpicker:1.1.0'
|
||||
|
||||
//run JS
|
||||
implementation 'org.mozilla:rhino:1.7R4'
|
||||
}
|
|
@ -6,17 +6,18 @@ import com.fasterxml.jackson.databind.DeserializationFeature
|
|||
import com.fasterxml.jackson.databind.json.JsonMapper
|
||||
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
||||
import com.lagradost.cloudstream3.animeproviders.DubbedAnimeProvider
|
||||
import com.lagradost.cloudstream3.animeproviders.ShiroProvider
|
||||
import com.lagradost.cloudstream3.animeproviders.TenshiProvider
|
||||
import com.lagradost.cloudstream3.animeproviders.WatchCartoonOnlineProvider
|
||||
import com.lagradost.cloudstream3.animeproviders.WcoProvider
|
||||
import com.lagradost.cloudstream3.movieproviders.HDMProvider
|
||||
import com.lagradost.cloudstream3.movieproviders.MeloMovieProvider
|
||||
import com.lagradost.cloudstream3.movieproviders.TrailersToProvider
|
||||
import com.lagradost.cloudstream3.movieproviders.VMoveeProvider
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
import java.util.*
|
||||
|
||||
const val USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; rv:68.0) Gecko/20100101 Firefox/68.0"
|
||||
|
||||
const val USER_AGENT =
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
|
||||
val baseHeader = mapOf("User-Agent" to USER_AGENT)
|
||||
val mapper = JsonMapper.builder().addModule(KotlinModule())
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).build()!!
|
||||
|
@ -37,6 +38,7 @@ object APIHolder {
|
|||
HDMProvider(),
|
||||
//LookMovieProvider(), // RECAPTCHA (Please allow up to 5 seconds...)
|
||||
VMoveeProvider(),
|
||||
WatchCartoonOnlineProvider(),
|
||||
)
|
||||
|
||||
fun getApiFromName(apiName: String?): MainAPI {
|
||||
|
@ -86,6 +88,14 @@ abstract class MainAPI {
|
|||
open val hasMainPage = false
|
||||
open val hasQuickSearch = false
|
||||
|
||||
open val supportedTypes = setOf(
|
||||
TvType.Movie,
|
||||
TvType.TvSeries,
|
||||
TvType.Cartoon,
|
||||
TvType.Anime,
|
||||
TvType.ONA
|
||||
)
|
||||
|
||||
open fun getMainPage(): HomePageResponse? {
|
||||
return null
|
||||
}
|
||||
|
@ -177,6 +187,7 @@ enum class DubStatus {
|
|||
enum class TvType {
|
||||
Movie,
|
||||
TvSeries,
|
||||
Cartoon,
|
||||
Anime,
|
||||
ONA,
|
||||
}
|
||||
|
@ -255,7 +266,7 @@ interface LoadResponse {
|
|||
val year: Int?
|
||||
val plot: String?
|
||||
val rating: Int? // 0-100
|
||||
val tags: ArrayList<String>?
|
||||
val tags: List<String>?
|
||||
val duration: String?
|
||||
val trailerUrl: String?
|
||||
}
|
||||
|
@ -290,13 +301,13 @@ data class AnimeLoadResponse(
|
|||
override val posterUrl: String?,
|
||||
override val year: Int?,
|
||||
|
||||
val dubEpisodes: ArrayList<AnimeEpisode>?,
|
||||
val subEpisodes: ArrayList<AnimeEpisode>?,
|
||||
val dubEpisodes: List<AnimeEpisode>?,
|
||||
val subEpisodes: List<AnimeEpisode>?,
|
||||
val showStatus: ShowStatus?,
|
||||
|
||||
override val plot: String?,
|
||||
override val tags: ArrayList<String>? = null,
|
||||
val synonyms: ArrayList<String>? = null,
|
||||
override val tags: List<String>? = null,
|
||||
val synonyms: List<String>? = null,
|
||||
|
||||
val malId: Int? = null,
|
||||
val anilistId: Int? = null,
|
||||
|
@ -318,7 +329,7 @@ data class MovieLoadResponse(
|
|||
|
||||
val imdbId: String?,
|
||||
override val rating: Int? = null,
|
||||
override val tags: ArrayList<String>? = null,
|
||||
override val tags: List<String>? = null,
|
||||
override val duration: String? = null,
|
||||
override val trailerUrl: String? = null,
|
||||
) : LoadResponse
|
||||
|
@ -339,7 +350,7 @@ data class TvSeriesLoadResponse(
|
|||
override val url: String,
|
||||
override val apiName: String,
|
||||
override val type: TvType,
|
||||
val episodes: ArrayList<TvSeriesEpisode>,
|
||||
val episodes: List<TvSeriesEpisode>,
|
||||
|
||||
override val posterUrl: String?,
|
||||
override val year: Int?,
|
||||
|
@ -348,7 +359,7 @@ data class TvSeriesLoadResponse(
|
|||
val showStatus: ShowStatus?,
|
||||
val imdbId: String?,
|
||||
override val rating: Int? = null,
|
||||
override val tags: ArrayList<String>? = null,
|
||||
override val tags: List<String>? = null,
|
||||
override val duration: String? = null,
|
||||
override val trailerUrl: String? = null,
|
||||
) : LoadResponse
|
||||
|
|
|
@ -18,6 +18,12 @@ class DubbedAnimeProvider : MainAPI() {
|
|||
override val hasQuickSearch: Boolean
|
||||
get() = true
|
||||
|
||||
override val supportedTypes: Set<TvType>
|
||||
get() = setOf(
|
||||
TvType.Movie,
|
||||
TvType.Anime,
|
||||
)
|
||||
|
||||
data class QueryEpisodeResultRoot(
|
||||
@JsonProperty("result")
|
||||
val result: QueryEpisodeResult,
|
||||
|
|
|
@ -160,7 +160,7 @@ class ShiroProvider : MainAPI() {
|
|||
val set: EnumSet<DubStatus> =
|
||||
EnumSet.of(if (isDubbed) DubStatus.Dubbed else DubStatus.Subbed)
|
||||
|
||||
val episodeCount = data.episodeCount?.toIntOrNull()
|
||||
val episodeCount = data.episodeCount.toIntOrNull()
|
||||
|
||||
return@map AnimeSearchResponse(
|
||||
data.name.replace("Dubbed", ""), // i.english ?: i.canonicalTitle,
|
||||
|
|
|
@ -29,6 +29,9 @@ class TenshiProvider : MainAPI() {
|
|||
override val hasQuickSearch: Boolean
|
||||
get() = false
|
||||
|
||||
override val supportedTypes: Set<TvType>
|
||||
get() = setOf(TvType.Anime, TvType.Movie, TvType.ONA)
|
||||
|
||||
private fun autoLoadToken(): Boolean {
|
||||
if (token != null) return true
|
||||
return loadToken()
|
||||
|
@ -91,7 +94,11 @@ class TenshiProvider : MainAPI() {
|
|||
private fun dateParser(dateString: String): String? {
|
||||
val format = SimpleDateFormat("dd 'of' MMM',' yyyy")
|
||||
val newFormat = SimpleDateFormat("dd-MM-yyyy")
|
||||
return newFormat.format(format.parse(dateString.replace("th ", " ").replace("st ", " ").replace("nd ", " ").replace("rd ", " ")))
|
||||
return newFormat.format(
|
||||
format.parse(
|
||||
dateString.replace("th ", " ").replace("st ", " ").replace("nd ", " ").replace("rd ", " ")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// data class TenshiSearchResponse(
|
||||
|
@ -147,14 +154,14 @@ class TenshiProvider : MainAPI() {
|
|||
|
||||
override fun search(query: String): ArrayList<SearchResponse> {
|
||||
val url = "$mainUrl/anime"
|
||||
var response = khttp.get(url, params=mapOf("q" to query), cookies=mapOf("loop-view" to "thumb"))
|
||||
var response = khttp.get(url, params = mapOf("q" to query), cookies = mapOf("loop-view" to "thumb"))
|
||||
var document = Jsoup.parse(response.text)
|
||||
val returnValue = parseSearchPage(document)
|
||||
|
||||
while (!document.select("""a.page-link[rel="next"]""").isEmpty()) {
|
||||
val link = document.select("""a.page-link[rel="next"]""")
|
||||
if (link != null && !link.isEmpty()) {
|
||||
response = khttp.get(link[0].attr("href"), cookies=mapOf("loop-view" to "thumb"))
|
||||
response = khttp.get(link[0].attr("href"), cookies = mapOf("loop-view" to "thumb"))
|
||||
document = Jsoup.parse(response.text)
|
||||
returnValue.addAll(parseSearchPage(document))
|
||||
} else {
|
||||
|
@ -166,7 +173,7 @@ class TenshiProvider : MainAPI() {
|
|||
}
|
||||
|
||||
override fun load(url: String): LoadResponse {
|
||||
val response = khttp.get(url, timeout = 120.0, cookies=mapOf("loop-view" to "thumb"))
|
||||
val response = khttp.get(url, timeout = 120.0, cookies = mapOf("loop-view" to "thumb"))
|
||||
val document = Jsoup.parse(response.text)
|
||||
|
||||
val englishTitle = document.selectFirst("span.value > span[title=\"English\"]")?.parent()?.text()?.trim()
|
||||
|
@ -183,7 +190,8 @@ class TenshiProvider : MainAPI() {
|
|||
dateParser(it.selectFirst(".episode-date").text().trim()).toString(),
|
||||
null,
|
||||
it.attr("data-content").trim(),
|
||||
) }
|
||||
)
|
||||
}
|
||||
?: ArrayList<AnimeEpisode>())
|
||||
val status = when (document.selectFirst("li.status > .value")?.text()?.trim()) {
|
||||
"Ongoing" -> ShowStatus.Ongoing
|
||||
|
@ -200,7 +208,8 @@ class TenshiProvider : MainAPI() {
|
|||
val synopsis = document.selectFirst(".entry-description > .card-body")?.text()?.trim()
|
||||
val genre = document.select("li.genre.meta-data > span.value").map { it?.text()?.trim().toString() }
|
||||
|
||||
val synonyms = document.select("li.synonym.meta-data > div.info-box > span.value").map { it?.text()?.trim().toString() }
|
||||
val synonyms =
|
||||
document.select("li.synonym.meta-data > div.info-box > span.value").map { it?.text()?.trim().toString() }
|
||||
|
||||
return AnimeLoadResponse(
|
||||
englishTitle,
|
||||
|
@ -231,7 +240,7 @@ class TenshiProvider : MainAPI() {
|
|||
): Boolean {
|
||||
val response = khttp.get(data)
|
||||
val src = Jsoup.parse(response.text).selectFirst(".embed-responsive > iframe").attr("src")
|
||||
val mp4moe = Jsoup.parse(khttp.get(src, headers=mapOf("Referer" to data)).text).selectFirst("video#player")
|
||||
val mp4moe = Jsoup.parse(khttp.get(src, headers = mapOf("Referer" to data)).text).selectFirst("video#player")
|
||||
|
||||
val sources = mp4moe.select("source").map {
|
||||
ExtractorLink(
|
||||
|
|
|
@ -0,0 +1,224 @@
|
|||
package com.lagradost.cloudstream3.animeproviders
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import com.fasterxml.jackson.module.kotlin.readValue
|
||||
import com.lagradost.cloudstream3.*
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
import com.lagradost.cloudstream3.utils.Qualities
|
||||
import org.jsoup.Jsoup
|
||||
import org.mozilla.javascript.Context
|
||||
import org.mozilla.javascript.Scriptable
|
||||
import java.util.*
|
||||
|
||||
|
||||
class WatchCartoonOnlineProvider : MainAPI() {
|
||||
override val name: String
|
||||
get() = "WatchCartoonOnline"
|
||||
override val mainUrl: String
|
||||
get() = "https://www.wcostream.com"
|
||||
|
||||
override val supportedTypes: Set<TvType>
|
||||
get() = setOf(
|
||||
TvType.Cartoon,
|
||||
TvType.Anime,
|
||||
)
|
||||
|
||||
override fun search(query: String): ArrayList<SearchResponse>? {
|
||||
val url = "https://www.wcostream.com/search"
|
||||
|
||||
val response =
|
||||
khttp.post(
|
||||
url,
|
||||
headers = mapOf("Referer" to url),
|
||||
data = mapOf("catara" to query, "konuara" to "series")
|
||||
)
|
||||
val document = Jsoup.parse(response.text)
|
||||
val items = document.select("div#blog > div.cerceve")
|
||||
if (items.isNullOrEmpty()) return ArrayList()
|
||||
val returnValue = ArrayList<SearchResponse>()
|
||||
|
||||
for (item in items) {
|
||||
val header = item.selectFirst("> div.iccerceve")
|
||||
val titleHeader = header.selectFirst("> div.aramadabaslik > a")
|
||||
val title = titleHeader.text()
|
||||
val href = fixUrl(titleHeader.attr("href"))
|
||||
val poster = fixUrl(header.selectFirst("> a > img").attr("src"))
|
||||
val genreText = item.selectFirst("div.cerceve-tur-ve-genre").ownText()
|
||||
if (genreText.contains("cartoon")) {
|
||||
returnValue.add(TvSeriesSearchResponse(title, href, this.name, TvType.Cartoon, poster, null, null))
|
||||
} else {
|
||||
val isDubbed = genreText.contains("dubbed")
|
||||
val set: EnumSet<DubStatus> =
|
||||
EnumSet.of(if (isDubbed) DubStatus.Dubbed else DubStatus.Subbed)
|
||||
returnValue.add(
|
||||
AnimeSearchResponse(
|
||||
title,
|
||||
href,
|
||||
this.name,
|
||||
TvType.Anime,
|
||||
poster,
|
||||
null,
|
||||
null,
|
||||
set,
|
||||
null,
|
||||
null
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
return returnValue
|
||||
}
|
||||
|
||||
override fun load(url: String): LoadResponse? {
|
||||
val response = khttp.get(url)
|
||||
val document = Jsoup.parse(response.text)
|
||||
|
||||
val title = document.selectFirst("td.vsbaslik > h2").text()
|
||||
val poster = fixUrl(document.selectFirst("div#cat-img-desc > div > img").attr("src"))
|
||||
val plot = document.selectFirst("div.iltext").text()
|
||||
val genres = document.select("div#cat-genre > div.wcobtn > a").map { it.text() }
|
||||
val episodes = document.select("div#catlist-listview > ul > li > a").reversed().map {
|
||||
val text = it.text()
|
||||
val match = Regex("Season ([0-9]*) Episode ([0-9]*).*? (.*)").find(text)
|
||||
val href = it.attr("href")
|
||||
if (match != null) {
|
||||
val last = match.groupValues[3]
|
||||
return@map TvSeriesEpisode(
|
||||
if (last.startsWith("English")) null else last,
|
||||
match.groupValues[1].toIntOrNull(),
|
||||
match.groupValues[2].toIntOrNull(),
|
||||
href
|
||||
)
|
||||
}
|
||||
val match2 = Regex("Episode ([0-9]*).*? (.*)").find(text)
|
||||
if (match2 != null) {
|
||||
val last = match2.groupValues[2]
|
||||
return@map TvSeriesEpisode(
|
||||
if (last.startsWith("English")) null else last,
|
||||
null,
|
||||
match2.groupValues[1].toIntOrNull(),
|
||||
href
|
||||
)
|
||||
}
|
||||
return@map TvSeriesEpisode(
|
||||
text,
|
||||
null,
|
||||
null,
|
||||
href
|
||||
)
|
||||
}
|
||||
|
||||
return TvSeriesLoadResponse(
|
||||
title,
|
||||
url,
|
||||
this.name,
|
||||
TvType.TvSeries,
|
||||
episodes,
|
||||
poster,
|
||||
null,
|
||||
plot,
|
||||
null,
|
||||
null,
|
||||
tags = genres
|
||||
)
|
||||
}
|
||||
|
||||
data class LinkResponse(
|
||||
// @JsonProperty("cdn")
|
||||
// val cdn: String,
|
||||
@JsonProperty("enc")
|
||||
val enc: String,
|
||||
@JsonProperty("hd")
|
||||
val hd: String,
|
||||
@JsonProperty("server")
|
||||
val server: String,
|
||||
)
|
||||
|
||||
override fun loadLinks(
|
||||
data: String,
|
||||
isCasting: Boolean,
|
||||
subtitleCallback: (SubtitleFile) -> Unit,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
): Boolean {
|
||||
val response = khttp.get(data)
|
||||
/*val embedUrl = fixUrl(
|
||||
Regex("itemprop=\"embedURL\" content=\"(.*?)\"").find(response.text)?.groupValues?.get(1) ?: return false
|
||||
)*/
|
||||
val text = response.text
|
||||
val start = text.indexOf("itemprop=\"embedURL")
|
||||
val foundJS = Regex("<script>(.*?)</script>").find(text, start)?.groupValues?.get(1)
|
||||
?.replace("document.write", "var returnValue = ")
|
||||
println("JS: $foundJS")
|
||||
val rhino = Context.enter()
|
||||
rhino.initStandardObjects()
|
||||
rhino.optimizationLevel = -1
|
||||
val scope: Scriptable = rhino.initStandardObjects()
|
||||
|
||||
val decodeBase64 = "atob = function(s) {\n" +
|
||||
" var e={},i,b=0,c,x,l=0,a,r='',w=String.fromCharCode,L=s.length;\n" +
|
||||
" var A=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n" +
|
||||
" for(i=0;i<64;i++){e[A.charAt(i)]=i;}\n" +
|
||||
" for(x=0;x<L;x++){\n" +
|
||||
" c=e[s.charAt(x)];b=(b<<6)+c;l+=6;\n" +
|
||||
" while(l>=8){((a=(b>>>(l-=8))&0xff)||(x<(L-2)))&&(r+=w(a));}\n" +
|
||||
" }\n" +
|
||||
" return r;\n" +
|
||||
"};"
|
||||
|
||||
rhino.evaluateString(scope, decodeBase64 + foundJS, "JavaScript", 1, null)
|
||||
val jsEval = scope.get("returnValue", scope) ?: return false
|
||||
val src = fixUrl(Regex("src=\"(.*?)\"").find(jsEval as String)?.groupValues?.get(1) ?: return false)
|
||||
|
||||
val embedResponse = khttp.get(
|
||||
(src),
|
||||
headers = mapOf("Referer" to data)
|
||||
)
|
||||
|
||||
val getVidLink = fixUrl(
|
||||
Regex("get\\(\"(.*?)\"").find(embedResponse.text)?.groupValues?.get(1) ?: return false
|
||||
)
|
||||
val linkResponse = khttp.get(
|
||||
getVidLink, headers = mapOf(
|
||||
"sec-ch-ua" to "\"Chromium\";v=\"91\", \" Not;A Brand\";v=\"99\"",
|
||||
"sec-ch-ua-mobile" to "?0",
|
||||
"sec-fetch-dest" to "empty",
|
||||
"sec-fetch-mode" to "cors",
|
||||
"sec-fetch-site" to "same-origin",
|
||||
"accept" to "*/*",
|
||||
"x-requested-with" to "XMLHttpRequest",
|
||||
"referer" to src.replace(" ", "%20"),
|
||||
"user-agent" to "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
|
||||
"cookie" to "countrytabs=0"
|
||||
)
|
||||
)
|
||||
println("LINK:" + linkResponse.text)
|
||||
val link = mapper.readValue<LinkResponse>(linkResponse.text)
|
||||
|
||||
val hdLink = "${link.server}/getvid?evid=${link.hd}"
|
||||
val sdLink = "${link.server}/getvid?evid=${link.enc}"
|
||||
|
||||
if (link.hd.isNotBlank())
|
||||
callback.invoke(
|
||||
ExtractorLink(
|
||||
this.name,
|
||||
this.name + " HD",
|
||||
hdLink,
|
||||
"",
|
||||
Qualities.HD.value
|
||||
)
|
||||
)
|
||||
|
||||
if (link.enc.isNotBlank())
|
||||
callback.invoke(
|
||||
ExtractorLink(
|
||||
this.name,
|
||||
this.name + " SD",
|
||||
sdLink,
|
||||
"",
|
||||
Qualities.SD.value
|
||||
)
|
||||
)
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
|
@ -27,6 +27,13 @@ class WcoProvider : MainAPI() {
|
|||
override val hasMainPage: Boolean
|
||||
get() = true
|
||||
|
||||
override val supportedTypes: Set<TvType>
|
||||
get() = setOf(
|
||||
TvType.Movie,
|
||||
TvType.Anime,
|
||||
TvType.ONA
|
||||
)
|
||||
|
||||
override fun getMainPage(): HomePageResponse? {
|
||||
val urls = listOf(
|
||||
Pair("$mainUrl/ajax/list/recently_updated?type=tv", "Recently Updated Anime"),
|
||||
|
|
|
@ -13,6 +13,11 @@ class HDMProvider : MainAPI() {
|
|||
override val hasDownloadSupport: Boolean
|
||||
get() = false
|
||||
|
||||
override val supportedTypes: Set<TvType>
|
||||
get() = setOf(
|
||||
TvType.Movie,
|
||||
)
|
||||
|
||||
override fun search(query: String): ArrayList<SearchResponse> {
|
||||
val url = "$mainUrl/search/$query"
|
||||
val response = khttp.get(url)
|
||||
|
|
|
@ -20,6 +20,12 @@ class LookMovieProvider : MainAPI() {
|
|||
override val mainUrl: String
|
||||
get() = "https://lookmovie.io"
|
||||
|
||||
override val supportedTypes: Set<TvType>
|
||||
get() = setOf(
|
||||
TvType.Movie,
|
||||
TvType.TvSeries,
|
||||
)
|
||||
|
||||
data class LookMovieSearchResult(
|
||||
@JsonProperty("backdrop") val backdrop: String?,
|
||||
@JsonProperty("imdb_rating") val imdb_rating: String,
|
||||
|
|
|
@ -23,6 +23,12 @@ class TrailersToProvider : MainAPI() {
|
|||
override val hasChromecastSupport: Boolean
|
||||
get() = false
|
||||
|
||||
override val supportedTypes: Set<TvType>
|
||||
get() = setOf(
|
||||
TvType.Movie,
|
||||
TvType.TvSeries,
|
||||
)
|
||||
|
||||
override fun getMainPage(): HomePageResponse? {
|
||||
val response = khttp.get(mainUrl)
|
||||
val document = Jsoup.parse(response.text)
|
||||
|
|
|
@ -14,6 +14,11 @@ class VMoveeProvider : MainAPI() {
|
|||
override val mainUrl: String
|
||||
get() = "https://www.vmovee.watch"
|
||||
|
||||
override val supportedTypes: Set<TvType>
|
||||
get() = setOf(
|
||||
TvType.Movie,
|
||||
)
|
||||
|
||||
override fun search(query: String): ArrayList<SearchResponse>? {
|
||||
val url = "$mainUrl/?s=$query"
|
||||
val response = khttp.get(url)
|
||||
|
|
|
@ -61,6 +61,7 @@ class HomeChildItemAdapter(
|
|||
TvType.Movie -> "Movie"
|
||||
TvType.ONA -> "ONA"
|
||||
TvType.TvSeries -> "TV"
|
||||
TvType.Cartoon -> "Cartoon"
|
||||
}
|
||||
// search_result_lang?.visibility = View.GONE
|
||||
|
||||
|
|
|
@ -796,7 +796,7 @@ class PlayerFragment : Fragment() {
|
|||
}
|
||||
//endregion
|
||||
|
||||
private fun onSubStyleChanged(style : SaveCaptionStyle) {
|
||||
private fun onSubStyleChanged(style: SaveCaptionStyle) {
|
||||
context?.let { ctx ->
|
||||
subStyle = style
|
||||
subView?.setStyle(ctx.fromSaveToStyle(style))
|
||||
|
@ -1131,7 +1131,7 @@ class PlayerFragment : Fragment() {
|
|||
val speedsNumbers = listOf(0.5f, 0.75f, 1f, 1.25f, 1.5f, 1.75f, 2f)
|
||||
val speedIndex = speedsNumbers.indexOf(playbackSpeed)
|
||||
|
||||
context?.showDialog(speedsText,speedIndex,"Player Speed", false, {
|
||||
context?.showDialog(speedsText, speedIndex, "Player Speed", false, {
|
||||
activity?.hideSystemUI()
|
||||
}) { index ->
|
||||
playbackSpeed = speedsNumbers[index]
|
||||
|
@ -1541,8 +1541,19 @@ class PlayerFragment : Fragment() {
|
|||
/*FastAniApi.currentHeaders?.forEach {
|
||||
dataSource.setRequestProperty(it.key, it.value)
|
||||
}*/
|
||||
if (currentUrl != null)
|
||||
if (currentUrl != null) {
|
||||
dataSource.setRequestProperty("Referer", currentUrl.referer)
|
||||
// extra stuff
|
||||
dataSource.setRequestProperty(
|
||||
"sec-ch-ua",
|
||||
"\"Chromium\";v=\"91\", \" Not;A Brand\";v=\"99\""
|
||||
)
|
||||
dataSource.setRequestProperty("sec-ch-ua-mobile", "?0")
|
||||
// dataSource.setRequestProperty("Sec-Fetch-Site", "none") //same-site
|
||||
dataSource.setRequestProperty("Sec-Fetch-User", "?1")
|
||||
dataSource.setRequestProperty("Sec-Fetch-Mode", "navigate")
|
||||
dataSource.setRequestProperty("Sec-Fetch-Dest", "document")
|
||||
}
|
||||
dataSource
|
||||
} else {
|
||||
DefaultDataSourceFactory(requireContext(), USER_AGENT).createDataSource()
|
||||
|
|
|
@ -238,14 +238,14 @@ class ResultFragment : Fragment() {
|
|||
var startAction: Int? = null
|
||||
|
||||
private fun lateFixDownloadButton(show: Boolean) {
|
||||
if (show) {
|
||||
result_movie_parent.visibility = VISIBLE
|
||||
result_episodes_text.visibility = GONE
|
||||
result_episodes.visibility = GONE
|
||||
} else {
|
||||
if(!show || currentType?.isMovieType() == true) {
|
||||
result_movie_parent.visibility = GONE
|
||||
result_episodes_text.visibility = VISIBLE
|
||||
result_episodes.visibility = VISIBLE
|
||||
} else {
|
||||
result_movie_parent.visibility = VISIBLE
|
||||
result_episodes_text.visibility = GONE
|
||||
result_episodes.visibility = GONE
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -430,6 +430,7 @@ class ResultFragment : Fragment() {
|
|||
TvType.Movie -> "Movies"
|
||||
TvType.TvSeries -> "TVSeries/$titleName"
|
||||
TvType.ONA -> "ONA"
|
||||
TvType.Cartoon -> "Cartoons/$titleName"
|
||||
else -> null
|
||||
}
|
||||
|
||||
|
|
|
@ -119,7 +119,6 @@ class ResultViewModel : ViewModel() {
|
|||
rangeList.add("${i + 1}-${currentList.size}")
|
||||
}
|
||||
}
|
||||
_rangeOptions.postValue(rangeList)
|
||||
|
||||
val cRange = range ?: if (selection != null) {
|
||||
0
|
||||
|
@ -133,14 +132,19 @@ class ResultViewModel : ViewModel() {
|
|||
cRange
|
||||
}
|
||||
|
||||
selectedRangeInt.postValue(realRange)
|
||||
selectedRange.postValue(rangeList[realRange])
|
||||
|
||||
if (currentList.size > EPISODE_RANGE_OVERLOAD) {
|
||||
currentList = currentList.subList(
|
||||
realRange * EPISODE_RANGE_SIZE,
|
||||
minOf(currentList.size, (realRange + 1) * EPISODE_RANGE_SIZE)
|
||||
)
|
||||
_rangeOptions.postValue(rangeList)
|
||||
selectedRangeInt.postValue(realRange)
|
||||
selectedRange.postValue(rangeList[realRange])
|
||||
} else {
|
||||
val allRange ="1-${currentList.size}"
|
||||
_rangeOptions.postValue(listOf(allRange))
|
||||
selectedRangeInt.postValue(0)
|
||||
selectedRange.postValue(allRange)
|
||||
}
|
||||
|
||||
_publicEpisodes.postValue(currentList)
|
||||
|
|
|
@ -50,7 +50,6 @@ class SearchAdapter(
|
|||
is CardViewHolder -> {
|
||||
holder.bind(cardList[position])
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,6 +93,7 @@ class SearchAdapter(
|
|||
TvType.Movie -> "Movie"
|
||||
TvType.ONA -> "ONA"
|
||||
TvType.TvSeries -> "TV"
|
||||
TvType.Cartoon -> "Cartoon"
|
||||
}
|
||||
// search_result_lang?.visibility = View.GONE
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ object VideoDownloadManager {
|
|||
private var currentDownloads = mutableListOf<Int>()
|
||||
|
||||
private const val USER_AGENT =
|
||||
"Mozilla/5.0 (Windows NT 10.0; rv:68.0) Gecko/20100101 Firefox/68.0"
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
|
||||
|
||||
@DrawableRes
|
||||
const val imgDone = R.drawable.rddone
|
||||
|
@ -511,6 +511,18 @@ object VideoDownloadManager {
|
|||
connection.setRequestProperty("Accept-Encoding", "identity")
|
||||
connection.setRequestProperty("User-Agent", USER_AGENT)
|
||||
if (link.referer.isNotEmpty()) connection.setRequestProperty("Referer", link.referer)
|
||||
|
||||
// extra stuff
|
||||
connection.setRequestProperty(
|
||||
"sec-ch-ua",
|
||||
"\"Chromium\";v=\"91\", \" Not;A Brand\";v=\"99\""
|
||||
)
|
||||
connection.setRequestProperty("sec-ch-ua-mobile", "?0")
|
||||
// dataSource.setRequestProperty("Sec-Fetch-Site", "none") //same-site
|
||||
connection.setRequestProperty("Sec-Fetch-User", "?1")
|
||||
connection.setRequestProperty("Sec-Fetch-Mode", "navigate")
|
||||
connection.setRequestProperty("Sec-Fetch-Dest", "document")
|
||||
|
||||
if (resume)
|
||||
connection.setRequestProperty("Range", "bytes=${fileLength}-")
|
||||
val resumeLength = (if (resume) fileLength else 0)
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
android:screenOrientation="userLandscape"
|
||||
app:surface_type="texture_view"
|
||||
>
|
||||
<!--
|
||||
app:fastforward_increment="10000"
|
||||
app:rewind_increment="10000"-->
|
||||
<com.google.android.exoplayer2.ui.PlayerView
|
||||
android:id="@+id/player_view"
|
||||
app:show_timeout="0"
|
||||
|
@ -18,8 +21,7 @@
|
|||
app:auto_show="true"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:fastforward_increment="10000"
|
||||
app:rewind_increment="10000"
|
||||
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
|
Loading…
Reference in a new issue