mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
f055b55e89
96 changed files with 1084 additions and 492 deletions
4
.github/site-list.py
vendored
4
.github/site-list.py
vendored
|
@ -6,14 +6,14 @@ from typing import List, Dict
|
||||||
|
|
||||||
# Globals
|
# Globals
|
||||||
URL_REGEX = compile(
|
URL_REGEX = compile(
|
||||||
"override val mainUrl(?:\:\s?String)?[^\"']+[\"'](https?://[a-zA-Z0-9\.-]+)[\"']")
|
"override\sva[lr]\smainUrl[^\"']+[\"'](https?://[a-zA-Z0-9\.-]+)[\"']")
|
||||||
NAME_REGEX = compile("class (.+?) ?: \w+\(\)\s\{")
|
NAME_REGEX = compile("class (.+?) ?: \w+\(\)\s\{")
|
||||||
START_MARKER = "<!--SITE LIST START-->"
|
START_MARKER = "<!--SITE LIST START-->"
|
||||||
END_MARKER = "<!--SITE LIST END-->"
|
END_MARKER = "<!--SITE LIST END-->"
|
||||||
GLOB = "app/src/main/java/com/lagradost/cloudstream3/*providers/*Provider.kt"
|
GLOB = "app/src/main/java/com/lagradost/cloudstream3/*providers/*Provider.kt"
|
||||||
MAIN_API = "app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt"
|
MAIN_API = "app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt"
|
||||||
API_REGEX = compile(
|
API_REGEX = compile(
|
||||||
"val (?:restrictedA|a)pis = arrayListOf\((.+?)\)(?=\n\n)", DOTALL)
|
"val\s*allProviders.*?{\s.*?arrayListOf\(([\W\w]*?)\)\s*\n*\s*}", DOTALL)
|
||||||
|
|
||||||
sites: Dict[str, str] = {}
|
sites: Dict[str, str] = {}
|
||||||
enabled_sites: List[str] = []
|
enabled_sites: List[str] = []
|
||||||
|
|
|
@ -98,4 +98,6 @@ It merely scrapes 3rd-party websites that are publicly accessable via any regula
|
||||||
- [9anime.center](https://9anime.center)
|
- [9anime.center](https://9anime.center)
|
||||||
- [animeworld.tv](https://www.animeworld.tv)
|
- [animeworld.tv](https://www.animeworld.tv)
|
||||||
- [asiaflix.app](https://asiaflix.app)
|
- [asiaflix.app](https://asiaflix.app)
|
||||||
|
- [kawaiifu.com](https://kawaiifu.com)
|
||||||
|
- [hdm.to](https://hdm.to)
|
||||||
<!--SITE LIST END-->
|
<!--SITE LIST END-->
|
||||||
|
|
|
@ -6,6 +6,7 @@ import android.net.Uri
|
||||||
import android.util.Base64.encodeToString
|
import android.util.Base64.encodeToString
|
||||||
import androidx.annotation.WorkerThread
|
import androidx.annotation.WorkerThread
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature
|
import com.fasterxml.jackson.databind.DeserializationFeature
|
||||||
import com.fasterxml.jackson.databind.json.JsonMapper
|
import com.fasterxml.jackson.databind.json.JsonMapper
|
||||||
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
||||||
|
@ -31,86 +32,76 @@ object APIHolder {
|
||||||
|
|
||||||
private const val defProvider = 0
|
private const val defProvider = 0
|
||||||
|
|
||||||
val apis = arrayListOf(
|
val allProviders by lazy {
|
||||||
PelisplusProvider(),
|
arrayListOf(
|
||||||
PelisplusHDProvider(),
|
// Movie providers
|
||||||
PeliSmartProvider(),
|
PelisplusProvider(),
|
||||||
GogoanimeProvider(),
|
PelisplusHDProvider(),
|
||||||
AllAnimeProvider(),
|
PeliSmartProvider(),
|
||||||
AnimekisaProvider(),
|
MeloMovieProvider(), // Captcha for links
|
||||||
//ShiroProvider(), // v2 fucked me
|
DoramasYTProvider(),
|
||||||
AnimeFlickProvider(),
|
CinecalidadProvider(),
|
||||||
AnimeflvnetProvider(),
|
CuevanaProvider(),
|
||||||
|
EntrepeliculasyseriesProvider(),
|
||||||
|
PelisflixProvider(),
|
||||||
|
SeriesflixProvider(),
|
||||||
|
IHaveNoTvProvider(), // Documentaries provider
|
||||||
|
LookMovieProvider(), // RECAPTCHA (Please allow up to 5 seconds...)
|
||||||
|
VMoveeProvider(),
|
||||||
|
AllMoviesForYouProvider(),
|
||||||
|
VidEmbedProvider(),
|
||||||
|
VfFilmProvider(),
|
||||||
|
VfSerieProvider(),
|
||||||
|
FrenchStreamProvider(),
|
||||||
|
AsianLoadProvider(),
|
||||||
|
AsiaFlixProvider(), // restricted
|
||||||
|
BflixProvider(),
|
||||||
|
FmoviesToProvider(),
|
||||||
|
SflixProProvider(),
|
||||||
|
FilmanProvider(),
|
||||||
|
SflixProvider(),
|
||||||
|
DopeboxProvider(),
|
||||||
|
SolarmovieProvider(),
|
||||||
|
PinoyMoviePediaProvider(),
|
||||||
|
PinoyHDXyzProvider(),
|
||||||
|
PinoyMoviesEsProvider(),
|
||||||
|
TrailersTwoProvider(),
|
||||||
|
TwoEmbedProvider(),
|
||||||
|
DramaSeeProvider(),
|
||||||
|
WatchAsianProvider(),
|
||||||
|
KdramaHoodProvider(),
|
||||||
|
AkwamProvider(),
|
||||||
|
MyCimaProvider(),
|
||||||
|
EgyBestProvider(),
|
||||||
|
SoaptwoDayProvider(),
|
||||||
|
HDMProvider(),// disabled due to cloudflare
|
||||||
|
|
||||||
TenshiProvider(),
|
// Metadata providers
|
||||||
WcoProvider(),
|
//TmdbProvider(),
|
||||||
// MeloMovieProvider(), // Captcha for links
|
CrossTmdbProvider(),
|
||||||
DubbedAnimeProvider(),
|
ApiMDBProvider(),
|
||||||
DoramasYTProvider(),
|
|
||||||
CinecalidadProvider(),
|
|
||||||
CuevanaProvider(),
|
|
||||||
EntrepeliculasyseriesProvider(),
|
|
||||||
PelisflixProvider(),
|
|
||||||
SeriesflixProvider(),
|
|
||||||
IHaveNoTvProvider(), // Documentaries provider
|
|
||||||
//LookMovieProvider(), // RECAPTCHA (Please allow up to 5 seconds...)
|
|
||||||
VMoveeProvider(),
|
|
||||||
WatchCartoonOnlineProvider(),
|
|
||||||
AllMoviesForYouProvider(),
|
|
||||||
ApiMDBProvider(),
|
|
||||||
|
|
||||||
MonoschinosProvider(),
|
// Anime providers
|
||||||
|
WatchCartoonOnlineProvider(),
|
||||||
|
GogoanimeProvider(),
|
||||||
|
AllAnimeProvider(),
|
||||||
|
AnimekisaProvider(),
|
||||||
|
//ShiroProvider(), // v2 fucked me
|
||||||
|
AnimeFlickProvider(),
|
||||||
|
AnimeflvnetProvider(),
|
||||||
|
TenshiProvider(),
|
||||||
|
WcoProvider(),
|
||||||
|
AnimePaheProvider(),
|
||||||
|
NineAnimeProvider(),
|
||||||
|
AnimeWorldProvider(),
|
||||||
|
ZoroProvider(),
|
||||||
|
DubbedAnimeProvider(),
|
||||||
|
MonoschinosProvider(),
|
||||||
|
KawaiifuProvider(), // disabled due to cloudflare
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
VidEmbedProvider(),
|
var apis : List<MainAPI> = arrayListOf()
|
||||||
VfFilmProvider(),
|
|
||||||
VfSerieProvider(),
|
|
||||||
FrenchStreamProvider(),
|
|
||||||
|
|
||||||
AsianLoadProvider(),
|
|
||||||
|
|
||||||
BflixProvider("https://bflix.ru","Bflix"),
|
|
||||||
BflixProvider("https://fmovies.to","Fmovies.to"),
|
|
||||||
BflixProvider("https://sflix.pro","Sflix.pro"),
|
|
||||||
|
|
||||||
SflixProvider("https://sflix.to", "Sflix.to"),
|
|
||||||
SflixProvider("https://dopebox.to", "Dopebox"),
|
|
||||||
SflixProvider("https://solarmovie.pe", "Solarmovie"),
|
|
||||||
|
|
||||||
//TmdbProvider(),
|
|
||||||
|
|
||||||
FilmanProvider(),
|
|
||||||
|
|
||||||
ZoroProvider(),
|
|
||||||
PinoyMoviePediaProvider(),
|
|
||||||
PinoyHDXyzProvider(),
|
|
||||||
PinoyMoviesEsProvider(),
|
|
||||||
TrailersTwoProvider(),
|
|
||||||
TwoEmbedProvider(),
|
|
||||||
DramaSeeProvider(),
|
|
||||||
WatchAsianProvider(),
|
|
||||||
KdramaHoodProvider(),
|
|
||||||
AkwamProvider(),
|
|
||||||
MyCimaProvider(),
|
|
||||||
EgyBestProvider(),
|
|
||||||
AnimePaheProvider(),
|
|
||||||
NineAnimeProvider(),
|
|
||||||
AnimeWorldProvider(),
|
|
||||||
SoaptwoDayProvider(),
|
|
||||||
|
|
||||||
CrossTmdbProvider(),
|
|
||||||
)
|
|
||||||
|
|
||||||
val restrictedApis = arrayListOf(
|
|
||||||
// TrailersToProvider(), // be aware that this is fuckery
|
|
||||||
// NyaaProvider(), // torrents in cs3 is wack
|
|
||||||
// ThenosProvider(), // ddos protection and wacked links
|
|
||||||
AsiaFlixProvider(),
|
|
||||||
)
|
|
||||||
|
|
||||||
private val backwardsCompatibleProviders = arrayListOf(
|
|
||||||
KawaiifuProvider(), // removed due to cloudflare
|
|
||||||
HDMProvider(),// removed due to cloudflare
|
|
||||||
)
|
|
||||||
|
|
||||||
fun getApiFromName(apiName: String?): MainAPI {
|
fun getApiFromName(apiName: String?): MainAPI {
|
||||||
return getApiFromNameNull(apiName) ?: apis[defProvider]
|
return getApiFromNameNull(apiName) ?: apis[defProvider]
|
||||||
|
@ -118,15 +109,7 @@ object APIHolder {
|
||||||
|
|
||||||
fun getApiFromNameNull(apiName: String?): MainAPI? {
|
fun getApiFromNameNull(apiName: String?): MainAPI? {
|
||||||
if (apiName == null) return null
|
if (apiName == null) return null
|
||||||
for (api in apis) {
|
for (api in allProviders) {
|
||||||
if (apiName == api.name)
|
|
||||||
return api
|
|
||||||
}
|
|
||||||
for (api in restrictedApis) {
|
|
||||||
if (apiName == api.name)
|
|
||||||
return api
|
|
||||||
}
|
|
||||||
for (api in backwardsCompatibleProviders) {
|
|
||||||
if (apiName == api.name)
|
if (apiName == api.name)
|
||||||
return api
|
return api
|
||||||
}
|
}
|
||||||
|
@ -281,10 +264,45 @@ object APIHolder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
0 = Site not good
|
||||||
|
1 = All good
|
||||||
|
2 = Slow, heavy traffic
|
||||||
|
3 = restricted, must donate 30 benenes to use
|
||||||
|
*/
|
||||||
|
const val PROVIDER_STATUS_KEY = "PROVIDER_STATUS_KEY"
|
||||||
|
const val PROVIDER_STATUS_URL = "https://raw.githubusercontent.com/LagradOst/CloudStream-3/master/providers.json"
|
||||||
|
const val PROVIDER_STATUS_BETA_ONLY = 3
|
||||||
|
const val PROVIDER_STATUS_SLOW = 2
|
||||||
|
const val PROVIDER_STATUS_OK = 1
|
||||||
|
const val PROVIDER_STATUS_DOWN = 0
|
||||||
|
|
||||||
|
data class ProvidersInfoJson(
|
||||||
|
@JsonProperty("name") var name: String,
|
||||||
|
@JsonProperty("url") var url: String,
|
||||||
|
@JsonProperty("status") var status: Int,
|
||||||
|
)
|
||||||
|
|
||||||
/**Every provider will **not** have try catch built in, so handle exceptions when calling these functions*/
|
/**Every provider will **not** have try catch built in, so handle exceptions when calling these functions*/
|
||||||
abstract class MainAPI {
|
abstract class MainAPI {
|
||||||
open val name = "NONE"
|
companion object {
|
||||||
open val mainUrl = "NONE"
|
var overrideData : HashMap<String, ProvidersInfoJson>? = null
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun overrideWithNewData(data : ProvidersInfoJson) {
|
||||||
|
this.name = data.name
|
||||||
|
this.mainUrl = data.url
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
overrideData?.get(this.javaClass.simpleName)?.let { data ->
|
||||||
|
overrideWithNewData(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open var name = "NONE"
|
||||||
|
open var mainUrl = "NONE"
|
||||||
|
|
||||||
//open val uniqueId : Int by lazy { this.name.hashCode() } // in case of duplicate providers you can have a shared id
|
//open val uniqueId : Int by lazy { this.name.hashCode() } // in case of duplicate providers you can have a shared id
|
||||||
|
|
||||||
|
@ -317,17 +335,17 @@ abstract class MainAPI {
|
||||||
open val providerType = ProviderType.DirectProvider
|
open val providerType = ProviderType.DirectProvider
|
||||||
|
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
suspend open fun getMainPage(): HomePageResponse? {
|
open suspend fun getMainPage(): HomePageResponse? {
|
||||||
throw NotImplementedError()
|
throw NotImplementedError()
|
||||||
}
|
}
|
||||||
|
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
suspend open fun search(query: String): List<SearchResponse>? {
|
open suspend fun search(query: String): List<SearchResponse>? {
|
||||||
throw NotImplementedError()
|
throw NotImplementedError()
|
||||||
}
|
}
|
||||||
|
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
suspend open fun quickSearch(query: String): List<SearchResponse>? {
|
open suspend fun quickSearch(query: String): List<SearchResponse>? {
|
||||||
throw NotImplementedError()
|
throw NotImplementedError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +354,7 @@ abstract class MainAPI {
|
||||||
* Based on data from search() or getMainPage() it generates a LoadResponse,
|
* Based on data from search() or getMainPage() it generates a LoadResponse,
|
||||||
* basically opening the info page from a link.
|
* basically opening the info page from a link.
|
||||||
* */
|
* */
|
||||||
suspend open fun load(url: String): LoadResponse? {
|
open suspend fun load(url: String): LoadResponse? {
|
||||||
throw NotImplementedError()
|
throw NotImplementedError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,13 +368,13 @@ abstract class MainAPI {
|
||||||
* if the need arises.
|
* if the need arises.
|
||||||
* */
|
* */
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
suspend open fun extractorVerifierJob(extractorData: String?) {
|
open suspend fun extractorVerifierJob(extractorData: String?) {
|
||||||
throw NotImplementedError()
|
throw NotImplementedError()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Callback is fired once a link is found, will return true if method is executed successfully*/
|
/**Callback is fired once a link is found, will return true if method is executed successfully*/
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
suspend open fun loadLinks(
|
open suspend fun loadLinks(
|
||||||
data: String,
|
data: String,
|
||||||
isCasting: Boolean,
|
isCasting: Boolean,
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
|
|
|
@ -23,9 +23,9 @@ import androidx.preference.PreferenceManager
|
||||||
import com.google.android.gms.cast.framework.*
|
import com.google.android.gms.cast.framework.*
|
||||||
import com.google.android.material.navigationrail.NavigationRailView
|
import com.google.android.material.navigationrail.NavigationRailView
|
||||||
import com.jaredrummler.android.colorpicker.ColorPickerDialogListener
|
import com.jaredrummler.android.colorpicker.ColorPickerDialogListener
|
||||||
|
import com.lagradost.cloudstream3.APIHolder.allProviders
|
||||||
import com.lagradost.cloudstream3.APIHolder.apis
|
import com.lagradost.cloudstream3.APIHolder.apis
|
||||||
import com.lagradost.cloudstream3.APIHolder.getApiDubstatusSettings
|
import com.lagradost.cloudstream3.APIHolder.getApiDubstatusSettings
|
||||||
import com.lagradost.cloudstream3.APIHolder.restrictedApis
|
|
||||||
import com.lagradost.cloudstream3.CommonActivity.backEvent
|
import com.lagradost.cloudstream3.CommonActivity.backEvent
|
||||||
import com.lagradost.cloudstream3.CommonActivity.loadThemes
|
import com.lagradost.cloudstream3.CommonActivity.loadThemes
|
||||||
import com.lagradost.cloudstream3.CommonActivity.onColorSelectedEvent
|
import com.lagradost.cloudstream3.CommonActivity.onColorSelectedEvent
|
||||||
|
@ -46,9 +46,12 @@ import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSet
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.isCastApiAvailable
|
import com.lagradost.cloudstream3.utils.AppUtils.isCastApiAvailable
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.loadCache
|
import com.lagradost.cloudstream3.utils.AppUtils.loadCache
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.loadResult
|
import com.lagradost.cloudstream3.utils.AppUtils.loadResult
|
||||||
|
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
|
||||||
import com.lagradost.cloudstream3.utils.BackupUtils.setUpBackup
|
import com.lagradost.cloudstream3.utils.BackupUtils.setUpBackup
|
||||||
|
import com.lagradost.cloudstream3.utils.Coroutines.main
|
||||||
import com.lagradost.cloudstream3.utils.DataStore.getKey
|
import com.lagradost.cloudstream3.utils.DataStore.getKey
|
||||||
import com.lagradost.cloudstream3.utils.DataStore.removeKey
|
import com.lagradost.cloudstream3.utils.DataStore.removeKey
|
||||||
|
import com.lagradost.cloudstream3.utils.DataStore.setKey
|
||||||
import com.lagradost.cloudstream3.utils.DataStoreHelper.setViewPos
|
import com.lagradost.cloudstream3.utils.DataStoreHelper.setViewPos
|
||||||
import com.lagradost.cloudstream3.utils.InAppUpdater.Companion.runAutoUpdate
|
import com.lagradost.cloudstream3.utils.InAppUpdater.Companion.runAutoUpdate
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.changeStatusBarState
|
import com.lagradost.cloudstream3.utils.UIHelper.changeStatusBarState
|
||||||
|
@ -60,6 +63,9 @@ import com.lagradost.cloudstream3.utils.UIHelper.navigate
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.requestRW
|
import com.lagradost.cloudstream3.utils.UIHelper.requestRW
|
||||||
import kotlinx.android.synthetic.main.activity_main.*
|
import kotlinx.android.synthetic.main.activity_main.*
|
||||||
import kotlinx.android.synthetic.main.fragment_result_swipe.*
|
import kotlinx.android.synthetic.main.fragment_result_swipe.*
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
|
|
||||||
|
@ -308,6 +314,88 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
||||||
for (api in OAuth2accountApis) {
|
for (api in OAuth2accountApis) {
|
||||||
api.init()
|
api.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
|
val downloadFromGithub = try {
|
||||||
|
settingsManager.getBoolean(getString(R.string.killswitch_key), true)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
logError(e)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
// must give benenes to get beta providers
|
||||||
|
val hasBenene = try {
|
||||||
|
val count = settingsManager.getInt(getString(R.string.benene_count), 0)
|
||||||
|
count > 30
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
// this pulls the latest data so ppl don't have to update to simply change provider url
|
||||||
|
if(downloadFromGithub) {
|
||||||
|
try {
|
||||||
|
runBlocking {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
try {
|
||||||
|
val cacheStr: String? = getKey(PROVIDER_STATUS_KEY)
|
||||||
|
val cache: HashMap<String, ProvidersInfoJson>? =
|
||||||
|
cacheStr?.let { tryParseJson(cacheStr) }
|
||||||
|
if (cache != null) {
|
||||||
|
// if cache is found then spin up a new request, but dont wait
|
||||||
|
main {
|
||||||
|
try {
|
||||||
|
val txt = app.get(PROVIDER_STATUS_URL).text
|
||||||
|
val newCache =
|
||||||
|
tryParseJson<HashMap<String, ProvidersInfoJson>>(txt)
|
||||||
|
setKey(PROVIDER_STATUS_KEY, txt)
|
||||||
|
MainAPI.overrideData = newCache // update all new providers
|
||||||
|
for (api in apis) { // update current providers
|
||||||
|
newCache?.get(api.javaClass.simpleName)?.let { data ->
|
||||||
|
api.overrideWithNewData(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
logError(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cache
|
||||||
|
} else {
|
||||||
|
// if it is the first time the user has used the app then wait for a request to update all providers
|
||||||
|
val txt = app.get(PROVIDER_STATUS_URL).text
|
||||||
|
setKey(PROVIDER_STATUS_KEY, txt)
|
||||||
|
val newCache = tryParseJson<HashMap<String, ProvidersInfoJson>>(txt)
|
||||||
|
newCache
|
||||||
|
}?.let { providersJsonMap ->
|
||||||
|
MainAPI.overrideData = providersJsonMap
|
||||||
|
val acceptableProviders =
|
||||||
|
providersJsonMap.filter { it.value.status == PROVIDER_STATUS_OK || it.value.status == PROVIDER_STATUS_SLOW }
|
||||||
|
.map { it.key }.toSet()
|
||||||
|
|
||||||
|
val restrictedApis =
|
||||||
|
if (hasBenene) providersJsonMap.filter { it.value.status == PROVIDER_STATUS_BETA_ONLY }
|
||||||
|
.map { it.key }.toSet() else emptySet()
|
||||||
|
|
||||||
|
apis = allProviders.filter { api ->
|
||||||
|
val name = api.javaClass.simpleName
|
||||||
|
// if the provider does not exist in the json file, then it is shown by default
|
||||||
|
!providersJsonMap.containsKey(name) || acceptableProviders.contains(name) || restrictedApis.contains(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e : Exception) {
|
||||||
|
logError(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
apis = allProviders
|
||||||
|
e.printStackTrace()
|
||||||
|
logError(e)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
apis = allProviders
|
||||||
|
}
|
||||||
|
|
||||||
loadThemes(this)
|
loadThemes(this)
|
||||||
updateLocale()
|
updateLocale()
|
||||||
app.initClient(this)
|
app.initClient(this)
|
||||||
|
@ -458,10 +546,8 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
||||||
createISO()
|
createISO()
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
var providersString = "Current providers are:\n"
|
|
||||||
var providersAndroidManifestString = "Current androidmanifest should be:\n"
|
var providersAndroidManifestString = "Current androidmanifest should be:\n"
|
||||||
for (api in apis) {
|
for (api in allProviders) {
|
||||||
providersString += "+ ${api.mainUrl}\n"
|
|
||||||
providersAndroidManifestString += "<data android:scheme=\"https\" android:host=\"${
|
providersAndroidManifestString += "<data android:scheme=\"https\" android:host=\"${
|
||||||
api.mainUrl.removePrefix(
|
api.mainUrl.removePrefix(
|
||||||
"https://"
|
"https://"
|
||||||
|
@ -469,17 +555,6 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
||||||
}\" android:pathPrefix=\"/\"/>\n"
|
}\" android:pathPrefix=\"/\"/>\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
for (api in restrictedApis) {
|
|
||||||
providersString += "+ ${api.mainUrl}\n"
|
|
||||||
providersAndroidManifestString += "<data android:scheme=\"https\" android:host=\"${
|
|
||||||
api.mainUrl.removePrefix(
|
|
||||||
"https://"
|
|
||||||
)
|
|
||||||
}\" android:pathPrefix=\"/\"/>\n"
|
|
||||||
}
|
|
||||||
println(providersString)
|
|
||||||
|
|
||||||
|
|
||||||
println(providersAndroidManifestString)
|
println(providersAndroidManifestString)
|
||||||
|
|
||||||
handleAppIntent(intent)
|
handleAppIntent(intent)
|
||||||
|
@ -488,15 +563,6 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
||||||
runAutoUpdate()
|
runAutoUpdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
// must give benenes to get beta providers
|
|
||||||
try {
|
|
||||||
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
|
|
||||||
val count = settingsManager.getInt(getString(R.string.benene_count), 0)
|
|
||||||
if (count > 30 && restrictedApis.size > 0 && !apis.contains(restrictedApis.first()))
|
|
||||||
apis.addAll(restrictedApis)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
APIRepository.dubStatusActive = getApiDubstatusSettings()
|
APIRepository.dubStatusActive = getApiDubstatusSettings()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -507,7 +573,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logError(e)
|
logError(e)
|
||||||
}
|
}
|
||||||
|
println("Loaded everything")
|
||||||
/*
|
/*
|
||||||
val relativePath = (Environment.DIRECTORY_DOWNLOADS) + File.separatorChar
|
val relativePath = (Environment.DIRECTORY_DOWNLOADS) + File.separatorChar
|
||||||
val displayName = "output.dex" //""output.dex"
|
val displayName = "output.dex" //""output.dex"
|
||||||
|
|
|
@ -17,8 +17,8 @@ import java.util.*
|
||||||
|
|
||||||
|
|
||||||
class AllAnimeProvider : MainAPI() {
|
class AllAnimeProvider : MainAPI() {
|
||||||
override val mainUrl = "https://allanime.site"
|
override var mainUrl = "https://allanime.site"
|
||||||
override val name = "AllAnime"
|
override var name = "AllAnime"
|
||||||
override val hasQuickSearch = false
|
override val hasQuickSearch = false
|
||||||
override val hasMainPage = false
|
override val hasMainPage = false
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,8 @@ class AnimeFlickProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val mainUrl = "https://animeflick.net"
|
override var mainUrl = "https://animeflick.net"
|
||||||
override val name = "AnimeFlick"
|
override var name = "AnimeFlick"
|
||||||
override val hasQuickSearch = false
|
override val hasQuickSearch = false
|
||||||
override val hasMainPage = false
|
override val hasMainPage = false
|
||||||
|
|
||||||
|
|
|
@ -44,8 +44,8 @@ class AnimePaheProvider : MainAPI() {
|
||||||
Regex("""(^(?:https?:)?(?://)?(?:www\.)?(?:youtu\.be/|youtube(?:-nocookie)?\.(?:[A-Za-z]{2,4}|[A-Za-z]{2,3}\.[A-Za-z]{2})/)(?:watch|embed/|vi?/)*(?:\?[\w=&]*vi?=)?[^#&?/]{11}.*${'$'})""")
|
Regex("""(^(?:https?:)?(?://)?(?:www\.)?(?:youtu\.be/|youtube(?:-nocookie)?\.(?:[A-Za-z]{2,4}|[A-Za-z]{2,3}\.[A-Za-z]{2})/)(?:watch|embed/|vi?/)*(?:\?[\w=&]*vi?=)?[^#&?/]{11}.*${'$'})""")
|
||||||
}
|
}
|
||||||
|
|
||||||
override val mainUrl = MAIN_URL
|
override var mainUrl = MAIN_URL
|
||||||
override val name = "AnimePahe"
|
override var name = "AnimePahe"
|
||||||
override val hasQuickSearch = false
|
override val hasQuickSearch = false
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,8 @@ import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.Qualities
|
import com.lagradost.cloudstream3.utils.Qualities
|
||||||
|
|
||||||
class AnimeWorldProvider : MainAPI() {
|
class AnimeWorldProvider : MainAPI() {
|
||||||
override val mainUrl = "https://www.animeworld.tv"
|
override var mainUrl = "https://www.animeworld.tv"
|
||||||
override val name = "AnimeWorld"
|
override var name = "AnimeWorld"
|
||||||
override val lang = "it"
|
override val lang = "it"
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,8 @@ class AnimeflvnetProvider:MainAPI() {
|
||||||
else TvType.Anime
|
else TvType.Anime
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
override val mainUrl = "https://www3.animeflv.net"
|
override var mainUrl = "https://www3.animeflv.net"
|
||||||
override val name = "Animeflv.net"
|
override var name = "Animeflv.net"
|
||||||
override val lang = "es"
|
override val lang = "es"
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val hasChromecastSupport = true
|
override val hasChromecastSupport = true
|
||||||
|
|
|
@ -12,8 +12,8 @@ import kotlin.collections.ArrayList
|
||||||
|
|
||||||
class AnimekisaProvider : MainAPI() {
|
class AnimekisaProvider : MainAPI() {
|
||||||
|
|
||||||
override val mainUrl = "https://animekisa.in"
|
override var mainUrl = "https://animekisa.in"
|
||||||
override val name = "Animekisa"
|
override var name = "Animekisa"
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val hasChromecastSupport = true
|
override val hasChromecastSupport = true
|
||||||
override val hasDownloadSupport = true
|
override val hasDownloadSupport = true
|
||||||
|
|
|
@ -11,8 +11,8 @@ import org.jsoup.Jsoup
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class DubbedAnimeProvider : MainAPI() {
|
class DubbedAnimeProvider : MainAPI() {
|
||||||
override val mainUrl = "https://bestdubbedanime.com"
|
override var mainUrl = "https://bestdubbedanime.com"
|
||||||
override val name = "DubbedAnime"
|
override var name = "DubbedAnime"
|
||||||
override val hasQuickSearch = true
|
override val hasQuickSearch = true
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
|
|
||||||
|
|
|
@ -155,8 +155,8 @@ class GogoanimeProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val mainUrl = "https://gogoanime.film"
|
override var mainUrl = "https://gogoanime.film"
|
||||||
override val name = "GogoAnime"
|
override var name = "GogoAnime"
|
||||||
override val hasQuickSearch = false
|
override val hasQuickSearch = false
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,8 @@ import org.jsoup.Jsoup
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class KawaiifuProvider : MainAPI() {
|
class KawaiifuProvider : MainAPI() {
|
||||||
override val mainUrl = "https://kawaiifu.com"
|
override var mainUrl = "https://kawaiifu.com"
|
||||||
override val name = "Kawaiifu"
|
override var name = "Kawaiifu"
|
||||||
override val hasQuickSearch = false
|
override val hasQuickSearch = false
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,8 @@ class MonoschinosProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val mainUrl = "https://monoschinos2.com"
|
override var mainUrl = "https://monoschinos2.com"
|
||||||
override val name = "Monoschinos"
|
override var name = "Monoschinos"
|
||||||
override val lang = "es"
|
override val lang = "es"
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val hasChromecastSupport = true
|
override val hasChromecastSupport = true
|
||||||
|
|
|
@ -10,8 +10,8 @@ import org.jsoup.Jsoup
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class NineAnimeProvider : MainAPI() {
|
class NineAnimeProvider : MainAPI() {
|
||||||
override val mainUrl = "https://9anime.center"
|
override var mainUrl = "https://9anime.center"
|
||||||
override val name = "9Anime"
|
override var name = "9Anime"
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val hasChromecastSupport = true
|
override val hasChromecastSupport = true
|
||||||
override val hasDownloadSupport = true
|
override val hasDownloadSupport = true
|
||||||
|
|
|
@ -25,8 +25,8 @@ class TenshiProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val mainUrl = "https://tenshi.moe"
|
override var mainUrl = "https://tenshi.moe"
|
||||||
override val name = "Tenshi.moe"
|
override var name = "Tenshi.moe"
|
||||||
override val hasQuickSearch = false
|
override val hasQuickSearch = false
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val supportedTypes = setOf(TvType.Anime, TvType.AnimeMovie, TvType.OVA)
|
override val supportedTypes = setOf(TvType.Anime, TvType.AnimeMovie, TvType.OVA)
|
||||||
|
|
|
@ -12,8 +12,8 @@ import java.util.*
|
||||||
|
|
||||||
|
|
||||||
class WatchCartoonOnlineProvider : MainAPI() {
|
class WatchCartoonOnlineProvider : MainAPI() {
|
||||||
override val name = "WatchCartoonOnline"
|
override var name = "WatchCartoonOnline"
|
||||||
override val mainUrl = "https://www.wcostream.com"
|
override var mainUrl = "https://www.wcostream.com"
|
||||||
|
|
||||||
override val supportedTypes = setOf(
|
override val supportedTypes = setOf(
|
||||||
TvType.Cartoon,
|
TvType.Cartoon,
|
||||||
|
|
|
@ -19,8 +19,8 @@ class WcoProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val mainUrl = "https://wcostream.cc"
|
override var mainUrl = "https://wcostream.cc"
|
||||||
override val name = "WCO Stream"
|
override var name = "WCO Stream"
|
||||||
override val hasQuickSearch = true
|
override val hasQuickSearch = true
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,8 @@ import java.net.URI
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class ZoroProvider : MainAPI() {
|
class ZoroProvider : MainAPI() {
|
||||||
override val mainUrl = "https://zoro.to"
|
override var mainUrl = "https://zoro.to"
|
||||||
override val name = "Zoro"
|
override var name = "Zoro"
|
||||||
override val hasQuickSearch = false
|
override val hasQuickSearch = false
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val hasChromecastSupport = true
|
override val hasChromecastSupport = true
|
||||||
|
|
|
@ -5,8 +5,8 @@ import com.lagradost.cloudstream3.utils.*
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
|
||||||
class AsianLoad : ExtractorApi() {
|
class AsianLoad : ExtractorApi() {
|
||||||
override val name = "AsianLoad"
|
override var name = "AsianLoad"
|
||||||
override val mainUrl = "https://asianembed.io"
|
override var mainUrl = "https://asianembed.io"
|
||||||
override val requiresReferer = true
|
override val requiresReferer = true
|
||||||
|
|
||||||
private val sourceRegex = Regex("""sources:[\W\w]*?file:\s*?["'](.*?)["']""")
|
private val sourceRegex = Regex("""sources:[\W\w]*?file:\s*?["'](.*?)["']""")
|
||||||
|
|
|
@ -7,21 +7,21 @@ import com.lagradost.cloudstream3.utils.Qualities
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
|
||||||
class DoodToExtractor : DoodLaExtractor() {
|
class DoodToExtractor : DoodLaExtractor() {
|
||||||
override val mainUrl = "https://dood.to"
|
override var mainUrl = "https://dood.to"
|
||||||
}
|
}
|
||||||
|
|
||||||
class DoodSoExtractor : DoodLaExtractor() {
|
class DoodSoExtractor : DoodLaExtractor() {
|
||||||
override val mainUrl = "https://dood.so"
|
override var mainUrl = "https://dood.so"
|
||||||
}
|
}
|
||||||
|
|
||||||
class DoodWsExtractor : DoodLaExtractor() {
|
class DoodWsExtractor : DoodLaExtractor() {
|
||||||
override val mainUrl = "https://dood.ws"
|
override var mainUrl = "https://dood.ws"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
open class DoodLaExtractor : ExtractorApi() {
|
open class DoodLaExtractor : ExtractorApi() {
|
||||||
override val name = "DoodStream"
|
override var name = "DoodStream"
|
||||||
override val mainUrl = "https://dood.la"
|
override var mainUrl = "https://dood.la"
|
||||||
override val requiresReferer = false
|
override val requiresReferer = false
|
||||||
|
|
||||||
override fun getExtractorUrl(id: String): String {
|
override fun getExtractorUrl(id: String): String {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import com.lagradost.cloudstream3.utils.*
|
||||||
import com.lagradost.cloudstream3.app
|
import com.lagradost.cloudstream3.app
|
||||||
|
|
||||||
class Evoload1 : Evoload() {
|
class Evoload1 : Evoload() {
|
||||||
override val mainUrl = "https://evoload.io"
|
override var mainUrl = "https://evoload.io"
|
||||||
}
|
}
|
||||||
|
|
||||||
open class Evoload : ExtractorApi() {
|
open class Evoload : ExtractorApi() {
|
||||||
|
|
|
@ -12,8 +12,8 @@ import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
|
|
||||||
|
|
||||||
open class GenericM3U8 : ExtractorApi() {
|
open class GenericM3U8 : ExtractorApi() {
|
||||||
override val name = "Upstream"
|
override var name = "Upstream"
|
||||||
override val mainUrl = "https://upstream.to"
|
override var mainUrl = "https://upstream.to"
|
||||||
override val requiresReferer = false
|
override val requiresReferer = false
|
||||||
|
|
||||||
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> {
|
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> {
|
||||||
|
|
|
@ -6,8 +6,8 @@ import com.lagradost.cloudstream3.app
|
||||||
|
|
||||||
|
|
||||||
open class Jawcloud : ExtractorApi() {
|
open class Jawcloud : ExtractorApi() {
|
||||||
override val name = "Jawcloud"
|
override var name = "Jawcloud"
|
||||||
override val mainUrl = "https://jawcloud.co"
|
override var mainUrl = "https://jawcloud.co"
|
||||||
override val requiresReferer = false
|
override val requiresReferer = false
|
||||||
|
|
||||||
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
|
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
|
||||||
|
|
|
@ -11,8 +11,8 @@ import com.lagradost.cloudstream3.utils.M3u8Helper
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
|
|
||||||
open class Mcloud : ExtractorApi() {
|
open class Mcloud : ExtractorApi() {
|
||||||
override val name = "Mcloud"
|
override var name = "Mcloud"
|
||||||
override val mainUrl = "https://mcloud.to"
|
override var mainUrl = "https://mcloud.to"
|
||||||
override val requiresReferer = true
|
override val requiresReferer = true
|
||||||
val headers = mapOf(
|
val headers = mapOf(
|
||||||
"Host" to "mcloud.to",
|
"Host" to "mcloud.to",
|
||||||
|
|
|
@ -4,8 +4,8 @@ import com.lagradost.cloudstream3.app
|
||||||
import com.lagradost.cloudstream3.utils.*
|
import com.lagradost.cloudstream3.utils.*
|
||||||
|
|
||||||
class MixDrop : ExtractorApi() {
|
class MixDrop : ExtractorApi() {
|
||||||
override val name = "MixDrop"
|
override var name = "MixDrop"
|
||||||
override val mainUrl = "https://mixdrop.co"
|
override var mainUrl = "https://mixdrop.co"
|
||||||
private val srcRegex = Regex("""wurl.*?=.*?"(.*?)";""")
|
private val srcRegex = Regex("""wurl.*?=.*?"(.*?)";""")
|
||||||
override val requiresReferer = false
|
override val requiresReferer = false
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,8 @@ import com.lagradost.cloudstream3.utils.Qualities
|
||||||
import com.lagradost.cloudstream3.utils.getAndUnpack
|
import com.lagradost.cloudstream3.utils.getAndUnpack
|
||||||
|
|
||||||
class Mp4Upload : ExtractorApi() {
|
class Mp4Upload : ExtractorApi() {
|
||||||
override val name = "Mp4Upload"
|
override var name = "Mp4Upload"
|
||||||
override val mainUrl = "https://www.mp4upload.com"
|
override var mainUrl = "https://www.mp4upload.com"
|
||||||
private val srcRegex = Regex("""player\.src\("(.*?)"""")
|
private val srcRegex = Regex("""player\.src\("(.*?)"""")
|
||||||
override val requiresReferer = true
|
override val requiresReferer = true
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,8 @@ import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
|
||||||
class MultiQuality : ExtractorApi() {
|
class MultiQuality : ExtractorApi() {
|
||||||
override val name = "MultiQuality"
|
override var name = "MultiQuality"
|
||||||
override val mainUrl = "https://gogo-play.net"
|
override var mainUrl = "https://gogo-play.net"
|
||||||
private val sourceRegex = Regex("""file:\s*['"](.*?)['"],label:\s*['"](.*?)['"]""")
|
private val sourceRegex = Regex("""file:\s*['"](.*?)['"],label:\s*['"](.*?)['"]""")
|
||||||
private val m3u8Regex = Regex(""".*?(\d*).m3u8""")
|
private val m3u8Regex = Regex(""".*?(\d*).m3u8""")
|
||||||
private val urlRegex = Regex("""(.*?)([^/]+$)""")
|
private val urlRegex = Regex("""(.*?)([^/]+$)""")
|
||||||
|
|
|
@ -1,35 +1,63 @@
|
||||||
package com.lagradost.cloudstream3.extractors
|
package com.lagradost.cloudstream3.extractors
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
import com.lagradost.cloudstream3.utils.*
|
import com.lagradost.cloudstream3.utils.*
|
||||||
import com.lagradost.cloudstream3.app
|
import com.lagradost.cloudstream3.app
|
||||||
|
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
||||||
|
|
||||||
|
data class DataOptionsJson (
|
||||||
|
@JsonProperty("flashvars") var flashvars : Flashvars? = Flashvars(),
|
||||||
|
)
|
||||||
|
data class Flashvars (
|
||||||
|
@JsonProperty("metadata") var metadata : String? = null,
|
||||||
|
@JsonProperty("hlsManifestUrl") var hlsManifestUrl : String? = null, //m3u8
|
||||||
|
)
|
||||||
|
|
||||||
|
data class MetadataOkru (
|
||||||
|
@JsonProperty("videos") var videos: ArrayList<Videos> = arrayListOf(),
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Videos (
|
||||||
|
@JsonProperty("name") var name : String,
|
||||||
|
@JsonProperty("url") var url : String,
|
||||||
|
@JsonProperty("seekSchema") var seekSchema : Int? = null,
|
||||||
|
@JsonProperty("disallowed") var disallowed : Boolean? = null
|
||||||
|
)
|
||||||
|
|
||||||
open class OkRu : ExtractorApi() {
|
open class OkRu : ExtractorApi() {
|
||||||
override val name = "Okru"
|
override var name = "Okru"
|
||||||
override val mainUrl = "http://ok.ru"
|
override var mainUrl = "http://ok.ru"
|
||||||
override val requiresReferer = false
|
override val requiresReferer = false
|
||||||
|
|
||||||
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
|
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
|
||||||
val doc = app.get(url).document
|
val doc = app.get(url).document
|
||||||
val urlString = doc.select("div[data-options]").attr("data-options")
|
val sources = ArrayList<ExtractorLink>()
|
||||||
.substringAfter("\\\"videos\\\":[{\\\"name\\\":\\\"")
|
val datajson = doc.select("div[data-options]").attr("data-options")
|
||||||
.substringBefore("]")
|
if (datajson.isNotBlank()) {
|
||||||
urlString.split("{\\\"name\\\":\\\"").reversed().forEach {
|
val main = parseJson<DataOptionsJson>(datajson)
|
||||||
val extractedUrl = it.substringAfter("url\\\":\\\"")
|
val metadatajson = parseJson<MetadataOkru>(main.flashvars?.metadata!!)
|
||||||
.substringBefore("\\\"")
|
val servers = metadatajson.videos
|
||||||
.replace("\\\\u0026", "&")
|
servers.forEach {
|
||||||
val Quality = it.uppercase().substringBefore("\\\"")
|
val quality = it.name.uppercase()
|
||||||
|
.replace("MOBILE","144p")
|
||||||
if (extractedUrl.isNotBlank()) return listOf(
|
.replace("LOWEST","240p")
|
||||||
ExtractorLink(
|
.replace("LOW","360p")
|
||||||
|
.replace("SD","480p")
|
||||||
|
.replace("HD","720p")
|
||||||
|
.replace("FULL","1080p")
|
||||||
|
.replace("QUAD","1440p")
|
||||||
|
.replace("ULTRA","4k")
|
||||||
|
val extractedurl = it.url.replace("\\\\u0026", "&")
|
||||||
|
sources.add(ExtractorLink(
|
||||||
name,
|
name,
|
||||||
"$name ${Quality}",
|
"$name $quality",
|
||||||
extractedUrl,
|
extractedurl,
|
||||||
url,
|
url,
|
||||||
Qualities.Unknown.value,
|
getQualityFromName(quality),
|
||||||
isM3u8 = false
|
isM3u8 = false
|
||||||
)
|
))
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
return null
|
return sources
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,8 +6,8 @@ import com.lagradost.cloudstream3.app
|
||||||
|
|
||||||
|
|
||||||
open class PlayerVoxzer : ExtractorApi() {
|
open class PlayerVoxzer : ExtractorApi() {
|
||||||
override val name = "Voxzer"
|
override var name = "Voxzer"
|
||||||
override val mainUrl = "https://player.voxzer.org"
|
override var mainUrl = "https://player.voxzer.org"
|
||||||
override val requiresReferer = false
|
override val requiresReferer = false
|
||||||
|
|
||||||
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
|
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
|
||||||
|
|
|
@ -10,16 +10,16 @@ import com.lagradost.cloudstream3.utils.getPostForm
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
|
|
||||||
//class SBPlay1 : SBPlay() {
|
//class SBPlay1 : SBPlay() {
|
||||||
// override val mainUrl = "https://sbplay1.com"
|
// override var mainUrl = "https://sbplay1.com"
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//class SBPlay2 : SBPlay() {
|
//class SBPlay2 : SBPlay() {
|
||||||
// override val mainUrl = "https://sbplay2.com"
|
// override var mainUrl = "https://sbplay2.com"
|
||||||
//}
|
//}
|
||||||
|
|
||||||
open class SBPlay : ExtractorApi() {
|
open class SBPlay : ExtractorApi() {
|
||||||
override val mainUrl = "https://sbplay.one"
|
override var mainUrl = "https://sbplay.one"
|
||||||
override val name = "SBPlay"
|
override var name = "SBPlay"
|
||||||
override val requiresReferer = false
|
override val requiresReferer = false
|
||||||
|
|
||||||
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> {
|
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> {
|
||||||
|
|
|
@ -9,46 +9,50 @@ import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
||||||
|
|
||||||
|
|
||||||
class StreamSB1 : StreamSB() {
|
class StreamSB1 : StreamSB() {
|
||||||
override val mainUrl = "https://sbplay1.com"
|
override var mainUrl = "https://sbplay1.com"
|
||||||
}
|
}
|
||||||
|
|
||||||
class StreamSB2 : StreamSB() {
|
class StreamSB2 : StreamSB() {
|
||||||
override val mainUrl = "https://sbplay2.com"
|
override var mainUrl = "https://sbplay2.com"
|
||||||
}
|
}
|
||||||
|
|
||||||
class StreamSB3 : StreamSB() {
|
class StreamSB3 : StreamSB() {
|
||||||
override val mainUrl = "https://sbplay3.com"
|
override var mainUrl = "https://sbplay3.com"
|
||||||
}
|
}
|
||||||
|
|
||||||
class StreamSB4 : StreamSB() {
|
class StreamSB4 : StreamSB() {
|
||||||
override val mainUrl = "https://cloudemb.com"
|
override var mainUrl = "https://cloudemb.com"
|
||||||
}
|
}
|
||||||
|
|
||||||
class StreamSB5 : StreamSB() {
|
class StreamSB5 : StreamSB() {
|
||||||
override val mainUrl = "https://sbplay.org"
|
override var mainUrl = "https://sbplay.org"
|
||||||
}
|
}
|
||||||
|
|
||||||
class StreamSB6 : StreamSB() {
|
class StreamSB6 : StreamSB() {
|
||||||
override val mainUrl = "https://embedsb.com"
|
override var mainUrl = "https://embedsb.com"
|
||||||
}
|
}
|
||||||
|
|
||||||
class StreamSB7 : StreamSB() {
|
class StreamSB7 : StreamSB() {
|
||||||
override val mainUrl = "https://pelistop.co"
|
override var mainUrl = "https://pelistop.co"
|
||||||
}
|
}
|
||||||
|
|
||||||
class StreamSB8 : StreamSB() {
|
class StreamSB8 : StreamSB() {
|
||||||
override val mainUrl = "https://streamsb.net"
|
override var mainUrl = "https://streamsb.net"
|
||||||
}
|
}
|
||||||
|
|
||||||
class StreamSB9 : StreamSB() {
|
class StreamSB9 : StreamSB() {
|
||||||
override val mainUrl = "https://sbplay.one"
|
override var mainUrl = "https://sbplay.one"
|
||||||
|
}
|
||||||
|
|
||||||
|
class StreamSB10 : StreamSB() {
|
||||||
|
override var mainUrl = "https://sbplay2.xyz"
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a modified version of https://github.com/jmir1/aniyomi-extensions/blob/master/src/en/genoanime/src/eu/kanade/tachiyomi/animeextension/en/genoanime/extractors/StreamSBExtractor.kt
|
// This is a modified version of https://github.com/jmir1/aniyomi-extensions/blob/master/src/en/genoanime/src/eu/kanade/tachiyomi/animeextension/en/genoanime/extractors/StreamSBExtractor.kt
|
||||||
// The following code is under the Apache License 2.0 https://github.com/jmir1/aniyomi-extensions/blob/master/LICENSE
|
// The following code is under the Apache License 2.0 https://github.com/jmir1/aniyomi-extensions/blob/master/LICENSE
|
||||||
open class StreamSB : ExtractorApi() {
|
open class StreamSB : ExtractorApi() {
|
||||||
override val name = "StreamSB"
|
override var name = "StreamSB"
|
||||||
override val mainUrl = "https://watchsb.com"
|
override var mainUrl = "https://watchsb.com"
|
||||||
override val requiresReferer = false
|
override val requiresReferer = false
|
||||||
|
|
||||||
private val hexArray = "0123456789ABCDEF".toCharArray()
|
private val hexArray = "0123456789ABCDEF".toCharArray()
|
||||||
|
@ -88,53 +92,30 @@ open class StreamSB : ExtractorApi() {
|
||||||
}.first()
|
}.first()
|
||||||
val bytes = id.toByteArray()
|
val bytes = id.toByteArray()
|
||||||
val bytesToHex = bytesToHex(bytes)
|
val bytesToHex = bytesToHex(bytes)
|
||||||
val master = "$mainUrl/sources41/566d337678566f743674494a7c7c${bytesToHex}7c7c346b6767586d6934774855537c7c73747265616d7362/6565417268755339773461447c7c346133383438333436313335376136323337373433383634376337633465366534393338373136643732373736343735373237613763376334363733353737303533366236333463353333363534366137633763373337343732363536313664373336327c7c6b586c3163614468645a47617c7c73747265616d7362"
|
val master = "$mainUrl/sources41/6d6144797752744a454267617c7c${bytesToHex.lowercase()}7c7c4e61755a56456f34385243727c7c73747265616d7362/6b4a33767968506e4e71374f7c7c343837323439333133333462353935333633373836643638376337633462333634663539343137373761333635313533333835333763376333393636363133393635366136323733343435323332376137633763373337343732363536313664373336327c7c504d754478413835306633797c7c73747265616d7362"
|
||||||
val headers = mapOf(
|
val headers = mapOf(
|
||||||
"Host" to url.substringAfter("https://").substringBefore("/"),
|
|
||||||
"User-Agent" to "Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0",
|
|
||||||
"Accept" to "application/json, text/plain, */*",
|
|
||||||
"Accept-Language" to "en-US,en;q=0.5",
|
|
||||||
"Referer" to url,
|
|
||||||
"watchsb" to "streamsb",
|
"watchsb" to "streamsb",
|
||||||
"DNT" to "1",
|
)
|
||||||
"Connection" to "keep-alive",
|
|
||||||
"Sec-Fetch-Dest" to "empty",
|
|
||||||
"Sec-Fetch-Mode" to "no-cors",
|
|
||||||
"Sec-Fetch-Site" to "same-origin",
|
|
||||||
"TE" to "trailers",
|
|
||||||
"Pragma" to "no-cache",
|
|
||||||
"Cache-Control" to "no-cache",)
|
|
||||||
val urltext = app.get(master,
|
val urltext = app.get(master,
|
||||||
headers = headers,
|
headers = headers,
|
||||||
allowRedirects = false
|
allowRedirects = false
|
||||||
).text
|
).text
|
||||||
val mapped = urltext.let { parseJson<Main>(it) }
|
val mapped = urltext.let { parseJson<Main>(it) }
|
||||||
val testurl = app.get(mapped.streamData.file, headers = headers).text
|
val testurl = app.get(mapped.streamData.file, headers = headers).text
|
||||||
val urlmain = mapped.streamData.file.substringBefore("/hls/")
|
// val urlmain = mapped.streamData.file.substringBefore("/hls/")
|
||||||
if (urltext.contains("m3u8") && testurl.contains("EXTM3U")) return M3u8Helper().m3u8Generation(
|
if (urltext.contains("m3u8") && testurl.contains("EXTM3U")) return M3u8Helper().m3u8Generation(
|
||||||
M3u8Helper.M3u8Stream(
|
M3u8Helper.M3u8Stream(
|
||||||
mapped.streamData.file,
|
mapped.streamData.file,
|
||||||
headers = mapOf(
|
headers = headers
|
||||||
"User-Agent" to USER_AGENT,
|
|
||||||
"Accept" to "*/*",
|
|
||||||
"Accept-Language" to "en-US,en;q=0.5",
|
|
||||||
"Accept-Encoding" to "gzip, deflate, br",
|
|
||||||
"Origin" to mainUrl,
|
|
||||||
"DNT" to "1",
|
|
||||||
"Connection" to "keep-alive",
|
|
||||||
"Referer" to "$mainUrl/",
|
|
||||||
"Sec-Fetch-Dest" to "empty",
|
|
||||||
"Sec-Fetch-Mode" to "cors",
|
|
||||||
"Sec-Fetch-Site" to "cross-site",),
|
|
||||||
), true
|
), true
|
||||||
)
|
)
|
||||||
.map { stream ->
|
.map { stream ->
|
||||||
val cleanstreamurl = stream.streamUrl.replace(Regex("https://.*/hls/"), "$urlmain/hls/")
|
// val cleanstreamurl = stream.streamUrl.replace(Regex("https://.*/hls/"), "$urlmain/hls/")
|
||||||
val qualityString = if ((stream.quality ?: 0) == 0) "" else "${stream.quality}p"
|
val qualityString = if ((stream.quality ?: 0) == 0) "" else "${stream.quality}p"
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
name,
|
name,
|
||||||
"$name $qualityString",
|
"$name $qualityString",
|
||||||
cleanstreamurl,
|
stream.streamUrl,
|
||||||
url,
|
url,
|
||||||
getQualityFromName(stream.quality.toString()),
|
getQualityFromName(stream.quality.toString()),
|
||||||
true
|
true
|
||||||
|
|
|
@ -6,8 +6,8 @@ import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.Qualities
|
import com.lagradost.cloudstream3.utils.Qualities
|
||||||
|
|
||||||
class StreamTape : ExtractorApi() {
|
class StreamTape : ExtractorApi() {
|
||||||
override val name = "StreamTape"
|
override var name = "StreamTape"
|
||||||
override val mainUrl = "https://streamtape.com"
|
override var mainUrl = "https://streamtape.com"
|
||||||
override val requiresReferer = false
|
override val requiresReferer = false
|
||||||
|
|
||||||
private val linkRegex =
|
private val linkRegex =
|
||||||
|
|
|
@ -8,8 +8,8 @@ import com.lagradost.cloudstream3.utils.Qualities
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
|
||||||
class Streamhub : ExtractorApi() {
|
class Streamhub : ExtractorApi() {
|
||||||
override val mainUrl = "https://streamhub.to"
|
override var mainUrl = "https://streamhub.to"
|
||||||
override val name = "Streamhub"
|
override var name = "Streamhub"
|
||||||
override val requiresReferer = false
|
override val requiresReferer = false
|
||||||
|
|
||||||
override fun getExtractorUrl(id: String): String {
|
override fun getExtractorUrl(id: String): String {
|
||||||
|
|
|
@ -1,19 +1,21 @@
|
||||||
package com.lagradost.cloudstream3.extractors
|
package com.lagradost.cloudstream3.extractors
|
||||||
|
|
||||||
import com.lagradost.cloudstream3.utils.*
|
|
||||||
import com.lagradost.cloudstream3.app
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import com.lagradost.cloudstream3.app
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
||||||
|
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||||
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
|
import com.lagradost.cloudstream3.utils.Qualities
|
||||||
|
|
||||||
class Cinestart: Tomatomatela() {
|
class Cinestart: Tomatomatela() {
|
||||||
override val name: String = "Cinestart"
|
override var name = "Cinestart"
|
||||||
override val mainUrl: String = "https://cinestart.net"
|
override var mainUrl = "https://cinestart.net"
|
||||||
override val details = "vr.php?v="
|
override val details = "vr.php?v="
|
||||||
}
|
}
|
||||||
|
|
||||||
open class Tomatomatela : ExtractorApi() {
|
open class Tomatomatela : ExtractorApi() {
|
||||||
override val name = "Tomatomatela"
|
override var name = "Tomatomatela"
|
||||||
override val mainUrl = "https://tomatomatela.com"
|
override var mainUrl = "https://tomatomatela.com"
|
||||||
override val requiresReferer = false
|
override val requiresReferer = false
|
||||||
private data class Tomato (
|
private data class Tomato (
|
||||||
@JsonProperty("status") val status: Int,
|
@JsonProperty("status") val status: Int,
|
||||||
|
|
|
@ -4,7 +4,7 @@ import com.lagradost.cloudstream3.utils.*
|
||||||
import com.lagradost.cloudstream3.app
|
import com.lagradost.cloudstream3.app
|
||||||
|
|
||||||
class Uqload1 : Uqload() {
|
class Uqload1 : Uqload() {
|
||||||
override val mainUrl = "https://uqload.com"
|
override var mainUrl = "https://uqload.com"
|
||||||
}
|
}
|
||||||
|
|
||||||
open class Uqload : ExtractorApi() {
|
open class Uqload : ExtractorApi() {
|
||||||
|
|
|
@ -8,8 +8,8 @@ import com.lagradost.cloudstream3.utils.M3u8Helper
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
|
|
||||||
open class WatchSB : ExtractorApi() {
|
open class WatchSB : ExtractorApi() {
|
||||||
override val name = "WatchSB"
|
override var name = "WatchSB"
|
||||||
override val mainUrl = "https://watchsb.com"
|
override var mainUrl = "https://watchsb.com"
|
||||||
override val requiresReferer = false
|
override val requiresReferer = false
|
||||||
|
|
||||||
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> {
|
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> {
|
||||||
|
|
|
@ -8,19 +8,19 @@ import com.lagradost.cloudstream3.mapper
|
||||||
import com.lagradost.cloudstream3.utils.*
|
import com.lagradost.cloudstream3.utils.*
|
||||||
|
|
||||||
class Vidstreamz : WcoStream() {
|
class Vidstreamz : WcoStream() {
|
||||||
override val mainUrl: String = "https://vidstreamz.online"
|
override var mainUrl = "https://vidstreamz.online"
|
||||||
}
|
}
|
||||||
class Vizcloud : WcoStream() {
|
class Vizcloud : WcoStream() {
|
||||||
override val mainUrl: String = "https://vizcloud2.ru"
|
override var mainUrl = "https://vizcloud2.ru"
|
||||||
}
|
}
|
||||||
|
|
||||||
class Vizcloud2 : WcoStream() {
|
class Vizcloud2 : WcoStream() {
|
||||||
override val mainUrl: String = "https://vizcloud2.online"
|
override var mainUrl = "https://vizcloud2.online"
|
||||||
}
|
}
|
||||||
|
|
||||||
open class WcoStream : ExtractorApi() {
|
open class WcoStream : ExtractorApi() {
|
||||||
override val name = "VidStream" //Cause works for animekisa and wco
|
override var name = "VidStream" //Cause works for animekisa and wco
|
||||||
override val mainUrl = "https://vidstream.pro"
|
override var mainUrl = "https://vidstream.pro"
|
||||||
override val requiresReferer = false
|
override val requiresReferer = false
|
||||||
private val hlsHelper = M3u8Helper()
|
private val hlsHelper = M3u8Helper()
|
||||||
|
|
||||||
|
|
|
@ -5,23 +5,23 @@ import com.lagradost.cloudstream3.app
|
||||||
import com.lagradost.cloudstream3.utils.*
|
import com.lagradost.cloudstream3.utils.*
|
||||||
|
|
||||||
class Zplayer: ZplayerV2() {
|
class Zplayer: ZplayerV2() {
|
||||||
override val name: String = "Zplayer"
|
override var name: String = "Zplayer"
|
||||||
override val mainUrl: String = "https://zplayer.live"
|
override var mainUrl: String = "https://zplayer.live"
|
||||||
}
|
}
|
||||||
|
|
||||||
class Upstream: ZplayerV2() {
|
class Upstream: ZplayerV2() {
|
||||||
override val name: String = "Upstream" //Here 'cause works
|
override var name: String = "Upstream" //Here 'cause works
|
||||||
override val mainUrl: String = "https://upstream.to"
|
override var mainUrl: String = "https://upstream.to"
|
||||||
}
|
}
|
||||||
|
|
||||||
class Streamhub2: ZplayerV2() {
|
class Streamhub2: ZplayerV2() {
|
||||||
override val name: String = "Streamhub" //Here 'cause works
|
override var name = "Streamhub" //Here 'cause works
|
||||||
override val mainUrl: String = "https://streamhub.to"
|
override var mainUrl = "https://streamhub.to"
|
||||||
}
|
}
|
||||||
|
|
||||||
open class ZplayerV2 : ExtractorApi() {
|
open class ZplayerV2 : ExtractorApi() {
|
||||||
override val name = "Zplayer V2"
|
override var name = "Zplayer V2"
|
||||||
override val mainUrl = "https://v2.zplayer.live"
|
override var mainUrl = "https://v2.zplayer.live"
|
||||||
override val requiresReferer = false
|
override val requiresReferer = false
|
||||||
|
|
||||||
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> {
|
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
|
|
||||||
class CrossTmdbProvider : TmdbProvider() {
|
class CrossTmdbProvider : TmdbProvider() {
|
||||||
override val name = "MultiMovie"
|
override var name = "MultiMovie"
|
||||||
override val apiName = "MultiMovie"
|
override val apiName = "MultiMovie"
|
||||||
override val lang = "en"
|
override val lang = "en"
|
||||||
override val useMetaLoadResponse = true
|
override val useMetaLoadResponse = true
|
||||||
|
|
|
@ -9,8 +9,8 @@ import org.jsoup.nodes.Element
|
||||||
|
|
||||||
class AkwamProvider : MainAPI() {
|
class AkwamProvider : MainAPI() {
|
||||||
override val lang = "ar"
|
override val lang = "ar"
|
||||||
override val mainUrl = "https://akwam.to"
|
override var mainUrl = "https://akwam.to"
|
||||||
override val name = "Akwam"
|
override var name = "Akwam"
|
||||||
override val usesWebView = false
|
override val usesWebView = false
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val supportedTypes = setOf(TvType.TvSeries, TvType.Movie, TvType.Anime, TvType.Cartoon)
|
override val supportedTypes = setOf(TvType.TvSeries, TvType.Movie, TvType.Anime, TvType.Cartoon)
|
||||||
|
|
|
@ -19,8 +19,8 @@ class AllMoviesForYouProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetching movies will not work if this link is outdated.
|
// Fetching movies will not work if this link is outdated.
|
||||||
override val mainUrl = "https://allmoviesforyou.net"
|
override var mainUrl = "https://allmoviesforyou.net"
|
||||||
override val name = "AllMoviesForYou"
|
override var name = "AllMoviesForYou"
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val supportedTypes = setOf(
|
override val supportedTypes = setOf(
|
||||||
TvType.Movie,
|
TvType.Movie,
|
||||||
|
@ -149,7 +149,7 @@ class AllMoviesForYouProvider : MainAPI() {
|
||||||
name,
|
name,
|
||||||
season.first,
|
season.first,
|
||||||
epNum,
|
epNum,
|
||||||
href,
|
fixUrl(href),
|
||||||
fixUrlNull(poster),
|
fixUrlNull(poster),
|
||||||
date
|
date
|
||||||
)
|
)
|
||||||
|
@ -175,7 +175,7 @@ class AllMoviesForYouProvider : MainAPI() {
|
||||||
title,
|
title,
|
||||||
url,
|
url,
|
||||||
type,
|
type,
|
||||||
url
|
fixUrl(url)
|
||||||
) {
|
) {
|
||||||
posterUrl = backgroundPoster
|
posterUrl = backgroundPoster
|
||||||
this.year = year?.toIntOrNull()
|
this.year = year?.toIntOrNull()
|
||||||
|
@ -193,12 +193,12 @@ class AllMoviesForYouProvider : MainAPI() {
|
||||||
callback: (ExtractorLink) -> Unit
|
callback: (ExtractorLink) -> Unit
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val doc = app.get(data).document
|
val doc = app.get(data).document
|
||||||
val iframe = doc.select("body iframe").map { it.attr("src") }
|
val iframe = doc.select("body iframe").map { fixUrl(it.attr("src")) }
|
||||||
iframe.apmap { id ->
|
iframe.apmap { id ->
|
||||||
if (id.contains("trembed")) {
|
if (id.contains("trembed")) {
|
||||||
val soup = app.get(id).document
|
val soup = app.get(id).document
|
||||||
soup.select("body iframe").map {
|
soup.select("body iframe").map {
|
||||||
val link = it.attr("src").replace("streamhub.to/d/","streamhub.to/e/")
|
val link = fixUrl(it.attr("src").replace("streamhub.to/d/","streamhub.to/e/"))
|
||||||
loadExtractor(link, data, callback)
|
loadExtractor(link, data, callback)
|
||||||
}
|
}
|
||||||
} else loadExtractor(id, data, callback)
|
} else loadExtractor(id, data, callback)
|
||||||
|
|
|
@ -10,8 +10,8 @@ import com.lagradost.cloudstream3.utils.loadExtractor
|
||||||
|
|
||||||
class ApiMDBProvider : TmdbProvider() {
|
class ApiMDBProvider : TmdbProvider() {
|
||||||
override val apiName = "ApiMDB"
|
override val apiName = "ApiMDB"
|
||||||
override val name = "ApiMDB"
|
override var name = "ApiMDB"
|
||||||
override val mainUrl = "https://v2.apimdb.net"
|
override var mainUrl = "https://v2.apimdb.net"
|
||||||
override val useMetaLoadResponse = true
|
override val useMetaLoadResponse = true
|
||||||
override val instantLinkLoading = false
|
override val instantLinkLoading = false
|
||||||
override val supportedTypes = setOf(
|
override val supportedTypes = setOf(
|
||||||
|
|
|
@ -11,8 +11,8 @@ import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
|
||||||
class AsiaFlixProvider : MainAPI() {
|
class AsiaFlixProvider : MainAPI() {
|
||||||
override val mainUrl = "https://asiaflix.app"
|
override var mainUrl = "https://asiaflix.app"
|
||||||
override val name = "AsiaFlix"
|
override var name = "AsiaFlix"
|
||||||
override val hasQuickSearch = false
|
override val hasQuickSearch = false
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val hasChromecastSupport = false
|
override val hasChromecastSupport = false
|
||||||
|
|
|
@ -6,8 +6,8 @@ import com.lagradost.cloudstream3.TvType
|
||||||
* make the app know what functions to call
|
* make the app know what functions to call
|
||||||
*/
|
*/
|
||||||
class AsianLoadProvider : VidstreamProviderTemplate() {
|
class AsianLoadProvider : VidstreamProviderTemplate() {
|
||||||
override val name = "AsianLoad"
|
override var name = "AsianLoad"
|
||||||
override val mainUrl = "https://asianembed.io"
|
override var mainUrl = "https://asianembed.io"
|
||||||
override val homePageUrlList = listOf(
|
override val homePageUrlList = listOf(
|
||||||
mainUrl,
|
mainUrl,
|
||||||
"$mainUrl/recently-added-raw",
|
"$mainUrl/recently-added-raw",
|
||||||
|
|
|
@ -7,9 +7,18 @@ import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.loadExtractor
|
import com.lagradost.cloudstream3.utils.loadExtractor
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
|
|
||||||
class BflixProvider(providerUrl: String, providerName: String) : MainAPI() {
|
class FmoviesToProvider : BflixProvider() {
|
||||||
override val mainUrl = providerUrl
|
override var mainUrl = "https://fmovies.to"
|
||||||
override val name = providerName
|
override var name = "Fmovies.to"
|
||||||
|
}
|
||||||
|
class SflixProProvider : BflixProvider() {
|
||||||
|
override var mainUrl = "https://sflix.pro"
|
||||||
|
override var name = "Sflix.pro"
|
||||||
|
}
|
||||||
|
|
||||||
|
open class BflixProvider() : MainAPI() {
|
||||||
|
override var mainUrl = "https://bflix.ru"
|
||||||
|
override var name = "Bflix"
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val hasChromecastSupport = true
|
override val hasChromecastSupport = true
|
||||||
override val hasDownloadSupport = true
|
override val hasDownloadSupport = true
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
package com.lagradost.cloudstream3.movieproviders
|
package com.lagradost.cloudstream3.movieproviders
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.extractors.Cinestart
|
import com.lagradost.cloudstream3.extractors.Cinestart
|
||||||
import com.lagradost.cloudstream3.mvvm.logError
|
import com.lagradost.cloudstream3.mvvm.logError
|
||||||
import com.lagradost.cloudstream3.utils.*
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import java.util.*
|
import com.lagradost.cloudstream3.utils.loadExtractor
|
||||||
|
|
||||||
class CinecalidadProvider:MainAPI() {
|
class CinecalidadProvider:MainAPI() {
|
||||||
override val mainUrl: String
|
override var mainUrl = "https://cinecalidad.lol"
|
||||||
get() = "https://cinecalidad.lol"
|
override var name = "Cinecalidad"
|
||||||
override val name: String
|
|
||||||
get() = "Cinecalidad"
|
|
||||||
override val lang = "es"
|
override val lang = "es"
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val hasChromecastSupport = true
|
override val hasChromecastSupport = true
|
||||||
|
|
|
@ -9,8 +9,8 @@ import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class CuevanaProvider:MainAPI() {
|
class CuevanaProvider:MainAPI() {
|
||||||
override val mainUrl = "https://cuevana3.io"
|
override var mainUrl = "https://cuevana3.me"
|
||||||
override val name = "Cuevana"
|
override var name = "Cuevana"
|
||||||
override val lang = "es"
|
override val lang = "es"
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val hasChromecastSupport = true
|
override val hasChromecastSupport = true
|
||||||
|
@ -191,19 +191,19 @@ class CuevanaProvider:MainAPI() {
|
||||||
): Boolean {
|
): Boolean {
|
||||||
app.get(data).document.select("div.TPlayer.embed_div iframe").apmap {
|
app.get(data).document.select("div.TPlayer.embed_div iframe").apmap {
|
||||||
val iframe = fixUrl(it.attr("data-src"))
|
val iframe = fixUrl(it.attr("data-src"))
|
||||||
if (iframe.contains("api.cuevana3.io/fembed/")) {
|
if (iframe.contains("api.cuevana3.me/fembed/")) {
|
||||||
val femregex = Regex("(https.\\/\\/api\\.cuevana3\\.io\\/fembed\\/\\?h=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)")
|
val femregex = Regex("(https.\\/\\/api\\.cuevana3\\.me\\/fembed\\/\\?h=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)")
|
||||||
femregex.findAll(iframe).map { femreg ->
|
femregex.findAll(iframe).map { femreg ->
|
||||||
femreg.value
|
femreg.value
|
||||||
}.toList().apmap { fem ->
|
}.toList().apmap { fem ->
|
||||||
val key = fem.replace("https://api.cuevana3.io/fembed/?h=","")
|
val key = fem.replace("https://api.cuevana3.me/fembed/?h=","")
|
||||||
val url = app.post("https://api.cuevana3.io/fembed/api.php", allowRedirects = false, headers = mapOf("Host" to "api.cuevana3.io",
|
val url = app.post("https://api.cuevana3.me/fembed/api.php", allowRedirects = false, headers = mapOf("Host" to "api.cuevana3.me",
|
||||||
"User-Agent" to USER_AGENT,
|
"User-Agent" to USER_AGENT,
|
||||||
"Accept" to "application/json, text/javascript, */*; q=0.01",
|
"Accept" to "application/json, text/javascript, */*; q=0.01",
|
||||||
"Accept-Language" to "en-US,en;q=0.5",
|
"Accept-Language" to "en-US,en;q=0.5",
|
||||||
"Content-Type" to "application/x-www-form-urlencoded; charset=UTF-8",
|
"Content-Type" to "application/x-www-form-urlencoded; charset=UTF-8",
|
||||||
"X-Requested-With" to "XMLHttpRequest",
|
"X-Requested-With" to "XMLHttpRequest",
|
||||||
"Origin" to "https://api.cuevana3.io",
|
"Origin" to "https://api.cuevana3.me",
|
||||||
"DNT" to "1",
|
"DNT" to "1",
|
||||||
"Connection" to "keep-alive",
|
"Connection" to "keep-alive",
|
||||||
"Sec-Fetch-Dest" to "empty",
|
"Sec-Fetch-Dest" to "empty",
|
||||||
|
@ -239,12 +239,12 @@ class CuevanaProvider:MainAPI() {
|
||||||
data = mapOf(Pair("url",tomkey))
|
data = mapOf(Pair("url",tomkey))
|
||||||
).response.headers.values("location").apmap { loc ->
|
).response.headers.values("location").apmap { loc ->
|
||||||
if (loc.contains("goto_ddh.php")) {
|
if (loc.contains("goto_ddh.php")) {
|
||||||
val gotoregex = Regex("(\\/\\/api.cuevana3.io\\/ir\\/goto_ddh.php\\?h=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)")
|
val gotoregex = Regex("(\\/\\/api.cuevana3.me\\/ir\\/goto_ddh.php\\?h=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)")
|
||||||
gotoregex.findAll(loc).map { goreg ->
|
gotoregex.findAll(loc).map { goreg ->
|
||||||
goreg.value.replace("//api.cuevana3.io/ir/goto_ddh.php?h=","")
|
goreg.value.replace("//api.cuevana3.me/ir/goto_ddh.php?h=","")
|
||||||
}.toList().apmap { gotolink ->
|
}.toList().apmap { gotolink ->
|
||||||
app.post("https://api.cuevana3.io/ir/redirect_ddh.php", allowRedirects = false,
|
app.post("https://api.cuevana3.me/ir/redirect_ddh.php", allowRedirects = false,
|
||||||
headers = mapOf("Host" to "api.cuevana3.io",
|
headers = mapOf("Host" to "api.cuevana3.me",
|
||||||
"User-Agent" to USER_AGENT,
|
"User-Agent" to USER_AGENT,
|
||||||
"Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
|
"Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
|
||||||
"Accept-Language" to "en-US,en;q=0.5",
|
"Accept-Language" to "en-US,en;q=0.5",
|
||||||
|
@ -263,12 +263,12 @@ class CuevanaProvider:MainAPI() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (loc.contains("index.php?h=")) {
|
if (loc.contains("index.php?h=")) {
|
||||||
val indexRegex = Regex("(\\/\\/api.cuevana3.io\\/sc\\/index.php\\?h=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)")
|
val indexRegex = Regex("(\\/\\/api.cuevana3.me\\/sc\\/index.php\\?h=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)")
|
||||||
indexRegex.findAll(loc).map { indreg ->
|
indexRegex.findAll(loc).map { indreg ->
|
||||||
indreg.value.replace("//api.cuevana3.io/sc/index.php?h=","")
|
indreg.value.replace("//api.cuevana3.me/sc/index.php?h=","")
|
||||||
}.toList().apmap { inlink ->
|
}.toList().apmap { inlink ->
|
||||||
app.post("https://api.cuevana3.io/sc/r.php", allowRedirects = false,
|
app.post("https://api.cuevana3.me/sc/r.php", allowRedirects = false,
|
||||||
headers = mapOf("Host" to "api.cuevana3.io",
|
headers = mapOf("Host" to "api.cuevana3.me",
|
||||||
"User-Agent" to USER_AGENT,
|
"User-Agent" to USER_AGENT,
|
||||||
"Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
|
"Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
|
||||||
"Accept-Language" to "en-US,en;q=0.5",
|
"Accept-Language" to "en-US,en;q=0.5",
|
||||||
|
|
|
@ -16,8 +16,8 @@ class DoramasYTProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val mainUrl = "https://doramasyt.com"
|
override var mainUrl = "https://doramasyt.com"
|
||||||
override val name = "DoramasYT"
|
override var name = "DoramasYT"
|
||||||
override val lang = "es"
|
override val lang = "es"
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val hasChromecastSupport = true
|
override val hasChromecastSupport = true
|
||||||
|
|
|
@ -10,8 +10,8 @@ import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.loadExtractor
|
import com.lagradost.cloudstream3.utils.loadExtractor
|
||||||
|
|
||||||
class DramaSeeProvider : MainAPI() {
|
class DramaSeeProvider : MainAPI() {
|
||||||
override val mainUrl = "https://dramasee.net"
|
override var mainUrl = "https://dramasee.net"
|
||||||
override val name = "DramaSee"
|
override var name = "DramaSee"
|
||||||
override val hasQuickSearch = false
|
override val hasQuickSearch = false
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val hasChromecastSupport = false
|
override val hasChromecastSupport = false
|
||||||
|
|
|
@ -8,8 +8,8 @@ import org.jsoup.nodes.Element
|
||||||
|
|
||||||
class EgyBestProvider : MainAPI() {
|
class EgyBestProvider : MainAPI() {
|
||||||
override val lang = "ar"
|
override val lang = "ar"
|
||||||
override val mainUrl = "https://egy.best"
|
override var mainUrl = "https://egy.best"
|
||||||
override val name = "EgyBest"
|
override var name = "EgyBest"
|
||||||
override val usesWebView = false
|
override val usesWebView = false
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val supportedTypes = setOf(TvType.TvSeries, TvType.Movie)
|
override val supportedTypes = setOf(TvType.TvSeries, TvType.Movie)
|
||||||
|
|
|
@ -6,8 +6,8 @@ import com.lagradost.cloudstream3.utils.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class EntrepeliculasyseriesProvider:MainAPI() {
|
class EntrepeliculasyseriesProvider:MainAPI() {
|
||||||
override val mainUrl = "https://entrepeliculasyseries.nu"
|
override var mainUrl = "https://entrepeliculasyseries.nu"
|
||||||
override val name = "EntrePeliculasySeries"
|
override var name = "EntrePeliculasySeries"
|
||||||
override val lang = "es"
|
override val lang = "es"
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val hasChromecastSupport = true
|
override val hasChromecastSupport = true
|
||||||
|
|
|
@ -9,8 +9,8 @@ import org.jsoup.Jsoup
|
||||||
import org.jsoup.select.Elements
|
import org.jsoup.select.Elements
|
||||||
|
|
||||||
class FilmanProvider : MainAPI() {
|
class FilmanProvider : MainAPI() {
|
||||||
override val mainUrl = "https://filman.cc"
|
override var mainUrl = "https://filman.cc"
|
||||||
override val name = "filman.cc"
|
override var name = "filman.cc"
|
||||||
override val lang = "pl"
|
override val lang = "pl"
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val supportedTypes = setOf(
|
override val supportedTypes = setOf(
|
||||||
|
|
|
@ -6,8 +6,8 @@ import com.lagradost.cloudstream3.utils.Qualities
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
|
|
||||||
class HDMProvider : MainAPI() {
|
class HDMProvider : MainAPI() {
|
||||||
override val name = "HD Movies"
|
override var name = "HD Movies"
|
||||||
override val mainUrl = "https://hdm.to"
|
override var mainUrl = "https://hdm.to"
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
|
|
||||||
override val supportedTypes = setOf(
|
override val supportedTypes = setOf(
|
||||||
|
|
|
@ -7,8 +7,8 @@ import org.jsoup.Jsoup
|
||||||
import java.net.URLEncoder
|
import java.net.URLEncoder
|
||||||
|
|
||||||
class IHaveNoTvProvider : MainAPI() {
|
class IHaveNoTvProvider : MainAPI() {
|
||||||
override val mainUrl = "https://ihavenotv.com"
|
override var mainUrl = "https://ihavenotv.com"
|
||||||
override val name = "I Have No TV"
|
override var name = "I Have No TV"
|
||||||
override val hasQuickSearch = false
|
override val hasQuickSearch = false
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,8 @@ import com.lagradost.cloudstream3.utils.loadExtractor
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
|
|
||||||
class KdramaHoodProvider : MainAPI() {
|
class KdramaHoodProvider : MainAPI() {
|
||||||
override val mainUrl = "https://kdramahood.com"
|
override var mainUrl = "https://kdramahood.com"
|
||||||
override val name = "KDramaHood"
|
override var name = "KDramaHood"
|
||||||
override val hasQuickSearch = false
|
override val hasQuickSearch = false
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val hasChromecastSupport = false
|
override val hasChromecastSupport = false
|
||||||
|
|
|
@ -13,8 +13,8 @@ import org.jsoup.Jsoup
|
||||||
//BE AWARE THAT weboas.is is a clone of lookmovie
|
//BE AWARE THAT weboas.is is a clone of lookmovie
|
||||||
class LookMovieProvider : MainAPI() {
|
class LookMovieProvider : MainAPI() {
|
||||||
override val hasQuickSearch = true
|
override val hasQuickSearch = true
|
||||||
override val name = "LookMovie"
|
override var name = "LookMovie"
|
||||||
override val mainUrl = "https://lookmovie.io"
|
override var mainUrl = "https://lookmovie.io"
|
||||||
|
|
||||||
override val supportedTypes = setOf(
|
override val supportedTypes = setOf(
|
||||||
TvType.Movie,
|
TvType.Movie,
|
||||||
|
|
|
@ -11,8 +11,8 @@ import org.jsoup.Jsoup
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
|
|
||||||
class MeloMovieProvider : MainAPI() {
|
class MeloMovieProvider : MainAPI() {
|
||||||
override val name = "MeloMovie"
|
override var name = "MeloMovie"
|
||||||
override val mainUrl = "https://melomovie.com"
|
override var mainUrl = "https://melomovie.com"
|
||||||
override val instantLinkLoading = true
|
override val instantLinkLoading = true
|
||||||
override val hasQuickSearch = true
|
override val hasQuickSearch = true
|
||||||
override val hasChromecastSupport = false // MKV FILES CANT BE PLAYED ON A CHROMECAST
|
override val hasChromecastSupport = false // MKV FILES CANT BE PLAYED ON A CHROMECAST
|
||||||
|
|
|
@ -9,8 +9,8 @@ import org.jsoup.nodes.Element
|
||||||
|
|
||||||
class MyCimaProvider : MainAPI() {
|
class MyCimaProvider : MainAPI() {
|
||||||
override val lang = "ar"
|
override val lang = "ar"
|
||||||
override val mainUrl = "https://mycima.tv"
|
override var mainUrl = "https://mycima.tv"
|
||||||
override val name = "MyCima"
|
override var name = "MyCima"
|
||||||
override val usesWebView = false
|
override val usesWebView = false
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val supportedTypes = setOf(TvType.TvSeries, TvType.Movie)
|
override val supportedTypes = setOf(TvType.TvSeries, TvType.Movie)
|
||||||
|
|
|
@ -7,8 +7,8 @@ import com.lagradost.cloudstream3.utils.loadExtractor
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
class PeliSmartProvider: MainAPI() {
|
class PeliSmartProvider: MainAPI() {
|
||||||
override val mainUrl = "https://pelismart.com"
|
override var mainUrl = "https://pelismart.com"
|
||||||
override val name = "PeliSmart"
|
override var name = "PeliSmart"
|
||||||
override val lang = "es"
|
override val lang = "es"
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val hasChromecastSupport = true
|
override val hasChromecastSupport = true
|
||||||
|
|
|
@ -7,8 +7,8 @@ import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.loadExtractor
|
import com.lagradost.cloudstream3.utils.loadExtractor
|
||||||
|
|
||||||
class PelisflixProvider : MainAPI() {
|
class PelisflixProvider : MainAPI() {
|
||||||
override val mainUrl = "https://pelisflix.li"
|
override var mainUrl = "https://pelisflix.li"
|
||||||
override val name = "Pelisflix"
|
override var name = "Pelisflix"
|
||||||
override val lang = "es"
|
override val lang = "es"
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val hasChromecastSupport = true
|
override val hasChromecastSupport = true
|
||||||
|
|
|
@ -6,8 +6,8 @@ import org.jsoup.nodes.Element
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class PelisplusHDProvider:MainAPI() {
|
class PelisplusHDProvider:MainAPI() {
|
||||||
override val mainUrl = "https://pelisplushd.net"
|
override var mainUrl = "https://pelisplushd.net"
|
||||||
override val name = "PelisplusHD"
|
override var name = "PelisplusHD"
|
||||||
override val lang = "es"
|
override val lang = "es"
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val hasChromecastSupport = true
|
override val hasChromecastSupport = true
|
||||||
|
|
|
@ -7,10 +7,10 @@ import com.lagradost.cloudstream3.TvType
|
||||||
*/
|
*/
|
||||||
class PelisplusProvider : PelisplusProviderTemplate() {
|
class PelisplusProvider : PelisplusProviderTemplate() {
|
||||||
// mainUrl is good to have as a holder for the url to make future changes easier.
|
// mainUrl is good to have as a holder for the url to make future changes easier.
|
||||||
override val mainUrl = "https://pelisplus.icu"
|
override var mainUrl = "https://pelisplus.icu"
|
||||||
|
|
||||||
// name is for how the provider will be named which is visible in the UI, no real rules for this.
|
// name is for how the provider will be named which is visible in the UI, no real rules for this.
|
||||||
override val name = "Pelisplus"
|
override var name = "Pelisplus"
|
||||||
|
|
||||||
override val homePageUrlList = listOf(
|
override val homePageUrlList = listOf(
|
||||||
mainUrl,
|
mainUrl,
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
package com.lagradost.cloudstream3.movieproviders
|
package com.lagradost.cloudstream3.movieproviders
|
||||||
|
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.extractors.Pelisplus
|
import com.lagradost.cloudstream3.utils.*
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import java.net.URI
|
|
||||||
|
|
||||||
/** Needs to inherit from MainAPI() to
|
/** Needs to inherit from MainAPI() to
|
||||||
* make the app know what functions to call
|
* make the app know what functions to call
|
||||||
|
@ -14,7 +11,6 @@ import java.net.URI
|
||||||
open class PelisplusProviderTemplate : MainAPI() {
|
open class PelisplusProviderTemplate : MainAPI() {
|
||||||
override val lang = "es"
|
override val lang = "es"
|
||||||
open val homePageUrlList = listOf<String>()
|
open val homePageUrlList = listOf<String>()
|
||||||
open val pelisplusExtractorUrl: String? = null
|
|
||||||
|
|
||||||
// // mainUrl is good to have as a holder for the url to make future changes easier.
|
// // mainUrl is good to have as a holder for the url to make future changes easier.
|
||||||
// override val mainUrl: String
|
// override val mainUrl: String
|
||||||
|
@ -35,6 +31,7 @@ open class PelisplusProviderTemplate : MainAPI() {
|
||||||
|
|
||||||
// Searching returns a SearchResponse, which can be one of the following: AnimeSearchResponse, MovieSearchResponse, TorrentSearchResponse, TvSeriesSearchResponse
|
// Searching returns a SearchResponse, which can be one of the following: AnimeSearchResponse, MovieSearchResponse, TorrentSearchResponse, TvSeriesSearchResponse
|
||||||
// Each of the classes requires some different data, but always has some critical things like name, poster and url.
|
// Each of the classes requires some different data, but always has some critical things like name, poster and url.
|
||||||
|
|
||||||
override suspend fun search(query: String): ArrayList<SearchResponse> {
|
override suspend fun search(query: String): ArrayList<SearchResponse> {
|
||||||
// Simply looking at devtools network is enough to spot a request like:
|
// Simply looking at devtools network is enough to spot a request like:
|
||||||
// https://vidembed.cc/search.html?keyword=neverland where neverland is the query, can be written as below.
|
// https://vidembed.cc/search.html?keyword=neverland where neverland is the query, can be written as below.
|
||||||
|
@ -48,7 +45,7 @@ open class PelisplusProviderTemplate : MainAPI() {
|
||||||
val poster = fixUrl(li.selectFirst("img").attr("src"))
|
val poster = fixUrl(li.selectFirst("img").attr("src"))
|
||||||
|
|
||||||
// .text() selects all the text in the element, be careful about doing this while too high up in the html hierarchy
|
// .text() selects all the text in the element, be careful about doing this while too high up in the html hierarchy
|
||||||
val title = li.selectFirst(".name").text()
|
val title = cleanName(li.selectFirst(".name").text())
|
||||||
// Use get(0) and toIntOrNull() to prevent any possible crashes, [0] or toInt() will error the search on unexpected values.
|
// Use get(0) and toIntOrNull() to prevent any possible crashes, [0] or toInt() will error the search on unexpected values.
|
||||||
val year = li.selectFirst(".date")?.text()?.split("-")?.get(0)?.toIntOrNull()
|
val year = li.selectFirst(".date")?.text()?.split("-")?.get(0)?.toIntOrNull()
|
||||||
|
|
||||||
|
@ -73,33 +70,29 @@ open class PelisplusProviderTemplate : MainAPI() {
|
||||||
val html = app.get(url).text
|
val html = app.get(url).text
|
||||||
val soup = Jsoup.parse(html)
|
val soup = Jsoup.parse(html)
|
||||||
|
|
||||||
var title = soup.selectFirst("h1,h2,h3").text()
|
val title = cleanName(soup.selectFirst("h1,h2,h3").text())
|
||||||
title = if (!title.contains("Episode")) title else title.split("Episode")[0].trim()
|
|
||||||
|
|
||||||
val description = soup.selectFirst(".post-entry")?.text()?.trim()
|
val description = soup.selectFirst(".post-entry")?.text()?.trim()
|
||||||
var poster: String? = null
|
val poster = soup.selectFirst("head meta[property=og:image]").attr("content")
|
||||||
|
|
||||||
val episodes = soup.select(".listing.items.lists > .video-block").map { li ->
|
val episodes = soup.select(".listing.items.lists > .video-block").map { li ->
|
||||||
val epTitle = if (li.selectFirst(".name") != null)
|
val href = fixUrl(li.selectFirst("a").attr("href"))
|
||||||
if (li.selectFirst(".name").text().contains("Episode"))
|
val regexseason = Regex("(-[Tt]emporada-(\\d+)-[Cc]apitulo-(\\d+))")
|
||||||
"Episode " + li.selectFirst(".name").text().split("Episode")[1].trim()
|
val aaa = regexseason.find(href)?.destructured?.component1()?.replace(Regex("(-[Tt]emporada-|[Cc]apitulo-)"),"")
|
||||||
else
|
val seasonid = aaa.let { str ->
|
||||||
li.selectFirst(".name").text()
|
str?.split("-")?.mapNotNull { subStr -> subStr.toIntOrNull() }
|
||||||
else ""
|
}
|
||||||
|
val isValid = seasonid?.size == 2
|
||||||
|
val episode = if (isValid) seasonid?.getOrNull(1) else null
|
||||||
|
val season = if (isValid) seasonid?.getOrNull(0) else null
|
||||||
val epThumb = fixUrl(li.selectFirst("img").attr("src"))
|
val epThumb = fixUrl(li.selectFirst("img").attr("src"))
|
||||||
val epDate = li.selectFirst(".meta > .date").text()
|
val epDate = li.selectFirst(".meta > .date").text()
|
||||||
|
|
||||||
if (poster == null) {
|
|
||||||
poster = li.selectFirst("img")?.attr("onerror")?.replace("//img", "https://img")?.split("=")?.get(1)
|
|
||||||
?.replace(Regex("[';]"), "")
|
|
||||||
}
|
|
||||||
|
|
||||||
val epNum = Regex("""Episode (\d+)""").find(epTitle)?.destructured?.component1()?.toIntOrNull()
|
|
||||||
|
|
||||||
TvSeriesEpisode(
|
TvSeriesEpisode(
|
||||||
epTitle,
|
|
||||||
null,
|
null,
|
||||||
epNum,
|
season,
|
||||||
|
episode,
|
||||||
fixUrl(li.selectFirst("a").attr("href")),
|
fixUrl(li.selectFirst("a").attr("href")),
|
||||||
epThumb,
|
epThumb,
|
||||||
epDate
|
epDate
|
||||||
|
@ -119,10 +112,10 @@ open class PelisplusProviderTemplate : MainAPI() {
|
||||||
this.name,
|
this.name,
|
||||||
tvType,
|
tvType,
|
||||||
episodes,
|
episodes,
|
||||||
poster,
|
fixUrl(poster),
|
||||||
year,
|
year,
|
||||||
description,
|
description,
|
||||||
ShowStatus.Ongoing,
|
null,
|
||||||
null,
|
null,
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
|
@ -134,7 +127,7 @@ open class PelisplusProviderTemplate : MainAPI() {
|
||||||
this.name,
|
this.name,
|
||||||
tvType,
|
tvType,
|
||||||
episodes[0].data,
|
episodes[0].data,
|
||||||
poster,
|
fixUrl(poster),
|
||||||
year,
|
year,
|
||||||
description,
|
description,
|
||||||
null,
|
null,
|
||||||
|
@ -156,12 +149,12 @@ open class PelisplusProviderTemplate : MainAPI() {
|
||||||
val document = Jsoup.parse(response)
|
val document = Jsoup.parse(response)
|
||||||
document.select("div.main-inner")?.forEach { inner ->
|
document.select("div.main-inner")?.forEach { inner ->
|
||||||
// Always trim your text unless you want the risk of spaces at the start or end.
|
// Always trim your text unless you want the risk of spaces at the start or end.
|
||||||
val title = inner.select(".widget-title").text().trim()
|
val title = cleanName(inner.select(".widget-title").text())
|
||||||
val elements = inner.select(".video-block").map {
|
val elements = inner.select(".video-block").map {
|
||||||
val link = fixUrl(it.select("a").attr("href"))
|
val link = fixUrl(it.select("a").attr("href"))
|
||||||
val image = it.select(".picture > img").attr("src").replace("//img", "https://img")
|
val image = it.select(".picture > img").attr("src").replace("//img", "https://img")
|
||||||
val name = it.select("div.name").text().trim().replace(Regex("""[Ee]pisode \d+"""), "")
|
val name = cleanName(it.select("div.name").text())
|
||||||
val isSeries = (name.contains("Season") || name.contains("Episode"))
|
val isSeries = (name.contains("Temporada") || name.contains("Capítulo"))
|
||||||
|
|
||||||
if (isSeries) {
|
if (isSeries) {
|
||||||
TvSeriesSearchResponse(
|
TvSeriesSearchResponse(
|
||||||
|
@ -198,6 +191,38 @@ open class PelisplusProviderTemplate : MainAPI() {
|
||||||
return HomePageResponse(homePageList)
|
return HomePageResponse(homePageList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun cleanName(input: String): String = input.replace(Regex("([Tt]emporada (\\d+)|[Cc]apítulo (\\d+))|[Tt]emporada|[Cc]apítulo"),"").trim()
|
||||||
|
|
||||||
|
|
||||||
|
private suspend fun getPelisStream(
|
||||||
|
link: String,
|
||||||
|
callback: (ExtractorLink) -> Unit) : Boolean {
|
||||||
|
val soup = app.get(link).text
|
||||||
|
val m3u8regex = Regex("((https:|http:)\\/\\/.*m3u8.*expiry=(\\d+))")
|
||||||
|
val m3u8 = m3u8regex.find(soup)?.value ?: return false
|
||||||
|
M3u8Helper().m3u8Generation(
|
||||||
|
M3u8Helper.M3u8Stream(
|
||||||
|
m3u8,
|
||||||
|
headers = mapOf("Referer" to mainUrl)
|
||||||
|
), true
|
||||||
|
)
|
||||||
|
.map { stream ->
|
||||||
|
val qualityString = if ((stream.quality ?: 0) == 0) "" else "${stream.quality}p"
|
||||||
|
callback(
|
||||||
|
ExtractorLink(
|
||||||
|
name,
|
||||||
|
"$name $qualityString",
|
||||||
|
stream.streamUrl,
|
||||||
|
mainUrl,
|
||||||
|
getQualityFromName(stream.quality.toString()),
|
||||||
|
true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// loadLinks gets the raw .mp4 or .m3u8 urls from the data parameter in the episodes class generated in load()
|
// loadLinks gets the raw .mp4 or .m3u8 urls from the data parameter in the episodes class generated in load()
|
||||||
// See TvSeriesEpisode(...) in this provider.
|
// See TvSeriesEpisode(...) in this provider.
|
||||||
// The data are usually links, but can be any other string to help aid loading the links.
|
// The data are usually links, but can be any other string to help aid loading the links.
|
||||||
|
@ -208,67 +233,37 @@ open class PelisplusProviderTemplate : MainAPI() {
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
callback: (ExtractorLink) -> Unit
|
callback: (ExtractorLink) -> Unit
|
||||||
): Boolean {
|
): Boolean {
|
||||||
// "?: return" is a very useful statement which returns if the iframe link isn't found.
|
val doc = app.get(data).document
|
||||||
val iframeLink = Jsoup.parse(app.get(data).text).selectFirst(".tab-video")?.attr("data-video") ?: return false
|
val info = doc.select("div.tabs-video li").text()
|
||||||
|
if (info.contains("Latino")) {
|
||||||
// In this case the video player is a vidstream clone and can be handled by the vidstream extractor.
|
doc.select(".server-item-1 li").apmap {
|
||||||
// This case is a both unorthodox and you normally do not call extractors as they detect the url returned and does the rest.
|
val serverid = fixUrl(it.attr("data-video")).replace("streaming.php","play")
|
||||||
val vidstreamObject = Pelisplus(pelisplusExtractorUrl ?: mainUrl)
|
loadExtractor(serverid, data, callback)
|
||||||
// https://vidembed.cc/streaming.php?id=MzUwNTY2&... -> MzUwNTY2
|
if (serverid.contains("pelisplus.icu")) {
|
||||||
val id = Regex("""id=([^?]*)""").find(iframeLink)?.groupValues?.get(1)
|
getPelisStream(serverid, callback)
|
||||||
|
|
||||||
if (id != null) {
|
|
||||||
vidstreamObject.getUrl(id, isCasting, callback)
|
|
||||||
}
|
|
||||||
|
|
||||||
val html = app.get(fixUrl(iframeLink)).text
|
|
||||||
val soup = Jsoup.parse(html)
|
|
||||||
|
|
||||||
val servers = soup.select(".list-server-items > .linkserver").mapNotNull { li ->
|
|
||||||
if (!li?.attr("data-video").isNullOrEmpty()) {
|
|
||||||
Pair(li.text(), fixUrl(li.attr("data-video")))
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
servers.apmap {
|
|
||||||
// When checking strings make sure to make them lowercase and trimmed because edgecases like "beta server " wouldn't work otherwise.
|
|
||||||
if (it.first.trim().equals("beta server", ignoreCase = true)) {
|
|
||||||
// Group 1: link, Group 2: Label
|
|
||||||
// Regex can be used to effectively parse small amounts of json without bothering with writing a json class.
|
|
||||||
val sourceRegex = Regex("""sources:[\W\w]*?file:\s*["'](.*?)["'][\W\w]*?label:\s*["'](.*?)["']""")
|
|
||||||
val trackRegex = Regex("""tracks:[\W\w]*?file:\s*["'](.*?)["'][\W\w]*?label:\s*["'](.*?)["']""")
|
|
||||||
|
|
||||||
// Having a referer is often required. It's a basic security check most providers have.
|
|
||||||
// Try to replicate what your browser does.
|
|
||||||
val serverHtml = app.get(it.second, headers = mapOf("referer" to iframeLink)).text
|
|
||||||
sourceRegex.findAll(serverHtml).forEach { match ->
|
|
||||||
callback.invoke(
|
|
||||||
ExtractorLink(
|
|
||||||
this.name,
|
|
||||||
match.groupValues.getOrNull(2)?.let { "${this.name} $it" } ?: this.name,
|
|
||||||
match.groupValues[1],
|
|
||||||
it.second,
|
|
||||||
// Useful function to turn something like "1080p" to an app quality.
|
|
||||||
getQualityFromName(match.groupValues.getOrNull(2) ?: ""),
|
|
||||||
// Kinda risky
|
|
||||||
// isM3u8 makes the player pick the correct extractor for the source.
|
|
||||||
// If isM3u8 is wrong the player will error on that source.
|
|
||||||
URI(match.groupValues[1]).path.endsWith(".m3u8"),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
trackRegex.findAll(serverHtml).forEach { match ->
|
|
||||||
subtitleCallback.invoke(
|
|
||||||
SubtitleFile(
|
|
||||||
match.groupValues.getOrNull(2) ?: "Unknown",
|
|
||||||
match.groupValues[1]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (info.contains("Subtitulado")) {
|
||||||
|
doc.select(".server-item-0 li").apmap {
|
||||||
|
val serverid = fixUrl(it.attr("data-video")).replace("streaming.php","play")
|
||||||
|
loadExtractor(serverid, data, callback)
|
||||||
|
if (serverid.contains("pelisplus.icu")) {
|
||||||
|
getPelisStream(serverid, callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.contains("Castellano")) {
|
||||||
|
doc.select(".server-item-2 li").apmap {
|
||||||
|
val serverid = fixUrl(it.attr("data-video")).replace("streaming.php","play")
|
||||||
|
loadExtractor(serverid, data, callback)
|
||||||
|
if (serverid.contains("pelisplus.icu")) {
|
||||||
|
getPelisStream(serverid, callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,8 @@ import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.loadExtractor
|
import com.lagradost.cloudstream3.utils.loadExtractor
|
||||||
|
|
||||||
class PinoyHDXyzProvider : MainAPI() {
|
class PinoyHDXyzProvider : MainAPI() {
|
||||||
override val name = "Pinoy-HD"
|
override var name = "Pinoy-HD"
|
||||||
override val mainUrl = "https://www.pinoy-hd.xyz"
|
override var mainUrl = "https://www.pinoy-hd.xyz"
|
||||||
override val lang = "tl"
|
override val lang = "tl"
|
||||||
override val supportedTypes = setOf(TvType.Movie, TvType.TvSeries)
|
override val supportedTypes = setOf(TvType.Movie, TvType.TvSeries)
|
||||||
override val hasDownloadSupport = true
|
override val hasDownloadSupport = true
|
||||||
|
|
|
@ -9,8 +9,8 @@ import com.lagradost.cloudstream3.utils.loadExtractor
|
||||||
import java.lang.Exception
|
import java.lang.Exception
|
||||||
|
|
||||||
class PinoyMoviePediaProvider : MainAPI() {
|
class PinoyMoviePediaProvider : MainAPI() {
|
||||||
override val name = "Pinoy Moviepedia"
|
override var name = "Pinoy Moviepedia"
|
||||||
override val mainUrl = "https://pinoymoviepedia.ru"
|
override var mainUrl = "https://pinoymoviepedia.ru"
|
||||||
override val lang = "tl"
|
override val lang = "tl"
|
||||||
override val supportedTypes = setOf(TvType.Movie, TvType.TvSeries)
|
override val supportedTypes = setOf(TvType.Movie, TvType.TvSeries)
|
||||||
override val hasDownloadSupport = true
|
override val hasDownloadSupport = true
|
||||||
|
|
|
@ -13,8 +13,8 @@ import org.jsoup.select.Elements
|
||||||
import java.lang.Exception
|
import java.lang.Exception
|
||||||
|
|
||||||
class PinoyMoviesEsProvider : MainAPI() {
|
class PinoyMoviesEsProvider : MainAPI() {
|
||||||
override val name = "Pinoy Movies"
|
override var name = "Pinoy Movies"
|
||||||
override val mainUrl = "https://pinoymovies.es"
|
override var mainUrl = "https://pinoymovies.es"
|
||||||
override val lang = "tl"
|
override val lang = "tl"
|
||||||
override val supportedTypes = setOf(TvType.Movie)
|
override val supportedTypes = setOf(TvType.Movie)
|
||||||
override val hasDownloadSupport = false
|
override val hasDownloadSupport = false
|
||||||
|
|
|
@ -7,8 +7,8 @@ import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.loadExtractor
|
import com.lagradost.cloudstream3.utils.loadExtractor
|
||||||
|
|
||||||
class SeriesflixProvider : MainAPI() {
|
class SeriesflixProvider : MainAPI() {
|
||||||
override val mainUrl = "https://seriesflix.video"
|
override var mainUrl = "https://seriesflix.video"
|
||||||
override val name = "Seriesflix"
|
override var name = "Seriesflix"
|
||||||
override val lang = "es"
|
override val lang = "es"
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val hasChromecastSupport = true
|
override val hasChromecastSupport = true
|
||||||
|
|
|
@ -21,9 +21,18 @@ import org.jsoup.nodes.Element
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import kotlin.system.measureTimeMillis
|
import kotlin.system.measureTimeMillis
|
||||||
|
|
||||||
class SflixProvider(providerUrl: String, providerName: String) : MainAPI() {
|
class DopeboxProvider : SflixProvider() {
|
||||||
override val mainUrl = providerUrl
|
override var mainUrl = "https://dopebox.to"
|
||||||
override val name = providerName
|
override var name = "Dopebox"
|
||||||
|
}
|
||||||
|
class SolarmovieProvider : SflixProvider() {
|
||||||
|
override var mainUrl = "https://solarmovie.pe"
|
||||||
|
override var name = "Solarmovie"
|
||||||
|
}
|
||||||
|
|
||||||
|
open class SflixProvider() : MainAPI() {
|
||||||
|
override var mainUrl = "https://sflix.to"
|
||||||
|
override var name = "Sflix.to"
|
||||||
|
|
||||||
override val hasQuickSearch = false
|
override val hasQuickSearch = false
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
|
|
|
@ -8,8 +8,8 @@ import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class SoaptwoDayProvider:MainAPI() {
|
class SoaptwoDayProvider:MainAPI() {
|
||||||
override val mainUrl = "https://secretlink.xyz" //Probably a rip off, but it has no captcha
|
override var mainUrl = "https://secretlink.xyz" //Probably a rip off, but it has no captcha
|
||||||
override val name = "Soap2Day"
|
override var name = "Soap2Day"
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val hasChromecastSupport = true
|
override val hasChromecastSupport = true
|
||||||
override val hasDownloadSupport = true
|
override val hasDownloadSupport = true
|
||||||
|
|
|
@ -12,8 +12,8 @@ import com.lagradost.cloudstream3.utils.SubtitleHelper
|
||||||
class TrailersTwoProvider : TmdbProvider() {
|
class TrailersTwoProvider : TmdbProvider() {
|
||||||
val user = "cloudstream"
|
val user = "cloudstream"
|
||||||
override val apiName = "Trailers.to"
|
override val apiName = "Trailers.to"
|
||||||
override val name = "Trailers.to"
|
override var name = "Trailers.to"
|
||||||
override val mainUrl = "https://trailers.to"
|
override var mainUrl = "https://trailers.to"
|
||||||
override val useMetaLoadResponse = true
|
override val useMetaLoadResponse = true
|
||||||
override val instantLinkLoading = true
|
override val instantLinkLoading = true
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,8 @@ import com.lagradost.cloudstream3.utils.loadExtractor
|
||||||
|
|
||||||
class TwoEmbedProvider : TmdbProvider() {
|
class TwoEmbedProvider : TmdbProvider() {
|
||||||
override val apiName = "2Embed"
|
override val apiName = "2Embed"
|
||||||
override val name = "2Embed"
|
override var name = "2Embed"
|
||||||
override val mainUrl = "https://www.2embed.ru"
|
override var mainUrl = "https://www.2embed.ru"
|
||||||
override val useMetaLoadResponse = true
|
override val useMetaLoadResponse = true
|
||||||
override val instantLinkLoading = false
|
override val instantLinkLoading = false
|
||||||
override val supportedTypes = setOf(
|
override val supportedTypes = setOf(
|
||||||
|
|
|
@ -8,8 +8,8 @@ import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
|
|
||||||
class VMoveeProvider : MainAPI() {
|
class VMoveeProvider : MainAPI() {
|
||||||
override val name = "VMovee"
|
override var name = "VMovee"
|
||||||
override val mainUrl = "https://www.vmovee.watch"
|
override var mainUrl = "https://www.vmovee.watch"
|
||||||
|
|
||||||
override val supportedTypes = setOf(TvType.Movie)
|
override val supportedTypes = setOf(TvType.Movie)
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,8 @@ import org.jsoup.Jsoup
|
||||||
|
|
||||||
// referer = https://vf-film.org, USERAGENT ALSO REQUIRED
|
// referer = https://vf-film.org, USERAGENT ALSO REQUIRED
|
||||||
class VfFilmProvider : MainAPI() {
|
class VfFilmProvider : MainAPI() {
|
||||||
override val mainUrl = "https://vf-film.me"
|
override var mainUrl = "https://vf-film.me"
|
||||||
override val name = "vf-film.me"
|
override var name = "vf-film.me"
|
||||||
override val lang = "fr"
|
override val lang = "fr"
|
||||||
override val hasQuickSearch = false
|
override val hasQuickSearch = false
|
||||||
override val hasMainPage = false
|
override val hasMainPage = false
|
||||||
|
|
|
@ -7,8 +7,8 @@ import org.jsoup.Jsoup
|
||||||
|
|
||||||
// referer = https://vf-serie.org, USERAGENT ALSO REQUIRED
|
// referer = https://vf-serie.org, USERAGENT ALSO REQUIRED
|
||||||
class VfSerieProvider : MainAPI() {
|
class VfSerieProvider : MainAPI() {
|
||||||
override val mainUrl = "https://vf-serie.org"
|
override var mainUrl = "https://vf-serie.org"
|
||||||
override val name = "vf-serie.org"
|
override var name = "vf-serie.org"
|
||||||
override val lang = "fr"
|
override val lang = "fr"
|
||||||
|
|
||||||
override val hasQuickSearch = false
|
override val hasQuickSearch = false
|
||||||
|
|
|
@ -7,10 +7,10 @@ import com.lagradost.cloudstream3.TvType
|
||||||
*/
|
*/
|
||||||
class VidEmbedProvider : VidstreamProviderTemplate() {
|
class VidEmbedProvider : VidstreamProviderTemplate() {
|
||||||
// mainUrl is good to have as a holder for the url to make future changes easier.
|
// mainUrl is good to have as a holder for the url to make future changes easier.
|
||||||
override val mainUrl = "https://vidembed.cc"
|
override var mainUrl = "https://vidembed.cc"
|
||||||
|
|
||||||
// name is for how the provider will be named which is visible in the UI, no real rules for this.
|
// name is for how the provider will be named which is visible in the UI, no real rules for this.
|
||||||
override val name = "VidEmbed"
|
override var name = "VidEmbed"
|
||||||
|
|
||||||
override val homePageUrlList: List<String> = listOf(
|
override val homePageUrlList: List<String> = listOf(
|
||||||
mainUrl,
|
mainUrl,
|
||||||
|
|
|
@ -10,8 +10,8 @@ import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.loadExtractor
|
import com.lagradost.cloudstream3.utils.loadExtractor
|
||||||
|
|
||||||
class WatchAsianProvider : MainAPI() {
|
class WatchAsianProvider : MainAPI() {
|
||||||
override val mainUrl = "https://watchasian.sh"
|
override var mainUrl = "https://watchasian.sh"
|
||||||
override val name = "WatchAsian"
|
override var name = "WatchAsian"
|
||||||
override val hasQuickSearch = false
|
override val hasQuickSearch = false
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val hasChromecastSupport = false
|
override val hasChromecastSupport = false
|
||||||
|
|
|
@ -6,8 +6,8 @@ import com.lagradost.cloudstream3.utils.extractorApis
|
||||||
|
|
||||||
|
|
||||||
class FrenchStreamProvider : MainAPI() {
|
class FrenchStreamProvider : MainAPI() {
|
||||||
override val mainUrl = "https://french-stream.re"
|
override var mainUrl = "https://french-stream.re"
|
||||||
override val name = "French Stream"
|
override var name = "French Stream"
|
||||||
override val hasQuickSearch = false
|
override val hasQuickSearch = false
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
override val lang = "fr"
|
override val lang = "fr"
|
||||||
|
|
|
@ -26,11 +26,11 @@ import java.net.URL
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class AniListApi(index: Int) : AccountManager(index), SyncAPI {
|
class AniListApi(index: Int) : AccountManager(index), SyncAPI {
|
||||||
override val name = "AniList"
|
override var name = "AniList"
|
||||||
override val key = "6871"
|
override val key = "6871"
|
||||||
override val redirectUrl = "anilistlogin"
|
override val redirectUrl = "anilistlogin"
|
||||||
override val idPrefix = "anilist"
|
override val idPrefix = "anilist"
|
||||||
override val mainUrl = "https://anilist.co"
|
override var mainUrl = "https://anilist.co"
|
||||||
override val icon = R.drawable.ic_anilist_icon
|
override val icon = R.drawable.ic_anilist_icon
|
||||||
|
|
||||||
override fun loginInfo(): OAuth2API.LoginInfo? {
|
override fun loginInfo(): OAuth2API.LoginInfo? {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import com.lagradost.cloudstream3.syncproviders.OAuth2API
|
||||||
//TODO dropbox sync
|
//TODO dropbox sync
|
||||||
class Dropbox : OAuth2API {
|
class Dropbox : OAuth2API {
|
||||||
override val idPrefix = "dropbox"
|
override val idPrefix = "dropbox"
|
||||||
override val name = "Dropbox"
|
override var name = "Dropbox"
|
||||||
override val key = "zlqsamadlwydvb2"
|
override val key = "zlqsamadlwydvb2"
|
||||||
override val redirectUrl = "dropboxlogin"
|
override val redirectUrl = "dropboxlogin"
|
||||||
|
|
||||||
|
|
|
@ -31,11 +31,11 @@ import java.util.*
|
||||||
const val MAL_MAX_SEARCH_LIMIT = 25
|
const val MAL_MAX_SEARCH_LIMIT = 25
|
||||||
|
|
||||||
class MALApi(index: Int) : AccountManager(index), SyncAPI {
|
class MALApi(index: Int) : AccountManager(index), SyncAPI {
|
||||||
override val name = "MAL"
|
override var name = "MAL"
|
||||||
override val key = "1714d6f2f4f7cc19644384f8c4629910"
|
override val key = "1714d6f2f4f7cc19644384f8c4629910"
|
||||||
override val redirectUrl = "mallogin"
|
override val redirectUrl = "mallogin"
|
||||||
override val idPrefix = "mal"
|
override val idPrefix = "mal"
|
||||||
override val mainUrl = "https://myanimelist.net"
|
override var mainUrl = "https://myanimelist.net"
|
||||||
override val icon = R.drawable.mal_logo
|
override val icon = R.drawable.mal_logo
|
||||||
|
|
||||||
override fun logOut() {
|
override fun logOut() {
|
||||||
|
|
|
@ -6,10 +6,10 @@ import com.lagradost.cloudstream3.utils.Qualities
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
|
|
||||||
class NyaaProvider : MainAPI() {
|
class NyaaProvider : MainAPI() {
|
||||||
override val name = "Nyaa"
|
override var name = "Nyaa"
|
||||||
override val hasChromecastSupport = false
|
override val hasChromecastSupport = false
|
||||||
|
|
||||||
override val mainUrl = "https://nyaa.si"
|
override var mainUrl = "https://nyaa.si"
|
||||||
override val supportedTypes = setOf(TvType.Torrent)
|
override val supportedTypes = setOf(TvType.Torrent)
|
||||||
override val vpnStatus = VPNStatus.Torrent
|
override val vpnStatus = VPNStatus.Torrent
|
||||||
override val instantLinkLoading = true
|
override val instantLinkLoading = true
|
||||||
|
|
|
@ -11,11 +11,11 @@ class APIRepository(val api: MainAPI) {
|
||||||
var dubStatusActive = HashSet<DubStatus>()
|
var dubStatusActive = HashSet<DubStatus>()
|
||||||
|
|
||||||
val noneApi = object : MainAPI() {
|
val noneApi = object : MainAPI() {
|
||||||
override val name = "None"
|
override var name = "None"
|
||||||
override val supportedTypes = emptySet<TvType>()
|
override val supportedTypes = emptySet<TvType>()
|
||||||
}
|
}
|
||||||
val randomApi = object : MainAPI() {
|
val randomApi = object : MainAPI() {
|
||||||
override val name = "Random"
|
override var name = "Random"
|
||||||
override val supportedTypes = emptySet<TvType>()
|
override val supportedTypes = emptySet<TvType>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -339,14 +339,21 @@ abstract class AbstractPlayerFragment(
|
||||||
SubtitlesFragment.applyStyleEvent += ::onSubStyleChanged
|
SubtitlesFragment.applyStyleEvent += ::onSubStyleChanged
|
||||||
|
|
||||||
try {
|
try {
|
||||||
context?.let {
|
context?.let { ctx ->
|
||||||
val settingsManager = PreferenceManager.getDefaultSharedPreferences(
|
val settingsManager = PreferenceManager.getDefaultSharedPreferences(
|
||||||
it
|
ctx
|
||||||
)
|
)
|
||||||
val currentPrefSize =
|
|
||||||
settingsManager.getInt(getString(R.string.video_cache_key), 300)
|
|
||||||
|
|
||||||
player.cacheSize = currentPrefSize * 1024L * 1024L
|
val currentPrefCacheSize =
|
||||||
|
settingsManager.getInt(getString(R.string.video_buffer_size_key), 0)
|
||||||
|
val currentPrefDiskSize =
|
||||||
|
settingsManager.getInt(getString(R.string.video_buffer_disk_key), 0)
|
||||||
|
val currentPrefBufferSec =
|
||||||
|
settingsManager.getInt(getString(R.string.video_buffer_length_key), 0)
|
||||||
|
|
||||||
|
player.cacheSize = currentPrefCacheSize * 1024L * 1024L
|
||||||
|
player.simpleCacheSize = currentPrefDiskSize * 1024L * 1024L
|
||||||
|
player.videoBufferMs = currentPrefBufferSec * 1000L
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logError(e)
|
logError(e)
|
||||||
|
|
|
@ -39,8 +39,9 @@ const val TAG = "CS3ExoPlayer"
|
||||||
class CS3IPlayer : IPlayer {
|
class CS3IPlayer : IPlayer {
|
||||||
private var isPlaying = false
|
private var isPlaying = false
|
||||||
private var exoPlayer: ExoPlayer? = null
|
private var exoPlayer: ExoPlayer? = null
|
||||||
var cacheSize = 300L * 1024L * 1024L // 300 mb
|
var cacheSize = 0L
|
||||||
private val simpleCacheSize : Long get() = cacheSize / 2 // idk chosen at random kinda
|
var simpleCacheSize = 0L
|
||||||
|
var videoBufferMs = 0L
|
||||||
|
|
||||||
private val seekActionTime = 30000L
|
private val seekActionTime = 30000L
|
||||||
|
|
||||||
|
@ -423,6 +424,7 @@ class CS3IPlayer : IPlayer {
|
||||||
playBackSpeed: Float,
|
playBackSpeed: Float,
|
||||||
subtitleOffset: Long,
|
subtitleOffset: Long,
|
||||||
cacheSize: Long,
|
cacheSize: Long,
|
||||||
|
videoBufferMs: Long,
|
||||||
playWhenReady: Boolean = true,
|
playWhenReady: Boolean = true,
|
||||||
cacheFactory: CacheDataSource.Factory? = null,
|
cacheFactory: CacheDataSource.Factory? = null,
|
||||||
trackSelector: TrackSelector? = null,
|
trackSelector: TrackSelector? = null,
|
||||||
|
@ -460,10 +462,11 @@ class CS3IPlayer : IPlayer {
|
||||||
)
|
)
|
||||||
.setBufferDurationsMs(
|
.setBufferDurationsMs(
|
||||||
DefaultLoadControl.DEFAULT_MIN_BUFFER_MS,
|
DefaultLoadControl.DEFAULT_MIN_BUFFER_MS,
|
||||||
maxOf(
|
if(videoBufferMs <= 0) {
|
||||||
DefaultLoadControl.DEFAULT_MAX_BUFFER_MS,
|
DefaultLoadControl.DEFAULT_MAX_BUFFER_MS
|
||||||
((cacheSize * 75L) / 32768L).toInt()
|
} else {
|
||||||
), // 500mb = 20min
|
videoBufferMs.toInt()
|
||||||
|
},
|
||||||
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS,
|
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS,
|
||||||
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS
|
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS
|
||||||
).build()
|
).build()
|
||||||
|
@ -574,6 +577,7 @@ class CS3IPlayer : IPlayer {
|
||||||
playbackPosition,
|
playbackPosition,
|
||||||
playBackSpeed,
|
playBackSpeed,
|
||||||
cacheSize = cacheSize,
|
cacheSize = cacheSize,
|
||||||
|
videoBufferMs = videoBufferMs,
|
||||||
playWhenReady = isPlaying, // this keep the current state of the player
|
playWhenReady = isPlaying, // this keep the current state of the player
|
||||||
cacheFactory = cacheFactory,
|
cacheFactory = cacheFactory,
|
||||||
subtitleOffset = currentSubtitleOffset
|
subtitleOffset = currentSubtitleOffset
|
||||||
|
|
|
@ -22,7 +22,6 @@ import com.hippo.unifile.UniFile
|
||||||
import com.lagradost.cloudstream3.APIHolder.apis
|
import com.lagradost.cloudstream3.APIHolder.apis
|
||||||
import com.lagradost.cloudstream3.APIHolder.getApiDubstatusSettings
|
import com.lagradost.cloudstream3.APIHolder.getApiDubstatusSettings
|
||||||
import com.lagradost.cloudstream3.APIHolder.getApiProviderLangSettings
|
import com.lagradost.cloudstream3.APIHolder.getApiProviderLangSettings
|
||||||
import com.lagradost.cloudstream3.APIHolder.restrictedApis
|
|
||||||
import com.lagradost.cloudstream3.AcraApplication
|
import com.lagradost.cloudstream3.AcraApplication
|
||||||
import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey
|
import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey
|
||||||
import com.lagradost.cloudstream3.CommonActivity.setLocale
|
import com.lagradost.cloudstream3.CommonActivity.setLocale
|
||||||
|
@ -199,32 +198,111 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
||||||
private fun getPref(id: Int): Preference? {
|
private fun getPref(id: Int): Preference? {
|
||||||
return try {
|
return try {
|
||||||
findPreference(getString(id))
|
findPreference(getString(id))
|
||||||
} catch (e : Exception) {
|
} catch (e: Exception) {
|
||||||
logError(e)
|
logError(e)
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getFolderSize(dir: File): Long {
|
||||||
|
var size: Long = 0
|
||||||
|
dir.listFiles()?.let {
|
||||||
|
for (file in it) {
|
||||||
|
size += if (file.isFile) {
|
||||||
|
// System.out.println(file.getName() + " " + file.length());
|
||||||
|
file.length()
|
||||||
|
} else getFolderSize(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return size
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
hideKeyboard()
|
hideKeyboard()
|
||||||
setPreferencesFromResource(R.xml.settings, rootKey)
|
setPreferencesFromResource(R.xml.settings, rootKey)
|
||||||
val settingsManager = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
val settingsManager = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||||
|
|
||||||
getPref(R.string.video_cache_key)?.setOnPreferenceClickListener {
|
getPref(R.string.video_buffer_length_key)?.setOnPreferenceClickListener {
|
||||||
val prefNames = resources.getStringArray(R.array.video_cache_size_names)
|
val prefNames = resources.getStringArray(R.array.video_buffer_length_names)
|
||||||
val prefValues = resources.getIntArray(R.array.video_cache_size_values)
|
val prefValues = resources.getIntArray(R.array.video_buffer_length_values)
|
||||||
|
|
||||||
val currentPrefSize =
|
val currentPrefSize =
|
||||||
settingsManager.getInt(getString(R.string.video_cache_key), 300)
|
settingsManager.getInt(getString(R.string.video_buffer_length_key), 0)
|
||||||
|
|
||||||
activity?.showBottomDialog(
|
activity?.showDialog(
|
||||||
prefNames.toList(),
|
prefNames.toList(),
|
||||||
prefValues.indexOf(currentPrefSize),
|
prefValues.indexOf(currentPrefSize),
|
||||||
getString(R.string.video_cache_settings),
|
getString(R.string.video_buffer_length_settings),
|
||||||
true,
|
true,
|
||||||
{}) {
|
{}) {
|
||||||
settingsManager.edit()
|
settingsManager.edit()
|
||||||
.putInt(getString(R.string.video_cache_key), prefValues[it])
|
.putInt(getString(R.string.video_buffer_length_key), prefValues[it])
|
||||||
|
.apply()
|
||||||
|
}
|
||||||
|
return@setOnPreferenceClickListener true
|
||||||
|
}
|
||||||
|
|
||||||
|
getPref(R.string.video_buffer_size_key)?.setOnPreferenceClickListener {
|
||||||
|
val prefNames = resources.getStringArray(R.array.video_buffer_size_names)
|
||||||
|
val prefValues = resources.getIntArray(R.array.video_buffer_size_values)
|
||||||
|
|
||||||
|
val currentPrefSize =
|
||||||
|
settingsManager.getInt(getString(R.string.video_buffer_size_key), 0)
|
||||||
|
|
||||||
|
activity?.showDialog(
|
||||||
|
prefNames.toList(),
|
||||||
|
prefValues.indexOf(currentPrefSize),
|
||||||
|
getString(R.string.video_buffer_size_settings),
|
||||||
|
true,
|
||||||
|
{}) {
|
||||||
|
settingsManager.edit()
|
||||||
|
.putInt(getString(R.string.video_buffer_size_key), prefValues[it])
|
||||||
|
.apply()
|
||||||
|
}
|
||||||
|
return@setOnPreferenceClickListener true
|
||||||
|
}
|
||||||
|
|
||||||
|
getPref(R.string.video_buffer_clear_key)?.let { pref ->
|
||||||
|
val cacheDir = context?.cacheDir ?: return@let
|
||||||
|
|
||||||
|
fun updateSummery() {
|
||||||
|
try {
|
||||||
|
pref.summary =
|
||||||
|
getString(R.string.mb_format).format(getFolderSize(cacheDir) / (1024L * 1024L))
|
||||||
|
} catch (e: Exception) {
|
||||||
|
logError(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSummery()
|
||||||
|
|
||||||
|
pref.setOnPreferenceClickListener {
|
||||||
|
try {
|
||||||
|
cacheDir.deleteRecursively()
|
||||||
|
updateSummery()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
logError(e)
|
||||||
|
}
|
||||||
|
return@setOnPreferenceClickListener true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getPref(R.string.video_buffer_disk_key)?.setOnPreferenceClickListener {
|
||||||
|
val prefNames = resources.getStringArray(R.array.video_buffer_size_names)
|
||||||
|
val prefValues = resources.getIntArray(R.array.video_buffer_size_values)
|
||||||
|
|
||||||
|
val currentPrefSize =
|
||||||
|
settingsManager.getInt(getString(R.string.video_buffer_disk_key), 0)
|
||||||
|
|
||||||
|
activity?.showDialog(
|
||||||
|
prefNames.toList(),
|
||||||
|
prefValues.indexOf(currentPrefSize),
|
||||||
|
getString(R.string.video_buffer_disk_settings),
|
||||||
|
true,
|
||||||
|
{}) {
|
||||||
|
settingsManager.edit()
|
||||||
|
.putInt(getString(R.string.video_buffer_disk_key), prefValues[it])
|
||||||
.apply()
|
.apply()
|
||||||
}
|
}
|
||||||
return@setOnPreferenceClickListener true
|
return@setOnPreferenceClickListener true
|
||||||
|
@ -301,9 +379,6 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
||||||
for (api in apis) {
|
for (api in apis) {
|
||||||
allLangs.add(api.lang)
|
allLangs.add(api.lang)
|
||||||
}
|
}
|
||||||
for (api in restrictedApis) {
|
|
||||||
allLangs.add(api.lang)
|
|
||||||
}
|
|
||||||
|
|
||||||
val currentList = ArrayList<Int>()
|
val currentList = ArrayList<Int>()
|
||||||
for (i in current) {
|
for (i in current) {
|
||||||
|
|
|
@ -323,18 +323,25 @@ class SubtitlesFragment : Fragment() {
|
||||||
val fontSizes = listOf(
|
val fontSizes = listOf(
|
||||||
Pair(null, textView.context.getString(R.string.normal)),
|
Pair(null, textView.context.getString(R.string.normal)),
|
||||||
Pair(6f, "6$suffix"),
|
Pair(6f, "6$suffix"),
|
||||||
|
Pair(7f, "7$suffix"),
|
||||||
Pair(8f, "8$suffix"),
|
Pair(8f, "8$suffix"),
|
||||||
Pair(9f, "9$suffix"),
|
Pair(9f, "9$suffix"),
|
||||||
Pair(10f, "10$suffix"),
|
Pair(10f, "10$suffix"),
|
||||||
Pair(11f, "11$suffix"),
|
Pair(11f, "11$suffix"),
|
||||||
Pair(12f, "12$suffix"),
|
Pair(12f, "12$suffix"),
|
||||||
|
Pair(13f, "13$suffix"),
|
||||||
Pair(14f, "14$suffix"),
|
Pair(14f, "14$suffix"),
|
||||||
|
Pair(15f, "15$suffix"),
|
||||||
Pair(16f, "16$suffix"),
|
Pair(16f, "16$suffix"),
|
||||||
|
Pair(17f, "17$suffix"),
|
||||||
Pair(18f, "18$suffix"),
|
Pair(18f, "18$suffix"),
|
||||||
Pair(19f, "19$suffix"),
|
Pair(19f, "19$suffix"),
|
||||||
|
Pair(20f, "20$suffix"),
|
||||||
Pair(21f, "21$suffix"),
|
Pair(21f, "21$suffix"),
|
||||||
|
Pair(22f, "22$suffix"),
|
||||||
Pair(23f, "23$suffix"),
|
Pair(23f, "23$suffix"),
|
||||||
Pair(24f, "24$suffix"),
|
Pair(24f, "24$suffix"),
|
||||||
|
Pair(25f, "25$suffix"),
|
||||||
Pair(26f, "26$suffix"),
|
Pair(26f, "26$suffix"),
|
||||||
Pair(28f, "28$suffix"),
|
Pair(28f, "28$suffix"),
|
||||||
Pair(30f, "30$suffix"),
|
Pair(30f, "30$suffix"),
|
||||||
|
|
|
@ -112,6 +112,7 @@ val extractorApis: Array<ExtractorApi> = arrayOf(
|
||||||
StreamSB7(),
|
StreamSB7(),
|
||||||
StreamSB8(),
|
StreamSB8(),
|
||||||
StreamSB9(),
|
StreamSB9(),
|
||||||
|
StreamSB10(),
|
||||||
// Streamhub(), cause Streamhub2() works
|
// Streamhub(), cause Streamhub2() works
|
||||||
Streamhub2(),
|
Streamhub2(),
|
||||||
|
|
||||||
|
|
|
@ -232,7 +232,7 @@
|
||||||
<string name="dont_show_again">لا تظهر مرة أخرى</string>
|
<string name="dont_show_again">لا تظهر مرة أخرى</string>
|
||||||
<string name="update">تحديث</string>
|
<string name="update">تحديث</string>
|
||||||
<string name="watch_quality_pref">جودة المشاهدة المفضلة</string>
|
<string name="watch_quality_pref">جودة المشاهدة المفضلة</string>
|
||||||
<string name="video_cache_settings">حجم ذاكرة التخزين المؤقت للفيديو</string>
|
<string name="video_buffer_size_settings">حجم ذاكرة التخزين المؤقت للفيديو</string>
|
||||||
<string name="dns_pref">DNS فوق HTTPS</string>
|
<string name="dns_pref">DNS فوق HTTPS</string>
|
||||||
<string name="dns_pref_summary">مفيد لتجاوز كتل مزود خدمة الإنترنت</string>
|
<string name="dns_pref_summary">مفيد لتجاوز كتل مزود خدمة الإنترنت</string>
|
||||||
|
|
||||||
|
|
|
@ -186,7 +186,7 @@
|
||||||
\n%s -> %s</string>
|
\n%s -> %s</string>
|
||||||
<string name="filler" formatted="true">Épisode spécial</string>
|
<string name="filler" formatted="true">Épisode spécial</string>
|
||||||
<string name="watch_quality_pref">Qualité de visionnage préférée</string>
|
<string name="watch_quality_pref">Qualité de visionnage préférée</string>
|
||||||
<string name="video_cache_settings">Taille de la mémoire cache</string>
|
<string name="video_buffer_size_settings">Taille de la mémoire cache</string>
|
||||||
<string name="resize_fill">Étendre</string>
|
<string name="resize_fill">Étendre</string>
|
||||||
<string name="legal_notice">Non-responsabilité</string>
|
<string name="legal_notice">Non-responsabilité</string>
|
||||||
<string name="primary_color_settings">Couleur principale</string>
|
<string name="primary_color_settings">Couleur principale</string>
|
||||||
|
|
|
@ -269,7 +269,7 @@
|
||||||
<string name="dont_show_again">Non mostrare di nuovo</string>
|
<string name="dont_show_again">Non mostrare di nuovo</string>
|
||||||
<string name="update">Aggiorna</string>
|
<string name="update">Aggiorna</string>
|
||||||
<string name="watch_quality_pref">Risoluzione preferita</string>
|
<string name="watch_quality_pref">Risoluzione preferita</string>
|
||||||
<string name="video_cache_settings">Dimensione cache video</string>
|
<string name="video_buffer_size_settings">Dimensione cache video</string>
|
||||||
<string name="dns_pref">DNS over HTTPS</string>
|
<string name="dns_pref">DNS over HTTPS</string>
|
||||||
<string name="dns_pref_summary">Utile per bypassare i blocchi ISP</string>
|
<string name="dns_pref_summary">Utile per bypassare i blocchi ISP</string>
|
||||||
|
|
||||||
|
|
|
@ -232,7 +232,7 @@
|
||||||
<string name="dont_show_again">Không hiển thị lại</string>
|
<string name="dont_show_again">Không hiển thị lại</string>
|
||||||
<string name="update">Cập nhật</string>
|
<string name="update">Cập nhật</string>
|
||||||
<string name="watch_quality_pref">Tự động chọn chất lượng phim</string>
|
<string name="watch_quality_pref">Tự động chọn chất lượng phim</string>
|
||||||
<string name="video_cache_settings">Kích thước video cache</string>
|
<string name="video_buffer_size_settings">Kích thước video cache</string>
|
||||||
<string name="dns_pref_summary">Rất hữu ích để bỏ chặn ISP</string>
|
<string name="dns_pref_summary">Rất hữu ích để bỏ chặn ISP</string>
|
||||||
|
|
||||||
<string name="download_path_pref">Đường dẫn tải xuống</string>
|
<string name="download_path_pref">Đường dẫn tải xuống</string>
|
||||||
|
|
|
@ -56,20 +56,88 @@
|
||||||
<item>1</item>
|
<item>1</item>
|
||||||
<item>2</item>
|
<item>2</item>
|
||||||
</array>
|
</array>
|
||||||
<array name="video_cache_size_names">
|
|
||||||
<item>@string/none</item>
|
<array name="video_buffer_length_names">
|
||||||
|
<item>@string/automatic</item>
|
||||||
|
<item>1min</item>
|
||||||
|
<item>1min 30s</item>
|
||||||
|
<item>2min</item>
|
||||||
|
<item>2min 30s</item>
|
||||||
|
<item>3min</item>
|
||||||
|
<item>3min 30s</item>
|
||||||
|
<item>4min</item>
|
||||||
|
<item>5min</item>
|
||||||
|
<item>6min</item>
|
||||||
|
<item>7min</item>
|
||||||
|
<item>8min</item>
|
||||||
|
<item>9min</item>
|
||||||
|
<item>10min</item>
|
||||||
|
<item>15min</item>
|
||||||
|
<item>20min</item>
|
||||||
|
<item>30min</item>
|
||||||
|
</array>
|
||||||
|
|
||||||
|
<array name="video_buffer_length_values">
|
||||||
|
<item>0</item>
|
||||||
|
<item>60</item>
|
||||||
|
<item>90</item>
|
||||||
|
<item>120</item>
|
||||||
|
<item>150</item>
|
||||||
|
<item>180</item>
|
||||||
|
<item>210</item>
|
||||||
|
<item>240</item>
|
||||||
|
<item>300</item>
|
||||||
|
<item>360</item>
|
||||||
|
<item>420</item>
|
||||||
|
<item>480</item>
|
||||||
|
<item>540</item>
|
||||||
|
<item>600</item>
|
||||||
|
<item>900</item>
|
||||||
|
<item>1200</item>
|
||||||
|
<item>1800</item>
|
||||||
|
</array>
|
||||||
|
|
||||||
|
<array name="video_buffer_size_names">
|
||||||
|
<item>@string/automatic</item>
|
||||||
|
<item>10MB</item>
|
||||||
|
<item>20MB</item>
|
||||||
|
<item>30MB</item>
|
||||||
|
<item>40MB</item>
|
||||||
|
<item>50MB</item>
|
||||||
|
<item>60MB</item>
|
||||||
|
<item>70MB</item>
|
||||||
|
<item>80MB</item>
|
||||||
|
<item>90MB</item>
|
||||||
<item>100MB</item>
|
<item>100MB</item>
|
||||||
|
<item>150MB</item>
|
||||||
<item>200MB</item>
|
<item>200MB</item>
|
||||||
|
<item>250MB</item>
|
||||||
<item>300MB</item>
|
<item>300MB</item>
|
||||||
|
<item>350MB</item>
|
||||||
<item>400MB</item>
|
<item>400MB</item>
|
||||||
|
<item>450MB</item>
|
||||||
<item>500MB</item>
|
<item>500MB</item>
|
||||||
</array>
|
</array>
|
||||||
<array name="video_cache_size_values">
|
|
||||||
|
<array name="video_buffer_size_values">
|
||||||
<item>0</item>
|
<item>0</item>
|
||||||
|
<item>10</item>
|
||||||
|
<item>20</item>
|
||||||
|
<item>30</item>
|
||||||
|
<item>40</item>
|
||||||
|
<item>50</item>
|
||||||
|
<item>60</item>
|
||||||
|
<item>70</item>
|
||||||
|
<item>80</item>
|
||||||
|
<item>90</item>
|
||||||
<item>100</item>
|
<item>100</item>
|
||||||
|
<item>150</item>
|
||||||
<item>200</item>
|
<item>200</item>
|
||||||
|
<item>250</item>
|
||||||
<item>300</item>
|
<item>300</item>
|
||||||
|
<item>350</item>
|
||||||
<item>400</item>
|
<item>400</item>
|
||||||
|
<item>450</item>
|
||||||
<item>500</item>
|
<item>500</item>
|
||||||
</array>
|
</array>
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,10 @@
|
||||||
<string name="subtitle_settings_key" translatable="false">subtitle_settings_key</string>
|
<string name="subtitle_settings_key" translatable="false">subtitle_settings_key</string>
|
||||||
<string name="subtitle_settings_chromecast_key" translatable="false">subtitle_settings_chromecast_key</string>
|
<string name="subtitle_settings_chromecast_key" translatable="false">subtitle_settings_chromecast_key</string>
|
||||||
<string name="quality_pref_key" translatable="false">quality_pref_key</string>
|
<string name="quality_pref_key" translatable="false">quality_pref_key</string>
|
||||||
<string name="video_cache_key" translatable="false">video_cache_key</string>
|
<string name="video_buffer_size_key" translatable="false">video_buffer_size_key</string>
|
||||||
|
<string name="video_buffer_length_key" translatable="false">video_buffer_length_key</string>
|
||||||
|
<string name="video_buffer_clear_key" translatable="false">video_buffer_clear_key</string>
|
||||||
|
<string name="video_buffer_disk_key" translatable="false">video_buffer_disk_key</string>
|
||||||
<string name="prerelease_commit_hash" translatable="false">unknown_prerelease</string>
|
<string name="prerelease_commit_hash" translatable="false">unknown_prerelease</string>
|
||||||
<string name="use_system_brightness_key" translatable="false">use_system_brightness_key</string>
|
<string name="use_system_brightness_key" translatable="false">use_system_brightness_key</string>
|
||||||
<string name="swipe_enabled_key" translatable="false">swipe_enabled_key</string>
|
<string name="swipe_enabled_key" translatable="false">swipe_enabled_key</string>
|
||||||
|
@ -32,6 +35,7 @@
|
||||||
<string name="app_layout_key" translatable="false">app_layout_key</string>
|
<string name="app_layout_key" translatable="false">app_layout_key</string>
|
||||||
<string name="primary_color_key" translatable="false">primary_color_key</string>
|
<string name="primary_color_key" translatable="false">primary_color_key</string>
|
||||||
<string name="restore_key" translatable="false">restore_key</string>
|
<string name="restore_key" translatable="false">restore_key</string>
|
||||||
|
<string name="killswitch_key" translatable="false">killswitch_key</string>
|
||||||
<string name="backup_key" translatable="false">backup_key</string>
|
<string name="backup_key" translatable="false">backup_key</string>
|
||||||
<string name="prefer_media_type_key" translatable="false">prefer_media_type_key</string>
|
<string name="prefer_media_type_key" translatable="false">prefer_media_type_key</string>
|
||||||
<string name="app_theme_key" translatable="false">app_theme_key</string>
|
<string name="app_theme_key" translatable="false">app_theme_key</string>
|
||||||
|
@ -41,6 +45,7 @@
|
||||||
<string name="extra_info_format" translatable="false" formatted="true">%d %s | %sMB</string>
|
<string name="extra_info_format" translatable="false" formatted="true">%d %s | %sMB</string>
|
||||||
<string name="storage_size_format" translatable="false" formatted="true">%s • %sGB</string>
|
<string name="storage_size_format" translatable="false" formatted="true">%s • %sGB</string>
|
||||||
<string name="download_size_format" translatable="false" formatted="true">%sMB / %sMB</string>
|
<string name="download_size_format" translatable="false" formatted="true">%sMB / %sMB</string>
|
||||||
|
<string name="mb_format" translatable="false" formatted="true">%dMB</string>
|
||||||
<string name="episode_name_format" translatable="false" formatted="true">%s %s</string>
|
<string name="episode_name_format" translatable="false" formatted="true">%s %s</string>
|
||||||
<string name="ffw_text_format" translatable="false" formatted="true">+%d</string>
|
<string name="ffw_text_format" translatable="false" formatted="true">+%d</string>
|
||||||
<string name="rew_text_format" translatable="false" formatted="true">-%d</string>
|
<string name="rew_text_format" translatable="false" formatted="true">-%d</string>
|
||||||
|
@ -198,6 +203,9 @@
|
||||||
</string>
|
</string>
|
||||||
|
|
||||||
<string name="restore_settings">Restore data from backup</string>
|
<string name="restore_settings">Restore data from backup</string>
|
||||||
|
<string name="killswitch_settings">Download latest metadata from github</string>
|
||||||
|
<string name="killswitch_settings_des">If you want access to all providers (even broken ones) turn this off</string>
|
||||||
|
|
||||||
<string name="backup_settings">Backup data</string>
|
<string name="backup_settings">Backup data</string>
|
||||||
<string name="restore_success">Loaded backup file</string>
|
<string name="restore_success">Loaded backup file</string>
|
||||||
<string name="restore_failed_format" formatted="true">Failed to restore data from file %s</string>
|
<string name="restore_failed_format" formatted="true">Failed to restore data from file %s</string>
|
||||||
|
@ -315,7 +323,14 @@
|
||||||
<string name="dont_show_again">Don\'t show again</string>
|
<string name="dont_show_again">Don\'t show again</string>
|
||||||
<string name="update">Update</string>
|
<string name="update">Update</string>
|
||||||
<string name="watch_quality_pref">Preferred watch quality</string>
|
<string name="watch_quality_pref">Preferred watch quality</string>
|
||||||
<string name="video_cache_settings">Video cache size</string>
|
<string name="video_buffer_size_settings">Video buffer size</string>
|
||||||
|
<string name="video_buffer_length_settings">Video buffer length</string>
|
||||||
|
<string name="video_buffer_disk_settings">Video cache on disk</string>
|
||||||
|
<string name="video_buffer_clear_settings">Clear video and image cache</string>
|
||||||
|
|
||||||
|
<string name="video_ram_description">May cause problems on systems with low ram such as Android TV devices or old phones if you set it too high</string>
|
||||||
|
<string name="video_disk_description">May cause problems on systems with low storage space such as Android TV devices if you set it too high</string>
|
||||||
|
|
||||||
<string name="dns_pref">DNS over HTTPS</string>
|
<string name="dns_pref">DNS over HTTPS</string>
|
||||||
<string name="dns_pref_summary">Useful for bypassing ISP blocks</string>
|
<string name="dns_pref_summary">Useful for bypassing ISP blocks</string>
|
||||||
|
|
||||||
|
|
|
@ -20,10 +20,7 @@
|
||||||
android:key="@string/quality_pref_key"
|
android:key="@string/quality_pref_key"
|
||||||
android:title="@string/watch_quality_pref"
|
android:title="@string/watch_quality_pref"
|
||||||
android:icon="@drawable/ic_baseline_hd_24" />
|
android:icon="@drawable/ic_baseline_hd_24" />
|
||||||
<Preference
|
|
||||||
android:key="@string/video_cache_key"
|
|
||||||
android:title="@string/video_cache_settings"
|
|
||||||
android:icon="@drawable/ic_baseline_storage_24" />
|
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:icon="@drawable/ic_baseline_picture_in_picture_alt_24"
|
android:icon="@drawable/ic_baseline_picture_in_picture_alt_24"
|
||||||
app:key="@string/pip_enabled_key"
|
app:key="@string/pip_enabled_key"
|
||||||
|
@ -66,6 +63,28 @@
|
||||||
android:title="@string/double_tap_to_pause_settings"
|
android:title="@string/double_tap_to_pause_settings"
|
||||||
android:summary="@string/double_tap_to_pause_settings_des"
|
android:summary="@string/double_tap_to_pause_settings_des"
|
||||||
app:defaultValue="false" />
|
app:defaultValue="false" />
|
||||||
|
<Preference
|
||||||
|
android:key="@string/video_buffer_disk_key"
|
||||||
|
android:title="@string/video_buffer_disk_settings"
|
||||||
|
android:summary="@string/video_disk_description"
|
||||||
|
android:icon="@drawable/ic_baseline_storage_24" />
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="@string/video_buffer_size_key"
|
||||||
|
android:title="@string/video_buffer_size_settings"
|
||||||
|
android:summary="@string/video_ram_description"
|
||||||
|
android:icon="@drawable/ic_baseline_storage_24" />
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="@string/video_buffer_length_key"
|
||||||
|
android:title="@string/video_buffer_length_settings"
|
||||||
|
android:summary="@string/video_ram_description"
|
||||||
|
android:icon="@drawable/ic_baseline_storage_24" />
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="@string/video_buffer_clear_key"
|
||||||
|
android:title="@string/video_buffer_clear_settings"
|
||||||
|
android:icon="@drawable/ic_baseline_delete_outline_24" />
|
||||||
<!--
|
<!--
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:icon="@drawable/ic_baseline_brightness_7_24"
|
android:icon="@drawable/ic_baseline_brightness_7_24"
|
||||||
|
@ -179,6 +198,13 @@
|
||||||
android:key="@string/restore_key"
|
android:key="@string/restore_key"
|
||||||
android:title="@string/restore_settings" />
|
android:title="@string/restore_settings" />
|
||||||
|
|
||||||
|
<SwitchPreference
|
||||||
|
android:icon="@drawable/netflix_download"
|
||||||
|
android:key="@string/killswitch_key"
|
||||||
|
android:defaultValue="true"
|
||||||
|
android:summary="@string/killswitch_settings_des"
|
||||||
|
android:title="@string/killswitch_settings" />
|
||||||
|
|
||||||
<Preference
|
<Preference
|
||||||
android:key="@string/mal_key"
|
android:key="@string/mal_key"
|
||||||
android:icon="@drawable/mal_logo" />
|
android:icon="@drawable/mal_logo" />
|
||||||
|
|
282
providers.json
Normal file
282
providers.json
Normal file
|
@ -0,0 +1,282 @@
|
||||||
|
{
|
||||||
|
"AkwamProvider": {
|
||||||
|
"name": "Akwam",
|
||||||
|
"url": "https://akwam.to",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"AllAnimeProvider": {
|
||||||
|
"name": "AllAnime",
|
||||||
|
"url": "https://allanime.site",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"AllMoviesForYouProvider": {
|
||||||
|
"name": "AllMoviesForYou",
|
||||||
|
"url": "https://allmoviesforyou.net",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"AnimeFlickProvider": {
|
||||||
|
"name": "AnimeFlick",
|
||||||
|
"url": "https://animeflick.net",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"AnimePaheProvider": {
|
||||||
|
"name": "AnimePahe",
|
||||||
|
"url": "https://animepahe.com",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"AnimeWorldProvider": {
|
||||||
|
"name": "AnimeWorld",
|
||||||
|
"url": "https://www.animeworld.tv",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"AnimeflvnetProvider": {
|
||||||
|
"name": "Animeflv.net",
|
||||||
|
"url": "https://www3.animeflv.net",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"AnimekisaProvider": {
|
||||||
|
"name": "Animekisa",
|
||||||
|
"url": "https://animekisa.in",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"AsianLoadProvider": {
|
||||||
|
"name": "AsianLoad",
|
||||||
|
"url": "https://asianembed.io",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"AsiaFlixProvider": {
|
||||||
|
"name": "AsiaFlix",
|
||||||
|
"url": "https://asiaflix.app",
|
||||||
|
"status": 3
|
||||||
|
},
|
||||||
|
"BflixProvider": {
|
||||||
|
"name": "Bflix",
|
||||||
|
"url": "https://bflix.ru",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"FmoviesToProvider": {
|
||||||
|
"name": "Fmovies.to",
|
||||||
|
"url": "https://fmovies.to",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"SflixProProvider": {
|
||||||
|
"name": "Sflix.pro",
|
||||||
|
"url": "https://sflix.pro",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"CinecalidadProvider": {
|
||||||
|
"name": "Cinecalidad",
|
||||||
|
"url": "https://cinecalidad.lol",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"CrossTmdbProvider": {
|
||||||
|
"name": "MultiMovie",
|
||||||
|
"url": "NONE",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"CuevanaProvider": {
|
||||||
|
"name": "Cuevana",
|
||||||
|
"url": "https://cuevana3.me",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"DoramasYTProvider": {
|
||||||
|
"name": "DoramasYT",
|
||||||
|
"url": "https://doramasyt.com",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"DramaSeeProvider": {
|
||||||
|
"name": "DramaSee",
|
||||||
|
"url": "https://dramasee.net",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"DubbedAnimeProvider": {
|
||||||
|
"name": "DubbedAnime",
|
||||||
|
"url": "https://bestdubbedanime.com",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"EgyBestProvider": {
|
||||||
|
"name": "EgyBest",
|
||||||
|
"url": "https://egy.best",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"EntrepeliculasyseriesProvider": {
|
||||||
|
"name": "EntrePeliculasySeries",
|
||||||
|
"url": "https://entrepeliculasyseries.nu",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"FilmanProvider": {
|
||||||
|
"name": "filman.cc",
|
||||||
|
"url": "https://filman.cc",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"FrenchStreamProvider": {
|
||||||
|
"name": "French Stream",
|
||||||
|
"url": "https://french-stream.re",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"GogoanimeProvider": {
|
||||||
|
"name": "GogoAnime",
|
||||||
|
"url": "https://gogoanime.film",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"KawaiifuProvider": {
|
||||||
|
"name": "Kawaiifu",
|
||||||
|
"url": "https://kawaiifu.com",
|
||||||
|
"status": 0
|
||||||
|
},
|
||||||
|
"HDMProvider": {
|
||||||
|
"name": "HD Movies",
|
||||||
|
"url": "https://hdm.to",
|
||||||
|
"status": 0
|
||||||
|
},
|
||||||
|
"IHaveNoTvProvider": {
|
||||||
|
"name": "I Have No TV",
|
||||||
|
"url": "https://ihavenotv.com",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"KdramaHoodProvider": {
|
||||||
|
"name": "KDramaHood",
|
||||||
|
"url": "https://kdramahood.com",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"LookMovieProvider": {
|
||||||
|
"name": "LookMovie",
|
||||||
|
"url": "https://lookmovie.io",
|
||||||
|
"status": 0
|
||||||
|
},
|
||||||
|
"MeloMovieProvider": {
|
||||||
|
"name": "MeloMovie",
|
||||||
|
"url": "https://melomovie.com",
|
||||||
|
"status": 0
|
||||||
|
},
|
||||||
|
"MonoschinosProvider": {
|
||||||
|
"name": "Monoschinos",
|
||||||
|
"url": "https://monoschinos2.com",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"MyCimaProvider": {
|
||||||
|
"name": "MyCima",
|
||||||
|
"url": "https://mycima.tv",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"NineAnimeProvider": {
|
||||||
|
"name": "9Anime",
|
||||||
|
"url": "https://9anime.center",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"PeliSmartProvider": {
|
||||||
|
"name": "PeliSmart",
|
||||||
|
"url": "https://pelismart.com",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"PelisflixProvider": {
|
||||||
|
"name": "Pelisflix",
|
||||||
|
"url": "https://pelisflix.li",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"PelisplusHDProvider": {
|
||||||
|
"name": "PelisplusHD",
|
||||||
|
"url": "https://pelisplushd.net",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"PelisplusProvider": {
|
||||||
|
"name": "Pelisplus",
|
||||||
|
"url": "https://pelisplus.icu",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"PinoyHDXyzProvider": {
|
||||||
|
"name": "Pinoy-HD",
|
||||||
|
"url": "https://www.pinoy-hd.xyz",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"PinoyMoviePediaProvider": {
|
||||||
|
"name": "Pinoy Moviepedia",
|
||||||
|
"url": "https://pinoymoviepedia.ru",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"PinoyMoviesEsProvider": {
|
||||||
|
"name": "Pinoy Movies",
|
||||||
|
"url": "https://pinoymovies.es",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"SflixProvider": {
|
||||||
|
"name": "Sflix.to",
|
||||||
|
"url": "https://sflix.to",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"DopeboxProvider": {
|
||||||
|
"name": "Dopebox",
|
||||||
|
"url": "https://dopebox.to",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"SolarmovieProvider": {
|
||||||
|
"name": "Solarmovie",
|
||||||
|
"url": "https://solarmovie.pe",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"SeriesflixProvider": {
|
||||||
|
"name": "Seriesflix",
|
||||||
|
"url": "https://seriesflix.video",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"SoaptwoDayProvider": {
|
||||||
|
"name": "Soap2Day",
|
||||||
|
"url": "https://secretlink.xyz",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"TenshiProvider": {
|
||||||
|
"name": "Tenshi.moe",
|
||||||
|
"url": "https://tenshi.moe",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"TrailersTwoProvider": {
|
||||||
|
"name": "Trailers.to",
|
||||||
|
"url": "https://trailers.to",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"TwoEmbedProvider": {
|
||||||
|
"name": "2Embed",
|
||||||
|
"url": "https://www.2embed.ru",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"VMoveeProvider": {
|
||||||
|
"name": "VMovee",
|
||||||
|
"url": "https://www.vmovee.watch",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"VfFilmProvider": {
|
||||||
|
"name": "vf-film.me",
|
||||||
|
"url": "https://vf-film.me",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"VfSerieProvider": {
|
||||||
|
"name": "vf-serie.org",
|
||||||
|
"url": "https://vf-serie.org",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"VidEmbedProvider": {
|
||||||
|
"name": "VidEmbed",
|
||||||
|
"url": "https://vidembed.cc",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"WatchAsianProvider": {
|
||||||
|
"name": "WatchAsian",
|
||||||
|
"url": "https://watchasian.sh",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"WatchCartoonOnlineProvider": {
|
||||||
|
"name": "WatchCartoonOnline",
|
||||||
|
"url": "https://www.wcostream.com",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"WcoProvider": {
|
||||||
|
"name": "WCO Stream",
|
||||||
|
"url": "https://wcostream.cc",
|
||||||
|
"status": 1
|
||||||
|
},
|
||||||
|
"ZoroProvider": {
|
||||||
|
"name": "Zoro",
|
||||||
|
"url": "https://zoro.to",
|
||||||
|
"status": 1
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue