mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
Merge branch 'master' into flow
This commit is contained in:
commit
aad0fd3e56
14 changed files with 172 additions and 79 deletions
|
@ -150,7 +150,7 @@ repositories {
|
|||
dependencies {
|
||||
// Testing
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
testImplementation("org.json:json:20230618")
|
||||
testImplementation("org.json:json:20231013")
|
||||
androidTestImplementation("androidx.test:core")
|
||||
implementation("androidx.test.ext:junit-ktx:1.1.5")
|
||||
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
||||
|
@ -172,13 +172,13 @@ dependencies {
|
|||
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
|
||||
|
||||
// Glide Module
|
||||
ksp("com.github.bumptech.glide:ksp:4.15.1")
|
||||
implementation("com.github.bumptech.glide:glide:4.15.1")
|
||||
implementation("com.github.bumptech.glide:okhttp3-integration:4.15.1")
|
||||
ksp("com.github.bumptech.glide:ksp:4.16.0")
|
||||
implementation("com.github.bumptech.glide:glide:4.16.0")
|
||||
implementation("com.github.bumptech.glide:okhttp3-integration:4.16.0")
|
||||
|
||||
// For KSP -> Official Annotation Processors are Not Yet Supported for KSP
|
||||
ksp("dev.zacsweers.autoservice:auto-service-ksp:1.1.0")
|
||||
implementation("com.google.guava:guava:32.1.2-android")
|
||||
implementation("com.google.guava:guava:32.1.3-android")
|
||||
implementation("dev.zacsweers.autoservice:auto-service-ksp:1.1.0")
|
||||
|
||||
// Media 3 (ExoPlayer)
|
||||
|
@ -210,15 +210,15 @@ dependencies {
|
|||
implementation("com.github.discord:OverlappingPanels:0.1.5") // Gestures
|
||||
implementation("com.github.rubensousa:previewseekbar-media3:1.1.1.0") // SeekBar Preview
|
||||
|
||||
// Extensionns & Other Libs
|
||||
implementation("org.mozilla:rhino:1.7.13") /* run JS
|
||||
^ Don't Bump RhinoJS to 1.7.14, since in 1.7.14 Rhino Uses the `SourceVersion` Class, Which is NOT
|
||||
Available on Android (even with Desugaring) & `NoClassDefFoundError` Occurs. */
|
||||
// Extensions & Other Libs
|
||||
implementation("org.mozilla:rhino:1.7.13") /* run JavaScript
|
||||
^ Don't Bump RhinoJS to 1.7.14,`NoClassDefFoundError` Occurs and Trailers won't play (even with Desugaring)
|
||||
NewPipeExtractor Issue */
|
||||
implementation("me.xdrop:fuzzywuzzy:1.4.0") // Library/Ext Searching with Levenshtein Distance
|
||||
implementation("com.github.LagradOst:SafeFile:0.0.5") // To Prevent the URI File Fu*kery
|
||||
implementation("com.github.LagradOst:SafeFile:0.0.6") // To Prevent the URI File Fu*kery
|
||||
implementation("org.conscrypt:conscrypt-android:2.5.2") // To Fix SSL Fu*kery on Android 9
|
||||
implementation("com.uwetrottmann.tmdb2:tmdb-java:2.10.0") // TMDB API v3 Wrapper Made with RetroFit
|
||||
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.6")
|
||||
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.4")
|
||||
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.1") /* JSON Parser
|
||||
^ Don't Bump Jackson above 2.13.1 , Crashes on Android TV's and FireSticks that have Min API
|
||||
Level 25 or Less. */
|
||||
|
|
|
@ -7,7 +7,7 @@ import com.lagradost.cloudstream3.extractors.helper.AesHelper.cryptoAESHandler
|
|||
import com.lagradost.cloudstream3.utils.AppUtils
|
||||
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
import com.lagradost.cloudstream3.utils.Qualities
|
||||
import com.lagradost.cloudstream3.utils.M3u8Helper
|
||||
|
||||
class Moviesapi : Chillx() {
|
||||
override val name = "Moviesapi"
|
||||
|
@ -23,13 +23,14 @@ class Watchx : Chillx() {
|
|||
override val name = "Watchx"
|
||||
override val mainUrl = "https://watchx.top"
|
||||
}
|
||||
|
||||
open class Chillx : ExtractorApi() {
|
||||
override val name = "Chillx"
|
||||
override val mainUrl = "https://chillx.top"
|
||||
override val requiresReferer = true
|
||||
|
||||
companion object {
|
||||
private const val KEY = "eN0^>\$^#M08uFv%c"
|
||||
private const val KEY = "tSIsE8FgpRkv3QQQ"
|
||||
}
|
||||
|
||||
override suspend fun getUrl(
|
||||
|
@ -38,10 +39,14 @@ open class Chillx : ExtractorApi() {
|
|||
subtitleCallback: (SubtitleFile) -> Unit,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
) {
|
||||
val master = Regex("MasterJS\\s*=\\s*'([^']+)").find(
|
||||
val master = Regex("\\s*=\\s*'([^']+)").find(
|
||||
app.get(
|
||||
url,
|
||||
referer = referer
|
||||
referer = referer ?: "",
|
||||
headers = mapOf(
|
||||
"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",
|
||||
)
|
||||
).text
|
||||
)?.groupValues?.get(1)
|
||||
val decrypt = cryptoAESHandler(master ?: return, KEY.toByteArray(), false)?.replace("\\", "") ?: throw ErrorLoadingException("failed to decrypt")
|
||||
|
@ -59,17 +64,12 @@ open class Chillx : ExtractorApi() {
|
|||
"Origin" to mainUrl,
|
||||
)
|
||||
|
||||
callback.invoke(
|
||||
ExtractorLink(
|
||||
name,
|
||||
name,
|
||||
source ?: return,
|
||||
"$mainUrl/",
|
||||
Qualities.P1080.value,
|
||||
headers = headers,
|
||||
isM3u8 = true
|
||||
)
|
||||
)
|
||||
M3u8Helper.generateM3u8(
|
||||
name,
|
||||
source ?: return,
|
||||
"$mainUrl/",
|
||||
headers = headers
|
||||
).forEach(callback)
|
||||
|
||||
AppUtils.tryParseJson<List<Tracks>>("[$tracks]")
|
||||
?.filter { it.kind == "captions" }?.map { track ->
|
||||
|
|
|
@ -7,7 +7,6 @@ import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
|
|||
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
import com.lagradost.cloudstream3.utils.M3u8Helper.Companion.generateM3u8
|
||||
import com.lagradost.cloudstream3.utils.Qualities
|
||||
import java.net.URL
|
||||
|
||||
open class Dailymotion : ExtractorApi() {
|
||||
|
@ -27,21 +26,16 @@ open class Dailymotion : ExtractorApi() {
|
|||
callback: (ExtractorLink) -> Unit
|
||||
) {
|
||||
val embedUrl = getEmbedUrl(url) ?: return
|
||||
val doc = app.get(embedUrl).document
|
||||
val req = app.get(embedUrl)
|
||||
val prefix = "window.__PLAYER_CONFIG__ = "
|
||||
val configStr = doc.selectFirst("script:containsData($prefix)")?.data() ?: return
|
||||
val config = tryParseJson<Config>(configStr.substringAfter(prefix)) ?: return
|
||||
val configStr = req.document.selectFirst("script:containsData($prefix)")?.data() ?: return
|
||||
val config = tryParseJson<Config>(configStr.substringAfter(prefix).substringBefore(";").trim()) ?: return
|
||||
val id = getVideoId(embedUrl) ?: return
|
||||
val dmV1st = config.dmInternalData.v1st
|
||||
val dmTs = config.dmInternalData.ts
|
||||
val metaDataUrl =
|
||||
"$mainUrl/player/metadata/video/$id?locale=en&dmV1st=$dmV1st&dmTs=$dmTs&is_native_app=0"
|
||||
val cookies = mapOf(
|
||||
"v1st" to dmV1st,
|
||||
"dmvk" to config.context.dmvk,
|
||||
"ts" to dmTs.toString()
|
||||
)
|
||||
val metaData = app.get(metaDataUrl, referer = embedUrl, cookies = cookies)
|
||||
val embedder = config.context.embedder
|
||||
val metaDataUrl = "$mainUrl/player/metadata/video/$id?embedder=$embedder&locale=en-US&dmV1st=$dmV1st&dmTs=$dmTs&is_native_app=0"
|
||||
val metaData = app.get(metaDataUrl, referer = embedUrl, cookies = req.cookies)
|
||||
.parsedSafe<MetaData>() ?: return
|
||||
metaData.qualities.forEach { (_, video) ->
|
||||
video.forEach {
|
||||
|
@ -84,13 +78,13 @@ open class Dailymotion : ExtractorApi() {
|
|||
)
|
||||
|
||||
data class InternalData(
|
||||
val ts: Int,
|
||||
val ts: Long,
|
||||
val v1st: String
|
||||
)
|
||||
|
||||
data class Context(
|
||||
@JsonProperty("access_token") val accessToken: String?,
|
||||
val dmvk: String,
|
||||
val embedder: String?,
|
||||
)
|
||||
|
||||
data class MetaData(
|
||||
|
|
|
@ -18,7 +18,8 @@ open class Linkbox : ExtractorApi() {
|
|||
subtitleCallback: (SubtitleFile) -> Unit,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
) {
|
||||
val id = Regex("""(?:/f/|/file/|\?id=)(\w+)""").find(url)?.groupValues?.get(1)
|
||||
val token = Regex("""(?:/f/|/file/|\?id=)(\w+)""").find(url)?.groupValues?.get(1)
|
||||
val id = app.get("$mainUrl/api/file/share_out_list/?sortField=utime&sortAsc=0&pageNo=1&pageSize=50&shareToken=$token").parsedSafe<Responses>()?.data?.itemId
|
||||
app.get("$mainUrl/api/file/detail?itemId=$id", referer = url)
|
||||
.parsedSafe<Responses>()?.data?.itemInfo?.resolutionList?.map { link ->
|
||||
callback.invoke(
|
||||
|
@ -44,6 +45,7 @@ open class Linkbox : ExtractorApi() {
|
|||
|
||||
data class Data(
|
||||
@JsonProperty("itemInfo") val itemInfo: ItemInfo? = null,
|
||||
@JsonProperty("itemId") val itemId: String? = null,
|
||||
)
|
||||
|
||||
data class Responses(
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
package com.lagradost.cloudstream3.extractors
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import com.lagradost.cloudstream3.SubtitleFile
|
||||
import com.lagradost.cloudstream3.app
|
||||
import com.lagradost.cloudstream3.base64Encode
|
||||
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
import com.lagradost.cloudstream3.utils.M3u8Helper
|
||||
import javax.crypto.Cipher
|
||||
import javax.crypto.spec.SecretKeySpec
|
||||
|
||||
// Code found in https://github.com/Claudemirovsky/worstsource-keys
|
||||
// special credits to @Claudemirovsky for providing key
|
||||
open class Vidplay : ExtractorApi() {
|
||||
override val name = "Vidplay"
|
||||
override val mainUrl = "https://vidplay.site"
|
||||
override val requiresReferer = true
|
||||
|
||||
override suspend fun getUrl(
|
||||
url: String,
|
||||
referer: String?,
|
||||
subtitleCallback: (SubtitleFile) -> Unit,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
) {
|
||||
val id = url.substringBefore("?").substringAfterLast("/")
|
||||
val encodeId = encodeId(id, getKeys())
|
||||
val mediaUrl = callFutoken(encodeId, url)
|
||||
val res = app.get(
|
||||
"$mediaUrl", headers = mapOf(
|
||||
"Accept" to "application/json, text/javascript, */*; q=0.01",
|
||||
"X-Requested-With" to "XMLHttpRequest",
|
||||
), referer = url
|
||||
).parsedSafe<Response>()?.result?.sources
|
||||
|
||||
res?.map {
|
||||
M3u8Helper.generateM3u8(
|
||||
this.name,
|
||||
it.file ?: return@map,
|
||||
"$mainUrl/"
|
||||
).forEach(callback)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private suspend fun getKeys(): List<String> {
|
||||
return app.get("https://raw.githubusercontent.com/Claudemirovsky/worstsource-keys/keys/keys.json")
|
||||
.parsed()
|
||||
}
|
||||
|
||||
private suspend fun callFutoken(id: String, url: String): String? {
|
||||
val script = app.get("$mainUrl/futoken").text
|
||||
val k = "k='(\\S+)'".toRegex().find(script)?.groupValues?.get(1) ?: return null
|
||||
val a = mutableListOf(k)
|
||||
for (i in id.indices) {
|
||||
a.add((k[i % k.length].code + id[i].code).toString())
|
||||
}
|
||||
return "$mainUrl/mediainfo/${a.joinToString(",")}?${url.substringAfter("?")}"
|
||||
}
|
||||
|
||||
private fun encodeId(id: String, keyList: List<String>): String {
|
||||
val cipher1 = Cipher.getInstance("RC4")
|
||||
val cipher2 = Cipher.getInstance("RC4")
|
||||
cipher1.init(
|
||||
Cipher.DECRYPT_MODE,
|
||||
SecretKeySpec(keyList[0].toByteArray(), "RC4"),
|
||||
cipher1.parameters
|
||||
)
|
||||
cipher2.init(
|
||||
Cipher.DECRYPT_MODE,
|
||||
SecretKeySpec(keyList[1].toByteArray(), "RC4"),
|
||||
cipher2.parameters
|
||||
)
|
||||
var input = id.toByteArray()
|
||||
input = cipher1.doFinal(input)
|
||||
input = cipher2.doFinal(input)
|
||||
return base64Encode(input).replace("/", "_")
|
||||
}
|
||||
|
||||
data class Sources(
|
||||
@JsonProperty("file") val file: String? = null,
|
||||
)
|
||||
|
||||
data class Result(
|
||||
@JsonProperty("sources") val sources: ArrayList<Sources>? = arrayListOf(),
|
||||
)
|
||||
|
||||
data class Response(
|
||||
@JsonProperty("result") val result: Result? = null,
|
||||
)
|
||||
|
||||
}
|
|
@ -167,6 +167,7 @@ import com.lagradost.cloudstream3.extractors.Vidgomunimesb
|
|||
import com.lagradost.cloudstream3.extractors.Vidmoly
|
||||
import com.lagradost.cloudstream3.extractors.Vidmolyme
|
||||
import com.lagradost.cloudstream3.extractors.Vido
|
||||
import com.lagradost.cloudstream3.extractors.Vidplay
|
||||
import com.lagradost.cloudstream3.extractors.Vidstreamz
|
||||
import com.lagradost.cloudstream3.extractors.Vizcloud
|
||||
import com.lagradost.cloudstream3.extractors.Vizcloud2
|
||||
|
@ -793,6 +794,7 @@ val extractorApis: MutableList<ExtractorApi> = arrayListOf(
|
|||
VidSrcExtractor2(),
|
||||
PlayLtXyz(),
|
||||
AStreamHub(),
|
||||
Vidplay(),
|
||||
|
||||
Cda(),
|
||||
Dailymotion(),
|
||||
|
|
|
@ -30,7 +30,7 @@ class GlideModule : AppGlideModule() {
|
|||
.signature(ObjectKey(System.currentTimeMillis().toShort()))
|
||||
}.setDiskCache {
|
||||
// Possible to make this a setting in the future.
|
||||
val memoryCacheSizeBytes: Long = 1024 * 1024 * 100; // 100mb
|
||||
val memoryCacheSizeBytes: Long = 1024 * 1024 * 100 // 100mb
|
||||
InternalCacheDiskCacheFactory(context, memoryCacheSizeBytes).build()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -316,15 +316,15 @@ object UIHelper {
|
|||
|
||||
if (colorCallback != null) {
|
||||
builder = builder.listener(object : RequestListener<Drawable> {
|
||||
@SuppressLint("CheckResult")
|
||||
|
||||
override fun onResourceReady(
|
||||
resource: Drawable?,
|
||||
model: Any?,
|
||||
resource: Drawable,
|
||||
model: Any,
|
||||
target: Target<Drawable>?,
|
||||
dataSource: DataSource?,
|
||||
dataSource: DataSource,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
resource?.toBitmapOrNull()
|
||||
resource.toBitmapOrNull()
|
||||
?.let { bitmap ->
|
||||
createPaletteAsync(
|
||||
identifier,
|
||||
|
@ -335,11 +335,10 @@ object UIHelper {
|
|||
return false
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
override fun onLoadFailed(
|
||||
e: GlideException?,
|
||||
model: Any?,
|
||||
target: Target<Drawable>?,
|
||||
target: Target<Drawable>,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
return false
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
<string name="bug_report_settings_off">بس بعات البيانات وقتما يتعطل الآپ</string>
|
||||
<string name="preview_background_img_des">شوف الخلفية</string>
|
||||
<string name="play_movie_button">مشّي الفيلم</string>
|
||||
<string name="subs_hold_to_reset_to_default">ضلّ كابس لترجع الساتِنگز كيف كانة أول ما نزلتو الآپ</string>
|
||||
<string name="subs_hold_to_reset_to_default">ضلّ كابس لترجع السَتِنگز كيف كانة أول ما نزلتو الآپ</string>
|
||||
<string name="season_format">%1$s%2$d%3$s</string>
|
||||
<string name="subs_default_reset_toast">رجِعت الساتِنيگز ل كيف كانت أساسًا</string>
|
||||
<string name="subs_default_reset_toast">رجِعت السَتِنگز ل كيف كانت أساسًا</string>
|
||||
<string name="uprereleases_settings_des">نبش على تجديدات بالنسخة التجريبية كمان</string>
|
||||
<string name="subs_outline_color">لون حدود الكتيبة</string>
|
||||
<string name="search_poster_img_des">پوستر</string>
|
||||
|
@ -37,7 +37,7 @@
|
|||
<string name="subs_download_languages">نزل الترجمات مع الڤيديو</string>
|
||||
<string name="search_provider_text_providers">عوزو المصادر لَ تنبّشو</string>
|
||||
<string name="go_back_img_des">رجاع</string>
|
||||
<string name="discord">انضم لگروپ \"كلودستريم\" ع الـ\"ديسكورد\"</string>
|
||||
<string name="discord">انضم لگروپ \"كلود ستريم\" ع الـ\"ديسكورد\"</string>
|
||||
<string name="episode_more_options_des">بعد خيارات</string>
|
||||
<string name="backup_success">تسيّڤة النسخة الإحتياطية</string>
|
||||
<string name="benene_count_text">صرتو عاطين %d موزززة للمطورين!</string>
|
||||
|
@ -73,7 +73,7 @@
|
|||
<string name="resume">كَمِّل</string>
|
||||
<string name="test_log">سِجِل</string>
|
||||
<string name="torrent_no_plot">ما نلاقى الوصف</string>
|
||||
<string name="subtitles_settings">ساتِنگز الترجمة</string>
|
||||
<string name="subtitles_settings">سَتِنگز الترجمة</string>
|
||||
<string name="subs_window_color">لون العلبة</string>
|
||||
<string name="play_torrent_button">عمول ستريم للتورنت</string>
|
||||
<string name="automatic_plugin_download_summary">تلقائيًا نَزِل كل الإضافات من الريپويات يلي نزادِت.</string>
|
||||
|
@ -86,18 +86,18 @@
|
|||
<string name="advanced_search">تنبيش منظّم</string>
|
||||
<string name="chromecast_subtitles_settings">ترجمة \"كروم كاست\"</string>
|
||||
<string name="swipe_to_change_settings">سحابو لتتحكمو بالصوت والضو</string>
|
||||
<string name="rated_format" formatted="true">رايتيگ: %.1f</string>
|
||||
<string name="chromecast_subtitles_settings_des">ستنگز تبع ترجمة \"كروم كاست\"</string>
|
||||
<string name="rated_format" formatted="true">رايتينگ: %.1f</string>
|
||||
<string name="chromecast_subtitles_settings_des">سَتِنگز تبع ترجمة \"كروم كاست\"</string>
|
||||
<string name="browser">متصفح الوَب</string>
|
||||
<string name="double_tap_to_seek_settings_des">كبوس مرتين على اليمين أو الشمال حتى تقرب أو ترَجِع الڤيديو</string>
|
||||
<string name="normal_no_plot">ما نلاقى وصف الأحداث</string>
|
||||
<string name="next_episode">الحلقة يلي بَعدا</string>
|
||||
<string name="updates_settings">فرجي تجديدات الآپ</string>
|
||||
<string name="library">رفّ</string>
|
||||
<string name="lightnovel">آپ زغير من نفس المطورين للروايات بدل من الڤيديوات</string>
|
||||
<string name="lightnovel">آپ من نفس المطورين للروايات الخفيفة، بدل من الڤيديوات</string>
|
||||
<string name="automatic_plugin_download_mode_title">حدد الوضع لَتفَلتِر تنزيل الإضافات</string>
|
||||
<string name="episode">حلقة</string>
|
||||
<string name="autoplay_next_settings_des">مَشّي الحلقة يلي بعدا تلقائيًا بعد ما تُخلَص الحلقة</string>
|
||||
<string name="autoplay_next_settings_des">مَشّي الحلقة يلّي بعدا تلقائيًا بعد ما تُخلَص الحلقة</string>
|
||||
<string name="subs_text_color">لون الكتيبة</string>
|
||||
<string name="type_completed">مخلص</string>
|
||||
<string name="use_system_brightness_settings_des">عوز قوة ضوّ الشاشة تبع السيستام بدل من تغميئ الڤيديو</string>
|
||||
|
@ -139,7 +139,7 @@
|
|||
<string name="home_main_poster_img_des">الپوسر الأساسية</string>
|
||||
<string name="pick_source">المصادر</string>
|
||||
<string name="double_tap_to_seek_settings">كبوسو مرتين لتقفو</string>
|
||||
<string name="title_settings">ثاتينگز</string>
|
||||
<string name="title_settings">سَتِنگز</string>
|
||||
<string name="title_search">التنبيش</string>
|
||||
<string name="loading">لودينگ…</string>
|
||||
<string name="action_remove_watching">شيل</string>
|
||||
|
@ -147,17 +147,17 @@
|
|||
<string name="category_updates">التجديد والنسخات الاحتياطية</string>
|
||||
<string name="pref_filter_search_quality">خبي هيدي الجودات من نتائج التنبيش</string>
|
||||
<string name="type_on_hold">موقف موقتًا</string>
|
||||
<string name="app_name">كلاودستريم</string>
|
||||
<string name="app_name">كلود ستريم</string>
|
||||
<string name="player_size_settings_des">شيل الأسود من الأطراف</string>
|
||||
<string name="season_short">ج</string>
|
||||
<string name="apk_installer_settings">طريقة تجديد الآپ</string>
|
||||
<string name="autoplay_next_settings">تقائيًا مشّي الحلقة ل بعدا</string>
|
||||
<string name="autoplay_next_settings">تلقائيًا مشّي الحلقة الّي بعدا</string>
|
||||
<string name="picture_in_picture">كفي فوق غير آپ</string>
|
||||
<string name="player_subtitles_settings_des">ساتِنگز ترجمة الڤيديو</string>
|
||||
<string name="player_subtitles_settings_des">سَتِنگز ترجمة الڤيديو</string>
|
||||
<string name="app_language">لغة الآپ</string>
|
||||
<string name="show_trailers_settings">فرجي المقاطع الدعائية</string>
|
||||
<string name="test_passed">نجح</string>
|
||||
<string name="play_with_app_name">مَشّي بـ\"كلاود ستريم\"</string>
|
||||
<string name="play_with_app_name">مَشّي بـ\"كلود ستريم\"</string>
|
||||
<string name="subs_subtitle_elevation">إرتفاع الترجمة</string>
|
||||
<string name="search_provider_text_types">عوزو الأنواع ل تنبّشو</string>
|
||||
<string name="episodes">حلقات</string>
|
||||
|
@ -536,7 +536,7 @@
|
|||
<string name="plugins_updated" formatted="true">عدد الإضافيات يلي تجددت: %d</string>
|
||||
<string name="delayed_update_notice">رح يتجدد الآپ وقتا تطلعو مِنو</string>
|
||||
<string name="hls_playlist">پلاي ليست \"ايش أل أس\"</string>
|
||||
<string name="add_repository">زيد ريپوزيتاري</string>
|
||||
<string name="add_repository">زيد ريپوزيتوري</string>
|
||||
<string name="action_mark_as_watched">علم إنو حضرتو</string>
|
||||
<string name="preferred_media_subtext">شو بَدَك تشوف</string>
|
||||
<string name="subtitles_remove_captions">شيل المعلومات يلي محطوطة بالترجمة ليلي عندن فقد سمعي</string>
|
||||
|
|
|
@ -510,4 +510,7 @@
|
|||
<string name="automatic">Automatikus</string>
|
||||
<string name="android_tv_interface_on_seek_settings_summary">Az átugrás mértéke, amikor a lejátszó látható</string>
|
||||
<string name="automatic_plugin_download_mode_title">Válassza ki a módot a pluginek letöltésének szűréséhez</string>
|
||||
<string name="backup_frequency">Mentési gyakoriság</string>
|
||||
<string name="sync_score">Értékelt</string>
|
||||
<string name="disable">Kikapcsolás</string>
|
||||
</resources>
|
||||
|
|
|
@ -11,11 +11,11 @@
|
|||
<string name="rew_text_regular_format" formatted="true" translatable="false">%d</string>
|
||||
<string name="rating_format" formatted="true" translatable="false">%.1f/10.0</string>
|
||||
<string name="year_format" formatted="true" translatable="false">%d</string>
|
||||
<string name="app_dub_sub_episode_text_format" formatted="true">%$1s B. %2$d</string>
|
||||
<string name="app_dub_sub_episode_text_format" formatted="true">%1$s B. %2$d</string>
|
||||
<string name="cast_format" formatted="true">Cast: %s</string>
|
||||
<string name="next_episode_format" formatted="true">Bölüm %d şu tarihte yayınlanacak</string>
|
||||
<string name="next_episode_time_day_format" formatted="true">%dg %ds %dd</string>
|
||||
<string name="next_episode_time_hour_format" formatted="true">%ds %dd</string>
|
||||
<string name="next_episode_time_day_format" formatted="true">%1$dg %2$ds %3$dd</string>
|
||||
<string name="next_episode_time_hour_format" formatted="true">%1$ds %2$dd</string>
|
||||
<string name="next_episode_time_min_format" formatted="true">%dm</string>
|
||||
<!-- IS NOT NEEDED TO TRANSLATE AS THEY ARE ONLY USED FOR SCREEN READERS AND WONT SHOW UP TO NORMAL USERS -->
|
||||
<string name="result_poster_img_des">Poster</string>
|
||||
|
@ -204,7 +204,7 @@
|
|||
<string name="delete_file">Dosyayı sil</string>
|
||||
<string name="delete">Sil</string>
|
||||
<string name="cancel">İptal et</string>
|
||||
<string name="pause">Durdur</string>
|
||||
<string name="pause">Duraklat</string>
|
||||
<string name="resume">Sürdür</string>
|
||||
<string name="go_back_30">-30</string>
|
||||
<string name="go_forward_30">+30</string>
|
||||
|
@ -537,11 +537,11 @@
|
|||
<string name="clipboard_too_large">Çok fazla metin. Panoya kaydedilemiyor.</string>
|
||||
<string name="library">Kütüphane</string>
|
||||
<string name="browser">Tarayıcı</string>
|
||||
<string name="empty_library_no_accounts_message">Görünüşe göre kütüphaneniz boş :(
|
||||
\nBir kütüphane hesabına giriş yapın veya yerel kütüphanenize içerik ekleyin</string>
|
||||
<string name="empty_library_no_accounts_message">Kütüphaneniz boş :(
|
||||
\nBir kütüphane hesabında oturum açın veya yerel kütüphanenize programlar ekleyin.</string>
|
||||
<string name="safe_mode_file">Güvenli mod dosyası bulundu!
|
||||
\nDosya kaldırılana kadar başlangıçta herhangi bir uzantı yüklenmiyor.</string>
|
||||
<string name="sort_by">Sırala</string>
|
||||
<string name="sort_by">Şuna Göre Sırala</string>
|
||||
<string name="sort">Sırala</string>
|
||||
<string name="sort_updated_new">Güncellenme (Yeniden Eskiye)</string>
|
||||
<string name="sort_updated_old">Güncellenme (Eskiden Yeniye)</string>
|
||||
|
|
|
@ -181,8 +181,8 @@
|
|||
<string name="no_season">Không có mùa nào</string>
|
||||
<string name="episode">Tập</string>
|
||||
<string name="episodes">Tập</string>
|
||||
<string name="episodes_range">%1$ng-%2$ng</string>
|
||||
<string name="episode_format" formatted="true">%d %s</string>
|
||||
<string name="episodes_range">%1$d-%2$d</string>
|
||||
<string name="episode_format" formatted="true">%1$d %2$s</string>
|
||||
<string name="season_short">M</string>
|
||||
<string name="episode_short">T</string>
|
||||
<string name="no_episodes_found">Không có tập nào</string>
|
||||
|
@ -311,7 +311,7 @@
|
|||
<string name="example_site_name">Địa chỉ trang web</string>
|
||||
<string name="example_site_url">example.com</string>
|
||||
<string name="example_lang_name">Mã ngôn ngữ (vi)</string>
|
||||
<string name="login_format" formatted="true">%1$gi %2$gi</string>
|
||||
<string name="login_format" formatted="true">%1$s %2$s</string>
|
||||
<string name="account">tài khoản</string>
|
||||
<string name="logout">Đăng xuất</string>
|
||||
<string name="login">Đăng nhập</string>
|
||||
|
@ -444,7 +444,7 @@
|
|||
<string name="redo_setup_process">Thiết lập lại</string>
|
||||
<string name="apk_installer_settings">Bộ cài APK</string>
|
||||
<string name="apk_installer_settings_des">Một số máy không hỗ trợ trình cài đặt gói mới. Hãy thử tùy chọn cũ nếu các bản cập nhật không cài đặt.</string>
|
||||
<string name="season_format">%s %d%s</string>
|
||||
<string name="season_format">%1$s %2$d%3$s</string>
|
||||
<string name="play_trailer_button">Xem giới thiệu</string>
|
||||
<string name="automatic_plugin_download_summary">Tự động tải plugin còn thiếu.</string>
|
||||
<string name="update_started">Bắt đầu cập nhật</string>
|
||||
|
|
|
@ -6,7 +6,7 @@ buildscript {
|
|||
}
|
||||
dependencies {
|
||||
classpath("com.android.tools.build:gradle:8.2.0")
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20")
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.21")
|
||||
classpath("org.jetbrains.dokka:dokka-gradle-plugin:1.9.10")
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
@ -22,9 +22,9 @@ allprojects {
|
|||
}
|
||||
|
||||
plugins {
|
||||
id("com.google.devtools.ksp") version "1.9.20-1.0.14" apply false
|
||||
id("com.google.devtools.ksp") version "1.9.21-1.0.15" apply false
|
||||
}
|
||||
|
||||
tasks.register<Delete>("clean") {
|
||||
delete(rootProject.layout.buildDirectory)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
CloudStream-3 size film, dizi ve anime akışı yapma ve indirme olanağı sunar.
|
||||
CloudStream-3, Filmleri, TV Dizilerini ve Animeleri izlemenize ve indirmenize olanak tanır.
|
||||
|
||||
Uygulama hiçbir reklam ve analitik yöntemleri barındırmaz ve birçok fragman & film sitelerini destekler, ve daha fazlası:
|
||||
Uygulama herhangi bir reklam ve analitik içermez ve
|
||||
birden fazla fragman & film sitesini ve daha fazlasını destekler, örneğin:
|
||||
|
||||
Yer imleri
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue