Compare commits

...

5 commits

Author SHA1 Message Date
Cloudburst
1be78df977
Merge branch 'master' into action-api 2024-09-22 20:56:15 +02:00
Cloudburst
e288c83c3d remove unused strings, address comment 2024-09-17 23:37:59 +02:00
Cloudburst
6f76352cbe move all possible actions to new api, handle some todos 2024-09-10 21:17:36 +02:00
Cloudburst
9505ca2592 move all app actions to new api, handle some todos 2024-09-09 17:21:45 +02:00
Cloudburst
1d55610685 initial start on the VideoClickAction api 2024-09-08 22:51:19 +02:00
81 changed files with 839 additions and 1048 deletions

View file

@ -17,7 +17,7 @@
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<!-- Required for getting arbitrary Aniyomi packages -->
<!-- Required for OpenInAppAction and getting arbitrary Aniyomi packages -->
<uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
@ -30,13 +30,6 @@
android:name="android.software.leanback"
android:required="false" />
<queries>
<package android:name="org.videolan.vlc" />
<package android:name="com.instantbits.cast.webvideo" />
<package android:name="is.xyz.mpv" />
<package android:name="is.xyz.mpv.ytdl" />
</queries>
<!-- Without the large heap Exoplayer buffering gets reset due to OOM. -->
<!--TODO https://stackoverflow.com/questions/41799732/chromecast-button-not-visible-in-android-->
<application

View file

@ -30,15 +30,14 @@ import com.google.android.material.chip.ChipGroup
import com.google.android.material.navigationrail.NavigationRailView
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey
import com.lagradost.cloudstream3.MainActivity.Companion.resumeApps
import com.lagradost.cloudstream3.actions.OpenInAppAction
import com.lagradost.cloudstream3.actions.VideoClickActionHolder
import com.lagradost.cloudstream3.databinding.ToastBinding
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.ui.player.PlayerEventType
import com.lagradost.cloudstream3.ui.result.ResultFragment
import com.lagradost.cloudstream3.ui.result.UiText
import com.lagradost.cloudstream3.ui.settings.Globals.updateTv
import com.lagradost.cloudstream3.utils.AppContextUtils.isRtl
import com.lagradost.cloudstream3.utils.DataStoreHelper
import com.lagradost.cloudstream3.utils.Event
import com.lagradost.cloudstream3.utils.UIHelper
import com.lagradost.cloudstream3.utils.UIHelper.hasPIPPermission
@ -218,19 +217,14 @@ object CommonActivity {
componentActivity.updateTv()
NewPipe.init(DownloaderTestImpl.getInstance())
for (resumeApp in resumeApps) {
resumeApp.launcher =
componentActivity.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
val resultCode = result.resultCode
val data = result.data
if (resultCode == AppCompatActivity.RESULT_OK && data != null && resumeApp.position != null && resumeApp.duration != null) {
val pos = resumeApp.getPosition(data)
val dur = resumeApp.getDuration(data)
if (dur > 0L && pos > 0L)
DataStoreHelper.setViewPos(getKey(resumeApp.lastId), pos, dur)
removeKey(resumeApp.lastId)
ResultFragment.updateUI()
}
MainActivity.activityResultLauncher = componentActivity.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == AppCompatActivity.RESULT_OK) {
val actionUid = getKey<String>("last_click_action") ?: return@registerForActivityResult
Log.d(TAG, "Loading action $actionUid result handler")
val action = VideoClickActionHolder.getByUniqueId(actionUid) as? OpenInAppAction ?: return@registerForActivityResult
action.onResult(act, result.data)
removeKey("last_click_action")
removeKey("last_opened_id")
}
}

View file

@ -173,7 +173,7 @@ import com.lagradost.cloudstream3.utils.UIHelper.setImage
import com.lagradost.cloudstream3.utils.UIHelper.toPx
import com.lagradost.cloudstream3.utils.USER_PROVIDER_API
import com.lagradost.cloudstream3.utils.USER_SELECTED_HOMEPAGE_API
import com.lagradost.cloudstream3.utils.fcast.FcastManager
import com.lagradost.cloudstream3.actions.temp.fcast.FcastManager
import com.lagradost.safefile.SafeFile
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
@ -186,120 +186,9 @@ import kotlin.math.abs
import kotlin.math.absoluteValue
import kotlin.system.exitProcess
//https://github.com/videolan/vlc-android/blob/3706c4be2da6800b3d26344fc04fab03ffa4b860/application/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.kt#L1898
//https://wiki.videolan.org/Android_Player_Intents/
//https://github.com/mpv-android/mpv-android/blob/0eb3cdc6f1632636b9c30d52ec50e4b017661980/app/src/main/java/is/xyz/mpv/MPVActivity.kt#L904
//https://mpv-android.github.io/mpv-android/intent.html
// https://www.webvideocaster.com/integrations
//https://github.com/jellyfin/jellyfin-android/blob/6cbf0edf84a3da82347c8d59b5d5590749da81a9/app/src/main/java/org/jellyfin/mobile/bridge/ExternalPlayer.kt#L225
class MainActivity : AppCompatActivity(), ColorPickerDialogListener, BiometricCallback {
companion object {
const val VLC_PACKAGE = "org.videolan.vlc"
const val MPV_PACKAGE = "is.xyz.mpv"
const val MPV_YTDL_PACKAGE = "is.xyz.mpv.ytdl"
const val WEB_VIDEO_CAST_PACKAGE = "com.instantbits.cast.webvideo"
val VLC_COMPONENT = ComponentName(VLC_PACKAGE, "$VLC_PACKAGE.gui.video.VideoPlayerActivity")
val MPV_COMPONENT = ComponentName(MPV_PACKAGE, "$MPV_PACKAGE.MPVActivity")
val MPV_YTDL_COMPONENT = ComponentName(MPV_YTDL_PACKAGE, "$MPV_PACKAGE.MPVActivity")
//TODO REFACTOR AF
open class ResultResume(
val packageString: String,
val action: String = Intent.ACTION_VIEW,
val position: String? = null,
val duration: String? = null,
var launcher: ActivityResultLauncher<Intent>? = null,
) {
val defaultTime = -1L
val lastId get() = "${packageString}_last_open_id"
suspend fun launch(id: Int?, callback: suspend Intent.() -> Unit) {
val intent = Intent(action)
if (id != null)
setKey(lastId, id)
else
removeKey(lastId)
intent.setPackage(packageString)
callback.invoke(intent)
launcher?.launch(intent)
}
open fun getPosition(intent: Intent?): Long {
return defaultTime
}
open fun getDuration(intent: Intent?): Long {
return defaultTime
}
}
val VLC = object : ResultResume(
VLC_PACKAGE,
// Android 13 intent restrictions fucks up specifically launching the VLC player
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
"org.videolan.vlc.player.result"
} else {
Intent.ACTION_VIEW
},
"extra_position",
"extra_duration",
) {
override fun getPosition(intent: Intent?): Long {
return intent?.getLongExtra(this.position, defaultTime) ?: defaultTime
}
override fun getDuration(intent: Intent?): Long {
return intent?.getLongExtra(this.duration, defaultTime) ?: defaultTime
}
}
val MPV = object : ResultResume(
MPV_PACKAGE,
//"is.xyz.mpv.MPVActivity.result", // resume not working :pensive:
position = "position",
duration = "duration",
) {
override fun getPosition(intent: Intent?): Long {
return intent?.getIntExtra(this.position, defaultTime.toInt())?.toLong()
?: defaultTime
}
override fun getDuration(intent: Intent?): Long {
return intent?.getIntExtra(this.duration, defaultTime.toInt())?.toLong()
?: defaultTime
}
}
val MPV_YTDL = object : ResultResume(
MPV_YTDL_PACKAGE,
//"is.xyz.mpv.ytdl/is.xyz.mpv.MPVActivity.result", // resume not working :pensive:
position = "position",
duration = "duration",
) {
override fun getPosition(intent: Intent?): Long {
return intent?.getIntExtra(this.position, defaultTime.toInt())?.toLong()
?: defaultTime
}
override fun getDuration(intent: Intent?): Long {
return intent?.getIntExtra(this.duration, defaultTime.toInt())?.toLong()
?: defaultTime
}
}
val WEB_VIDEO = ResultResume(WEB_VIDEO_CAST_PACKAGE)
val resumeApps = arrayOf(
VLC, MPV, MPV_YTDL, WEB_VIDEO
)
var activityResultLauncher: ActivityResultLauncher<Intent>? = null
const val TAG = "MAINACT"
const val ANIMATED_OUTLINE: Boolean = false

View file

@ -0,0 +1,134 @@
package com.lagradost.cloudstream3.actions
import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.widget.Toast
import androidx.core.content.FileProvider
import androidx.core.net.toUri
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
import com.lagradost.cloudstream3.CommonActivity.showToast
import com.lagradost.cloudstream3.MainActivity.Companion.activityResultLauncher
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.ui.result.LinkLoadingResult
import com.lagradost.cloudstream3.ui.result.ResultEpisode
import com.lagradost.cloudstream3.ui.result.ResultFragment
import com.lagradost.cloudstream3.ui.result.UiText
import com.lagradost.cloudstream3.ui.result.txt
import com.lagradost.cloudstream3.utils.AppContextUtils.isAppInstalled
import com.lagradost.cloudstream3.utils.DataStoreHelper
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
fun updateDurationAndPosition(position: Long, duration: Long) {
if (position <= 0 || duration <= 0) return
DataStoreHelper.setViewPos(getKey("last_opened_id"), position, duration)
ResultFragment.updateUI()
}
/**
* Util method that may be helpful for creating intents for apps that support m3u8 files.
* All sources are written to a temporary m3u8 file, which is then sent to the app.
*/
fun makeTempM3U8Intent(
context: Context,
intent: Intent,
result: LinkLoadingResult) {
intent.apply {
addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
addFlags(Intent.FLAG_GRANT_PREFIX_URI_PERMISSION)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
}
val outputDir = context.cacheDir
if (result.links.size == 1) {
intent.setDataAndType(result.links.first().url.toUri(), "video/*")
} else {
val outputFile = File.createTempFile("mirrorlist", ".m3u8", outputDir)
var text = "#EXTM3U\n#EXT-X-VERSION:3"
result.links.forEachIndexed { index, link ->
text += "\n#EXTINF:$index,${link.name}\n${link.url}"
}
//With subtitles it doesn't work for no reason :(
/*for (sub in result.subs) {
val normalizedName = sub.name.replace("[^a-zA-Z0-9 ]".toRegex(), "")
text += "\n#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"${normalizedName}\",DEFAULT=NO,AUTOSELECT=NO,FORCED=NO,LANGUAGE=\"${sub.languageCode}\",URI=\"${sub.url}\""
}*/
text += "\n#EXT-X-ENDLIST"
outputFile.writeText(text)
intent.setDataAndType(
FileProvider.getUriForFile(
context,
context.applicationContext.packageName + ".provider",
outputFile
), "application/x-mpegURL"
)
}
}
abstract class OpenInAppAction(
open val appName: UiText,
open val packageName: String,
private val intentClass: String? = null,
private val action: String = Intent.ACTION_VIEW
): VideoClickAction() {
override val name: UiText
get() = txt(R.string.episode_action_play_in_format, appName)
override val isPlayer = true
override fun shouldShow(context: Context?, video: ResultEpisode?) = context?.isAppInstalled(packageName) == true
override fun runAction(
context: Context?,
video: ResultEpisode,
result: LinkLoadingResult,
index: Int?
) {
if (context == null) return
val intent = Intent(action)
intent.setPackage(packageName)
if (intentClass != null) {
intent.component = ComponentName(packageName, intentClass)
}
putExtra(context, intent, video, result, index)
setKey("last_opened_id", video.id)
try {
CoroutineScope(Dispatchers.IO).launch {
activityResultLauncher?.launch(intent)
}
} catch (_: ActivityNotFoundException) {
showToast(R.string.app_not_found_error, Toast.LENGTH_LONG)
} catch (t: Throwable) {
logError(t)
showToast(t.toString(), Toast.LENGTH_LONG)
}
}
/**
* Before intent is sent, this function is called to put extra data into the intent.
* @see VideoClickAction.runAction
* */
abstract fun putExtra(context: Context, intent: Intent, video: ResultEpisode, result: LinkLoadingResult, index: Int?)
/**
* This function is called when the app is opened again after the intent was sent.
* You can use it to for example update duration and position.
* @see updateDurationAndPosition
*/
abstract fun onResult(activity: Activity, intent: Intent?)
}

View file

@ -0,0 +1,87 @@
package com.lagradost.cloudstream3.actions
import android.app.Activity
import android.content.Context
import com.lagradost.api.Log
import com.lagradost.cloudstream3.actions.temp.CopyClipboardAction
import com.lagradost.cloudstream3.actions.temp.MpvKtPackage
import com.lagradost.cloudstream3.actions.temp.MpvKtPreviewPackage
import com.lagradost.cloudstream3.actions.temp.MpvPackage
import com.lagradost.cloudstream3.actions.temp.MpvYTDLPackage
import com.lagradost.cloudstream3.actions.temp.PlayInBrowserAction
import com.lagradost.cloudstream3.actions.temp.ViewM3U8Action
import com.lagradost.cloudstream3.actions.temp.VlcPackage
import com.lagradost.cloudstream3.actions.temp.WebVideoCastPackage
import com.lagradost.cloudstream3.actions.temp.fcast.FcastAction
import com.lagradost.cloudstream3.ui.result.LinkLoadingResult
import com.lagradost.cloudstream3.ui.result.ResultEpisode
import com.lagradost.cloudstream3.ui.result.UiText
import com.lagradost.cloudstream3.utils.Coroutines.threadSafeListOf
import com.lagradost.cloudstream3.utils.ExtractorLinkType
import kotlin.reflect.jvm.jvmName
object VideoClickActionHolder {
val allVideoClickActions = threadSafeListOf<VideoClickAction>(
PlayInBrowserAction(), CopyClipboardAction(),
VlcPackage(), ViewM3U8Action(),
MpvPackage(), MpvYTDLPackage(),
WebVideoCastPackage(), MpvKtPackage(), MpvKtPreviewPackage(),
FcastAction()
)
init {
Log.d("VideoClickActionHolder", "allVideoClickActions: ${allVideoClickActions.map { it.uniqueId() }}")
}
private const val ACTION_ID_OFFSET = 1000
fun makeOptionMap(activity: Activity?, video: ResultEpisode) = allVideoClickActions
// We need to have index before filtering
.mapIndexed { id, it -> it to id + ACTION_ID_OFFSET }
.filter { it.first.shouldShow(activity, video) }
.map { it.first.name to it.second }
fun getActionById(id: Int): VideoClickAction? = allVideoClickActions.getOrNull(id - ACTION_ID_OFFSET)
fun getByUniqueId(uniqueId: String): VideoClickAction? = allVideoClickActions.firstOrNull { it.uniqueId() == uniqueId }
fun uniqueIdToId(uniqueId: String?): Int? {
if (uniqueId == null) return null
return allVideoClickActions
.mapIndexed { id, it -> it to id + ACTION_ID_OFFSET }
.firstOrNull { it.first.uniqueId() == uniqueId }
?.second
}
fun getPlayers(activity: Activity? = null) = allVideoClickActions.filter { it.isPlayer && it.shouldShow(activity, null) }
}
abstract class VideoClickAction {
abstract val name: UiText
/** if true, the app will show dialog to select source - result.links[index] */
open val oneSource : Boolean = false
/** if true, this action could be selected as default player (one press action) in settings */
open val isPlayer: Boolean = false
/** Which type of sources this action can handle. */
open val sourceTypes: Set<ExtractorLinkType> = ExtractorLinkType.entries.toSet()
/** Determines which plugin a given provider is from. This is the full path to the plugin. */
var sourcePlugin: String? = null
fun uniqueId() = "$sourcePlugin:${this::class.jvmName}"
abstract fun shouldShow(context: Context?, video: ResultEpisode?): Boolean
/**
* This function is called when the action is clicked.
* @param context The current activity
* @param video The episode/movie that was clicked
* @param result The result of the link loading, contains video & subtitle links
* @param index if oneSource is true, this is the index of the selected source
*/
abstract fun runAction(context: Context?, video: ResultEpisode, result: LinkLoadingResult, index: Int?)
}

View file

@ -0,0 +1,27 @@
package com.lagradost.cloudstream3.actions.temp
import android.content.Context
import com.lagradost.cloudstream3.actions.VideoClickAction
import com.lagradost.cloudstream3.ui.result.LinkLoadingResult
import com.lagradost.cloudstream3.ui.result.ResultEpisode
import com.lagradost.cloudstream3.ui.result.txt
import com.lagradost.cloudstream3.utils.UIHelper.clipboardHelper
class CopyClipboardAction: VideoClickAction() {
override val name = txt("Copy to clipboard")
override val oneSource = true
override fun shouldShow(context: Context?, video: ResultEpisode?) = true
override fun runAction(
context: Context?,
video: ResultEpisode,
result: LinkLoadingResult,
index: Int?
) {
if (index == null) return
val link = result.links.getOrNull(index) ?: return
clipboardHelper(txt(link.name), link.url)
}
}

View file

@ -0,0 +1,69 @@
package com.lagradost.cloudstream3.actions.temp
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.core.net.toUri
import com.lagradost.cloudstream3.actions.OpenInAppAction
import com.lagradost.cloudstream3.actions.updateDurationAndPosition
import com.lagradost.cloudstream3.ui.result.LinkLoadingResult
import com.lagradost.cloudstream3.ui.result.ResultEpisode
import com.lagradost.cloudstream3.ui.result.txt
import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos
import com.lagradost.cloudstream3.utils.ExtractorLinkType
class MpvKtPreviewPackage: MpvKtPackage(
appName = "mpvKt Preview",
packageName = "live.mehiz.mpvkt.preview",
)
open class MpvKtPackage(
appName: String = "mpvKt",
packageName: String = "live.mehiz.mpvkt",
): OpenInAppAction(
appName = txt(appName),
packageName = packageName,
intentClass = "live.mehiz.mpvkt.ui.player.PlayerActivity"
) {
override val oneSource = true
override val sourceTypes = setOf(
ExtractorLinkType.VIDEO,
ExtractorLinkType.DASH,
ExtractorLinkType.M3U8
)
override fun putExtra(
context: Context,
intent: Intent,
video: ResultEpisode,
result: LinkLoadingResult,
index: Int?
) {
val link = result.links.getOrNull(index ?: 0) ?: return
intent.apply {
putExtra("subs", result.subs.map { it.url.toUri() }.toTypedArray())
setDataAndType(Uri.parse(link.url), "video/*")
// m3u8 plays, but changing sources feature is not available
// makeTempM3U8Intent(activity, this, result)
//putExtra("headers", link.headers.flatMap { listOf(it.key, it.value) }.toTypedArray())
val position = getViewPos(video.id)?.position
if (position != null)
putExtra("position", position.toInt())
putExtra("secure_uri", true)
}
}
override fun onResult(activity: Activity, intent: Intent?) {
val position = intent?.getIntExtra("position", -1)?.toLong() ?: -1
val duration = intent?.getIntExtra("duration", -1)?.toLong() ?: -1
updateDurationAndPosition(position, duration)
}
}

View file

@ -0,0 +1,61 @@
package com.lagradost.cloudstream3.actions.temp
import android.app.Activity
import android.content.Context
import android.content.Intent
import androidx.core.net.toUri
import com.lagradost.api.Log
import com.lagradost.cloudstream3.actions.OpenInAppAction
import com.lagradost.cloudstream3.actions.makeTempM3U8Intent
import com.lagradost.cloudstream3.actions.updateDurationAndPosition
import com.lagradost.cloudstream3.ui.result.LinkLoadingResult
import com.lagradost.cloudstream3.ui.result.ResultEpisode
import com.lagradost.cloudstream3.ui.result.txt
import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos
import com.lagradost.cloudstream3.utils.ExtractorLinkType
// https://github.com/mpv-android/mpv-android/blob/0eb3cdc6f1632636b9c30d52ec50e4b017661980/app/src/main/java/is/xyz/mpv/MPVActivity.kt#L904
// https://mpv-android.github.io/mpv-android/intent.html
class MpvYTDLPackage : MpvPackage("MPV YTDL", "is.xyz.mpv.ytdl") {
override val sourceTypes = setOf(
ExtractorLinkType.VIDEO,
ExtractorLinkType.DASH,
ExtractorLinkType.M3U8
)
}
open class MpvPackage(appName: String = "MPV", packageName: String = "is.xyz.mpv"): OpenInAppAction(
txt(appName),
packageName,
"is.xyz.mpv.MPVActivity"
) {
override fun putExtra(
context: Context,
intent: Intent,
video: ResultEpisode,
result: LinkLoadingResult,
index: Int?
) {
intent.apply {
putExtra("subs", result.subs.map { it.url.toUri() }.toTypedArray())
putExtra("title", video.name)
makeTempM3U8Intent(context, this, result)
val position = getViewPos(video.id)?.position
if (position != null)
putExtra("position", position.toInt())
putExtra("secure_uri", true)
}
}
override fun onResult(activity: Activity, intent: Intent?) {
val position = intent?.getIntExtra("position", -1) ?: -1
val duration = intent?.getIntExtra("duration", -1) ?: -1
Log.d("MPV", "Position: $position, Duration: $duration")
updateDurationAndPosition(position.toLong(), duration.toLong())
}
}

View file

@ -0,0 +1,44 @@
package com.lagradost.cloudstream3.actions.temp
import android.content.Context
import android.content.Intent
import android.net.Uri
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.actions.VideoClickAction
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.ui.result.LinkLoadingResult
import com.lagradost.cloudstream3.ui.result.ResultEpisode
import com.lagradost.cloudstream3.ui.result.txt
import com.lagradost.cloudstream3.utils.ExtractorLinkType
class PlayInBrowserAction: VideoClickAction() {
override val name = txt(R.string.episode_action_play_in_format, "Browser")
override val oneSource = true
override val isPlayer = true
override val sourceTypes: Set<ExtractorLinkType> = setOf(
ExtractorLinkType.VIDEO,
ExtractorLinkType.DASH,
ExtractorLinkType.M3U8
)
override fun shouldShow(context: Context?, video: ResultEpisode?) = true
override fun runAction(
context: Context?,
video: ResultEpisode,
result: LinkLoadingResult,
index: Int?
) {
val link = result.links.getOrNull(index ?: 0) ?: return
try {
val i = Intent(Intent.ACTION_VIEW)
i.data = Uri.parse(link.url)
context?.startActivity(i)
} catch (e: Exception) {
logError(e)
}
}
}

View file

@ -0,0 +1,30 @@
package com.lagradost.cloudstream3.actions.temp
import android.content.Context
import android.content.Intent
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.actions.VideoClickAction
import com.lagradost.cloudstream3.actions.makeTempM3U8Intent
import com.lagradost.cloudstream3.ui.result.LinkLoadingResult
import com.lagradost.cloudstream3.ui.result.ResultEpisode
import com.lagradost.cloudstream3.ui.result.txt
class ViewM3U8Action: VideoClickAction() {
override val name = txt(R.string.episode_action_play_in_format, "m3u8 player")
override val isPlayer = true
override fun shouldShow(context: Context?, video: ResultEpisode?) = true
override fun runAction(
context: Context?,
video: ResultEpisode,
result: LinkLoadingResult,
index: Int?
) {
if (context == null) return
val i = Intent(Intent.ACTION_VIEW)
makeTempM3U8Intent(context, i, result)
context.startActivity(i)
}
}

View file

@ -0,0 +1,68 @@
package com.lagradost.cloudstream3.actions.temp
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Build
import com.lagradost.api.Log
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
import com.lagradost.cloudstream3.actions.OpenInAppAction
import com.lagradost.cloudstream3.actions.makeTempM3U8Intent
import com.lagradost.cloudstream3.actions.updateDurationAndPosition
import com.lagradost.cloudstream3.ui.result.LinkLoadingResult
import com.lagradost.cloudstream3.ui.result.ResultEpisode
import com.lagradost.cloudstream3.ui.result.txt
import com.lagradost.cloudstream3.ui.subtitles.SUBTITLE_AUTO_SELECT_KEY
import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos
// https://github.com/videolan/vlc-android/blob/3706c4be2da6800b3d26344fc04fab03ffa4b860/application/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.kt#L1898
// https://wiki.videolan.org/Android_Player_Intents/
class VlcPackage: OpenInAppAction(
appName = txt("VLC"),
packageName = "org.videolan.vlc",
intentClass = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
"org.videolan.vlc.gui.video.VideoPlayerActivity"
} else {
null
},
action = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
"org.videolan.vlc.player.result"
} else {
Intent.ACTION_VIEW
}
) {
override val oneSource = false
override fun putExtra(
context: Context,
intent: Intent,
video: ResultEpisode,
result: LinkLoadingResult,
index: Int?
) {
makeTempM3U8Intent(context, intent, result)
val position = getViewPos(video.id)?.position ?: 0L
intent.putExtra("from_start", false)
intent.putExtra("position", position)
intent.putExtra("secure_uri", true)
intent.putExtra("title", video.name)
val subsLang = getKey(SUBTITLE_AUTO_SELECT_KEY) ?: "en"
result.subs.firstOrNull {
subsLang == it.languageCode
}?.let {
intent.putExtra("subtitles_location", it.url)
}
}
override fun onResult(activity: Activity, intent: Intent?) {
val position = intent?.getLongExtra("extra_position", -1) ?: -1
val duration = intent?.getLongExtra("extra_duration", -1) ?: -1
Log.d("VLC", "Position: $position, Duration: $duration")
updateDurationAndPosition(position, duration)
}
}

View file

@ -0,0 +1,62 @@
package com.lagradost.cloudstream3.actions.temp
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.core.net.toUri
import com.lagradost.cloudstream3.USER_AGENT
import com.lagradost.cloudstream3.actions.OpenInAppAction
import com.lagradost.cloudstream3.ui.result.LinkLoadingResult
import com.lagradost.cloudstream3.ui.result.ResultEpisode
import com.lagradost.cloudstream3.ui.result.txt
import com.lagradost.cloudstream3.utils.ExtractorLinkType
// https://www.webvideocaster.com/integrations
class WebVideoCastPackage: OpenInAppAction(
txt("Web Video Cast"),
"com.instantbits.cast.webvideo"
) {
override val oneSource = true
override val sourceTypes = setOf(
ExtractorLinkType.VIDEO,
ExtractorLinkType.DASH,
ExtractorLinkType.M3U8
)
override fun putExtra(
context: Context,
intent: Intent,
video: ResultEpisode,
result: LinkLoadingResult,
index: Int?
) {
val link = result.links[index ?: 0]
intent.apply {
setDataAndType(Uri.parse(link.url), "video/*")
val title = video.name ?: video.headerName
putExtra("subs", result.subs.map { it.url.toUri() }.toTypedArray())
putExtra("title", title)
video.poster?.let { putExtra("poster", it) }
val headers = Bundle().apply {
if (link.referer.isNotBlank())
putString("Referer", link.referer)
putString("User-Agent", USER_AGENT)
for ((key, value) in link.headers) {
putString(key, value)
}
}
putExtra("android.media.intent.extra.HTTP_HEADERS", headers)
putExtra("secure_uri", true)
}
}
override fun onResult(activity: Activity, intent: Intent?) = Unit
}

View file

@ -0,0 +1,67 @@
package com.lagradost.cloudstream3.actions.temp.fcast
import android.content.Context
import com.lagradost.cloudstream3.AcraApplication.Companion.getActivity
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.USER_AGENT
import com.lagradost.cloudstream3.actions.VideoClickAction
import com.lagradost.cloudstream3.ui.result.LinkLoadingResult
import com.lagradost.cloudstream3.ui.result.ResultEpisode
import com.lagradost.cloudstream3.ui.result.txt
import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.ExtractorLinkType
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog
class FcastAction: VideoClickAction() {
override val name = txt("Fcast to device")
override val oneSource = true
override val sourceTypes = setOf(
ExtractorLinkType.VIDEO,
ExtractorLinkType.DASH,
ExtractorLinkType.M3U8
)
override fun shouldShow(context: Context?, video: ResultEpisode?) = FcastManager.currentDevices.isNotEmpty()
override fun runAction(
context: Context?,
video: ResultEpisode,
result: LinkLoadingResult,
index: Int?
) {
val link = result.links.getOrNull(index ?: 0) ?: return
val devices = FcastManager.currentDevices.toList()
context?.getActivity()?.showBottomDialog(
devices.map { it.name },
-1,
txt(R.string.player_settings_select_cast_device).asString(context),
false,
{}) {
val position = getViewPos(video.id)?.position
castTo(devices.getOrNull(it), link, position)
}
}
private fun castTo(device: PublicDeviceInfo?, link: ExtractorLink, position: Long?) {
val host = device?.host ?: return
FcastSession(host).use { session ->
session.sendMessage(
Opcode.Play,
PlayMessage(
"video/*",
link.url,
time = position?.let { it / 1000.0 },
headers = mapOf(
"referer" to link.referer,
"user-agent" to USER_AGENT
) + link.headers
)
)
}
}
}

View file

@ -1,4 +1,4 @@
package com.lagradost.cloudstream3.utils.fcast
package com.lagradost.cloudstream3.actions.temp.fcast
import android.content.Context
import android.net.nsd.NsdManager

View file

@ -1,4 +1,4 @@
package com.lagradost.cloudstream3.utils.fcast
package com.lagradost.cloudstream3.actions.temp.fcast
import android.util.Log
import androidx.annotation.WorkerThread

View file

@ -1,4 +1,4 @@
package com.lagradost.cloudstream3.utils.fcast
package com.lagradost.cloudstream3.actions.temp.fcast
// See https://gitlab.com/futo-org/fcast/-/wikis/Protocol-version-1
enum class Opcode(val value: Byte) {

View file

@ -9,6 +9,8 @@ import com.lagradost.cloudstream3.utils.ExtractorApi
import com.lagradost.cloudstream3.utils.extractorApis
import android.util.Log
import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.actions.VideoClickAction
import com.lagradost.cloudstream3.actions.VideoClickActionHolder
const val PLUGIN_TAG = "PluginInstance"
@ -52,6 +54,18 @@ abstract class Plugin {
extractorApis.add(element)
}
/**
* Used to register VideoClickAction instances
* @param element VideoClickAction you want to register
*/
fun registerVideoClickAction(element: VideoClickAction) {
Log.i(PLUGIN_TAG, "Adding ${element.name} VideoClickAction")
element.sourcePlugin = this.filename
synchronized(VideoClickActionHolder.allVideoClickActions) {
VideoClickActionHolder.allVideoClickActions.add(element)
}
}
class Manifest {
@JsonProperty("name")
var name: String? = null

View file

@ -24,6 +24,8 @@ import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
import com.lagradost.cloudstream3.CommonActivity.showToast
import com.lagradost.cloudstream3.MainAPI.Companion.settingsForProvider
import com.lagradost.cloudstream3.MainActivity.Companion.afterPluginsLoadedEvent
import com.lagradost.cloudstream3.actions.VideoClickAction
import com.lagradost.cloudstream3.actions.VideoClickActionHolder
import com.lagradost.cloudstream3.mvvm.debugPrint
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
@ -583,8 +585,13 @@ object PluginManager {
synchronized(APIHolder.allProviders) {
APIHolder.allProviders.removeIf { provider: MainAPI -> provider.sourcePlugin == plugin.filename }
}
extractorApis.removeIf { provider: ExtractorApi -> provider.sourcePlugin == plugin.filename }
synchronized(VideoClickActionHolder.allVideoClickActions) {
VideoClickActionHolder.allVideoClickActions.removeIf { action: VideoClickAction -> action.sourcePlugin == plugin.filename }
}
classLoaders.values.removeIf { v -> v == plugin }
plugins.remove(absolutePath)

View file

@ -3,10 +3,15 @@ package com.lagradost.cloudstream3.ui
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.View.*
import android.widget.*
import android.view.View.GONE
import android.view.View.INVISIBLE
import android.view.View.VISIBLE
import android.widget.AbsListView
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.ListView
import androidx.appcompat.app.AlertDialog
import androidx.media3.common.util.UnstableApi
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.json.JsonMapper
import com.fasterxml.jackson.module.kotlin.kotlinModule
@ -25,7 +30,7 @@ import com.lagradost.cloudstream3.mvvm.Resource
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.mvvm.safeApiCall
import com.lagradost.cloudstream3.sortUrls
import com.lagradost.cloudstream3.ui.player.LoadType
import com.lagradost.cloudstream3.ui.player.LOADTYPE_CHROMECAST
import com.lagradost.cloudstream3.ui.player.RepoLinkGenerator
import com.lagradost.cloudstream3.ui.player.SubtitleData
import com.lagradost.cloudstream3.ui.result.ResultEpisode
@ -298,14 +303,16 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi
val isSuccessful = safeApiCall {
generator.generateLinks(
clearCache = false, type = LoadType.Chromecast,
clearCache = false,
allowedTypes = LOADTYPE_CHROMECAST,
callback = {
it.first?.let { link ->
currentLinks.add(link)
}
}, subtitleCallback = {
currentSubs.add(it)
})
},
isCasting = true)
}
val sortedLinks = sortUrls(currentLinks)

View file

@ -6,6 +6,7 @@ import com.lagradost.cloudstream3.CommonActivity.activity
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.ui.player.PlayerSubtitleHelper.Companion.toSubtitleMimeType
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.ExtractorLinkType
import com.lagradost.cloudstream3.utils.SubtitleUtils.cleanDisplayName
import com.lagradost.cloudstream3.utils.SubtitleUtils.isMatchingSubtitle
import com.lagradost.cloudstream3.utils.VideoDownloadManager.getDownloadFileInfoAndUpdateSettings
@ -57,10 +58,11 @@ class DownloadFileGenerator(
override suspend fun generateLinks(
clearCache: Boolean,
type: LoadType,
sourceTypes: Set<ExtractorLinkType>,
callback: (Pair<ExtractorLink?, ExtractorUri?>) -> Unit,
subtitleCallback: (SubtitleData) -> Unit,
offset: Int
offset: Int,
isCasting: Boolean
): Boolean {
val meta = episodes[currentIndex + offset]

View file

@ -1,6 +1,7 @@
package com.lagradost.cloudstream3.ui.player
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.ExtractorLinkType
class ExtractorLinkGenerator(
private val links: List<ExtractorLink>,
@ -37,15 +38,15 @@ class ExtractorLinkGenerator(
override suspend fun generateLinks(
clearCache: Boolean,
type: LoadType,
sourceTypes: Set<ExtractorLinkType>,
callback: (Pair<ExtractorLink?, ExtractorUri?>) -> Unit,
subtitleCallback: (SubtitleData) -> Unit,
offset: Int
offset: Int,
isCasting: Boolean
): Boolean {
subtitles.forEach(subtitleCallback)
val allowedTypes = type.toSet()
links.forEach {
if(allowedTypes.contains(it.type)) {
if(sourceTypes.contains(it.type)) {
callback.invoke(it to null)
}
}

View file

@ -3,45 +3,25 @@ package com.lagradost.cloudstream3.ui.player
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.ExtractorLinkType
enum class LoadType {
Unknown,
InApp,
InAppDownload,
ExternalApp,
Browser,
Chromecast,
Fcast
}
val LOADTYPE_INAPP = setOf(
ExtractorLinkType.VIDEO,
ExtractorLinkType.DASH,
ExtractorLinkType.M3U8
)
fun LoadType.toSet() : Set<ExtractorLinkType> {
return when(this) {
LoadType.InApp -> setOf(
val LOADTYPE_INAPP_DOWNLOAD = setOf(
ExtractorLinkType.VIDEO,
ExtractorLinkType.M3U8
)
val LOADTYPE_CHROMECAST = setOf(
ExtractorLinkType.VIDEO,
ExtractorLinkType.DASH,
ExtractorLinkType.M3U8
)
LoadType.Browser -> setOf(
ExtractorLinkType.VIDEO,
ExtractorLinkType.DASH,
ExtractorLinkType.M3U8
)
LoadType.InAppDownload -> setOf(
ExtractorLinkType.VIDEO,
ExtractorLinkType.M3U8
)
LoadType.ExternalApp, LoadType.Unknown -> ExtractorLinkType.entries.toSet()
LoadType.Chromecast -> setOf(
ExtractorLinkType.VIDEO,
ExtractorLinkType.DASH,
ExtractorLinkType.M3U8
)
LoadType.Fcast -> setOf(
ExtractorLinkType.VIDEO,
ExtractorLinkType.DASH,
ExtractorLinkType.M3U8
)
}
}
val LOADTYPE_ALL = ExtractorLinkType.entries.toSet()
interface IGenerator {
val hasCache: Boolean
@ -60,9 +40,10 @@ interface IGenerator {
/* not safe, must use try catch */
suspend fun generateLinks(
clearCache: Boolean,
type: LoadType,
sourceTypes: Set<ExtractorLinkType>,
callback: (Pair<ExtractorLink?, ExtractorUri?>) -> Unit,
subtitleCallback: (SubtitleData) -> Unit,
offset: Int = 0,
isCasting: Boolean = false
): Boolean
}

View file

@ -4,6 +4,7 @@ import android.net.Uri
import com.lagradost.cloudstream3.TvType
import com.lagradost.cloudstream3.amap
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.ExtractorLinkType
import com.lagradost.cloudstream3.utils.INFER_TYPE
import com.lagradost.cloudstream3.utils.Qualities
import com.lagradost.cloudstream3.utils.loadExtractor
@ -69,10 +70,11 @@ class LinkGenerator(
override suspend fun generateLinks(
clearCache: Boolean,
type: LoadType,
sourceTypes: Set<ExtractorLinkType>,
callback: (Pair<ExtractorLink?, ExtractorUri?>) -> Unit,
subtitleCallback: (SubtitleData) -> Unit,
offset: Int
offset: Int,
isCasting: Boolean
): Boolean {
links.amap { link ->
if (!extract || !loadExtractor(link.url, referer, {

View file

@ -15,6 +15,7 @@ import com.lagradost.cloudstream3.ui.result.ResultEpisode
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
import com.lagradost.cloudstream3.utils.EpisodeSkip
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.ExtractorLinkType
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
@ -94,7 +95,7 @@ class PlayerGeneratorViewModel : ViewModel() {
if (generator?.hasCache == true && generator?.hasNext() == true) {
safeApiCall {
generator?.generateLinks(
type = LoadType.InApp,
sourceTypes = LOADTYPE_INAPP,
clearCache = false,
callback = {},
subtitleCallback = {},
@ -173,7 +174,7 @@ class PlayerGeneratorViewModel : ViewModel() {
}
}
fun loadLinks(type: LoadType = LoadType.InApp) {
fun loadLinks(sourceTypes: Set<ExtractorLinkType> = LOADTYPE_INAPP) {
Log.i(TAG, "loadLinks")
currentJob?.cancel()
@ -188,7 +189,7 @@ class PlayerGeneratorViewModel : ViewModel() {
// load more data
_loadingLinks.postValue(Resource.Loading())
val loadingState = safeApiCall {
generator?.generateLinks(type = type, clearCache = forceClearCache, callback = {
generator?.generateLinks(sourceTypes = sourceTypes, clearCache = forceClearCache, callback = {
currentLinks.add(it)
// Clone to prevent ConcurrentModificationException
normalSafeApiCall {

View file

@ -1,13 +1,13 @@
package com.lagradost.cloudstream3.ui.player
import android.util.Log
import androidx.media3.common.util.UnstableApi
import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull
import com.lagradost.cloudstream3.APIHolder.unixTime
import com.lagradost.cloudstream3.LoadResponse
import com.lagradost.cloudstream3.ui.APIRepository
import com.lagradost.cloudstream3.ui.result.ResultEpisode
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.ExtractorLinkType
import kotlin.math.max
import kotlin.math.min
@ -75,12 +75,12 @@ class RepoLinkGenerator(
override suspend fun generateLinks(
clearCache: Boolean,
type: LoadType,
allowedTypes: Set<ExtractorLinkType>,
callback: (Pair<ExtractorLink?, ExtractorUri?>) -> Unit,
subtitleCallback: (SubtitleData) -> Unit,
offset: Int
offset: Int,
isCasting: Boolean,
): Boolean {
val allowedTypes = type.toSet()
val index = currentIndex
val current = episodes.getOrNull(index + offset) ?: return false
@ -123,7 +123,7 @@ class RepoLinkGenerator(
val result = APIRepository(
getApiFromNameNull(current.apiName) ?: throw Exception("This provider does not exist")
).loadLinks(current.data,
isCasting = LoadType.Chromecast == type,
isCasting = isCasting,
subtitleCallback = { file ->
val correctFile = PlayerSubtitleHelper.getSubtitleData(file)
if (correctFile.url.isNotEmpty() && !currentSubsUrls.contains(correctFile.url)) {

View file

@ -11,6 +11,7 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.lagradost.cloudstream3.APIHolder.unixTimeMS
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.actions.VideoClickActionHolder
import com.lagradost.cloudstream3.databinding.ResultEpisodeBinding
import com.lagradost.cloudstream3.databinding.ResultEpisodeLargeBinding
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.secondsToReadable
@ -30,9 +31,11 @@ import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
/**
* Ids >= 1000 are reserved for VideoClickActions
* @see VideoClickActionHolder
*/
const val ACTION_PLAY_EPISODE_IN_PLAYER = 1
const val ACTION_PLAY_EPISODE_IN_VLC_PLAYER = 2
const val ACTION_PLAY_EPISODE_IN_BROWSER = 3
const val ACTION_CHROME_CAST_EPISODE = 4
const val ACTION_CHROME_CAST_MIRROR = 5
@ -41,7 +44,6 @@ const val ACTION_DOWNLOAD_EPISODE = 6
const val ACTION_DOWNLOAD_MIRROR = 7
const val ACTION_RELOAD_EPISODE = 8
const val ACTION_COPY_LINK = 9
const val ACTION_SHOW_OPTIONS = 10
@ -52,12 +54,7 @@ const val ACTION_SHOW_DESCRIPTION = 15
const val ACTION_DOWNLOAD_EPISODE_SUBTITLE = 13
const val ACTION_DOWNLOAD_EPISODE_SUBTITLE_MIRROR = 14
const val ACTION_PLAY_EPISODE_IN_WEB_VIDEO = 16
const val ACTION_PLAY_EPISODE_IN_MPV = 17
const val ACTION_PLAY_EPISODE_IN_MPV_YTDL = 20
const val ACTION_MARK_AS_WATCHED = 18
const val ACTION_FCAST = 19
const val TV_EP_SIZE = 400
@ -69,22 +66,10 @@ class EpisodeAdapter(
private val downloadClickCallback: (DownloadClickEvent) -> Unit,
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
companion object {
/**
* @return ACTION_PLAY_EPISODE_IN_PLAYER, ACTION_PLAY_EPISODE_IN_BROWSER or ACTION_PLAY_EPISODE_IN_VLC_PLAYER depending on player settings.
* See array.xml/player_pref_values
**/
fun getPlayerAction(context: Context): Int {
val settingsManager = PreferenceManager.getDefaultSharedPreferences(context)
return when (settingsManager.getInt(context.getString(R.string.player_pref_key), 1)) {
1 -> ACTION_PLAY_EPISODE_IN_PLAYER
2 -> ACTION_PLAY_EPISODE_IN_VLC_PLAYER
3 -> ACTION_PLAY_EPISODE_IN_BROWSER
4 -> ACTION_PLAY_EPISODE_IN_WEB_VIDEO
5 -> ACTION_PLAY_EPISODE_IN_MPV
6 -> ACTION_PLAY_EPISODE_IN_MPV_YTDL
else -> ACTION_PLAY_EPISODE_IN_PLAYER
}
val playerPref = settingsManager.getString(context.getString(R.string.player_default_key), "")
return VideoClickActionHolder.uniqueIdToId(playerPref) ?: ACTION_PLAY_EPISODE_IN_PLAYER
}
}

View file

@ -2,16 +2,11 @@ package com.lagradost.cloudstream3.ui.result
import android.app.Activity
import android.content.*
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.text.format.Formatter.formatFileSize
import android.util.Log
import android.widget.Toast
import androidx.annotation.MainThread
import androidx.appcompat.app.AlertDialog
import androidx.core.content.FileProvider
import androidx.core.net.toUri
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
@ -30,37 +25,28 @@ import com.lagradost.cloudstream3.LoadResponse.Companion.getAniListId
import com.lagradost.cloudstream3.LoadResponse.Companion.getMalId
import com.lagradost.cloudstream3.LoadResponse.Companion.isMovie
import com.lagradost.cloudstream3.LoadResponse.Companion.readIdFromString
import com.lagradost.cloudstream3.MainActivity.Companion.MPV
import com.lagradost.cloudstream3.MainActivity.Companion.MPV_COMPONENT
import com.lagradost.cloudstream3.MainActivity.Companion.MPV_PACKAGE
import com.lagradost.cloudstream3.MainActivity.Companion.MPV_YTDL
import com.lagradost.cloudstream3.MainActivity.Companion.MPV_YTDL_COMPONENT
import com.lagradost.cloudstream3.MainActivity.Companion.MPV_YTDL_PACKAGE
import com.lagradost.cloudstream3.MainActivity.Companion.VLC
import com.lagradost.cloudstream3.MainActivity.Companion.VLC_COMPONENT
import com.lagradost.cloudstream3.MainActivity.Companion.VLC_PACKAGE
import com.lagradost.cloudstream3.MainActivity.Companion.WEB_VIDEO
import com.lagradost.cloudstream3.MainActivity.Companion.WEB_VIDEO_CAST_PACKAGE
import com.lagradost.cloudstream3.actions.VideoClickActionHolder
import com.lagradost.cloudstream3.metaproviders.SyncRedirector
import com.lagradost.cloudstream3.mvvm.*
import com.lagradost.cloudstream3.syncproviders.AccountManager
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.secondsToReadable
import com.lagradost.cloudstream3.syncproviders.SyncAPI
import com.lagradost.cloudstream3.syncproviders.providers.Kitsu
import com.lagradost.cloudstream3.syncproviders.providers.SimklApi
import com.lagradost.cloudstream3.ui.APIRepository
import com.lagradost.cloudstream3.ui.WatchType
import com.lagradost.cloudstream3.ui.download.DOWNLOAD_NAVIGATE_TO
import com.lagradost.cloudstream3.ui.player.GeneratorPlayer
import com.lagradost.cloudstream3.ui.player.IGenerator
import com.lagradost.cloudstream3.ui.player.LoadType
import com.lagradost.cloudstream3.ui.player.LOADTYPE_ALL
import com.lagradost.cloudstream3.ui.player.LOADTYPE_CHROMECAST
import com.lagradost.cloudstream3.ui.player.LOADTYPE_INAPP
import com.lagradost.cloudstream3.ui.player.LOADTYPE_INAPP_DOWNLOAD
import com.lagradost.cloudstream3.ui.player.RepoLinkGenerator
import com.lagradost.cloudstream3.ui.player.SubtitleData
import com.lagradost.cloudstream3.ui.result.EpisodeAdapter.Companion.getPlayerAction
import com.lagradost.cloudstream3.ui.subtitles.SubtitlesFragment
import com.lagradost.cloudstream3.utils.*
import com.lagradost.cloudstream3.utils.AppContextUtils.getNameFull
import com.lagradost.cloudstream3.utils.AppContextUtils.isAppInstalled
import com.lagradost.cloudstream3.utils.AppContextUtils.isConnectedToChromecast
import com.lagradost.cloudstream3.utils.AppContextUtils.setDefaultFocus
import com.lagradost.cloudstream3.utils.AppContextUtils.sortSubs
@ -69,6 +55,7 @@ import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
import com.lagradost.cloudstream3.utils.Coroutines.ioWork
import com.lagradost.cloudstream3.utils.Coroutines.ioWorkSafe
import com.lagradost.cloudstream3.utils.Coroutines.main
import com.lagradost.cloudstream3.utils.DataStore.setKey
import com.lagradost.cloudstream3.utils.DataStoreHelper.deleteBookmarkedData
import com.lagradost.cloudstream3.utils.DataStoreHelper.getAllBookmarkedData
import com.lagradost.cloudstream3.utils.DataStoreHelper.getAllFavorites
@ -96,12 +83,7 @@ import com.lagradost.cloudstream3.utils.DataStoreHelper.setVideoWatchState
import com.lagradost.cloudstream3.utils.DataStoreHelper.updateSubscribedData
import com.lagradost.cloudstream3.utils.UIHelper.clipboardHelper
import com.lagradost.cloudstream3.utils.UIHelper.navigate
import com.lagradost.cloudstream3.utils.fcast.FcastManager
import com.lagradost.cloudstream3.utils.fcast.FcastSession
import com.lagradost.cloudstream3.utils.fcast.Opcode
import com.lagradost.cloudstream3.utils.fcast.PlayMessage
import kotlinx.coroutines.*
import java.io.File
import java.util.concurrent.TimeUnit
/** This starts at 1 */
@ -803,7 +785,7 @@ class ResultViewModel2 : ViewModel() {
val generator = RepoLinkGenerator(listOf(episode))
val currentLinks = mutableSetOf<ExtractorLink>()
val currentSubs = mutableSetOf<SubtitleData>()
generator.generateLinks(clearCache = false, LoadType.Chromecast, callback = {
generator.generateLinks(clearCache = false, allowedTypes = LOADTYPE_INAPP_DOWNLOAD, callback = {
it.first?.let { link ->
currentLinks.add(link)
}
@ -954,7 +936,7 @@ class ResultViewModel2 : ViewModel() {
isVisible: Boolean = true
) {
if (activity == null) return
loadLinks(result, isVisible = isVisible, LoadType.Chromecast) { data ->
loadLinks(result, isVisible = isVisible, sourceTypes = LOADTYPE_CHROMECAST, isCasting = true) { data ->
startChromecast(activity, result, data.links, data.subs, 0)
}
}
@ -1264,7 +1246,7 @@ class ResultViewModel2 : ViewModel() {
_loadedLinks.postValue(null)
}
private fun postPopup(text: UiText, options: List<UiText>, callback: suspend (Int?) -> Unit) {
fun postPopup(text: UiText, options: List<UiText>, callback: suspend (Int?) -> Unit) {
_selectPopup.postValue(
SelectPopup.SelectText(
text,
@ -1300,8 +1282,9 @@ class ResultViewModel2 : ViewModel() {
private fun loadLinks(
result: ResultEpisode,
isVisible: Boolean,
type: LoadType,
sourceTypes: Set<ExtractorLinkType> = LOADTYPE_ALL,
clearCache: Boolean = false,
isCasting: Boolean = false,
work: suspend (CoroutineScope.(LinkLoadingResult) -> Unit)
) {
currentLoadLinkJob?.cancel()
@ -1309,8 +1292,9 @@ class ResultViewModel2 : ViewModel() {
val links = loadLinks(
result,
isVisible = isVisible,
type = type,
clearCache = clearCache
sourceTypes = sourceTypes,
clearCache = clearCache,
isCasting = isCasting
)
if (!this.isActive) return@ioSafe
work(links)
@ -1320,11 +1304,12 @@ class ResultViewModel2 : ViewModel() {
private var currentLoadLinkJob: Job? = null
private fun acquireSingleLink(
result: ResultEpisode,
type: LoadType,
sourceTypes: Set<ExtractorLinkType>,
text: UiText,
callback: (Pair<LinkLoadingResult, Int>) -> Unit,
isCasting: Boolean = false,
callback: (Pair<LinkLoadingResult, Int>) -> Unit
) {
loadLinks(result, isVisible = true, type) { links ->
loadLinks(result, isVisible = true, sourceTypes, isCasting = isCasting) { links ->
// Could not find a better way to do this
val context = AcraApplication.context
postPopup(
@ -1344,7 +1329,7 @@ class ResultViewModel2 : ViewModel() {
text: UiText,
callback: (Pair<LinkLoadingResult, Int>) -> Unit,
) {
loadLinks(result, isVisible = true, type = LoadType.Unknown) { links ->
loadLinks(result, isVisible = true) { links ->
postPopup(
text,
links.subs.map { txt(it.name) })
@ -1357,8 +1342,9 @@ class ResultViewModel2 : ViewModel() {
private suspend fun CoroutineScope.loadLinks(
result: ResultEpisode,
isVisible: Boolean,
type: LoadType,
sourceTypes: Set<ExtractorLinkType> = LOADTYPE_ALL,
clearCache: Boolean = false,
isCasting: Boolean = false
): LinkLoadingResult {
val tempGenerator = RepoLinkGenerator(listOf(result))
@ -1371,15 +1357,19 @@ class ResultViewModel2 : ViewModel() {
}
try {
updatePage()
tempGenerator.generateLinks(clearCache, type, { (link, _) ->
tempGenerator.generateLinks(clearCache,
allowedTypes = sourceTypes,
callback = { (link, _) ->
if (link != null) {
links += link
updatePage()
}
}, { sub ->
},
subtitleCallback = { sub ->
subs += sub
updatePage()
})
},
isCasting = isCasting)
} catch (e: Exception) {
logError(e)
} finally {
@ -1389,185 +1379,11 @@ class ResultViewModel2 : ViewModel() {
return LinkLoadingResult(sortUrls(links), sortSubs(subs))
}
private fun launchActivity(
activity: Activity?,
resumeApp: MainActivity.Companion.ResultResume,
id: Int? = null,
work: suspend (Intent.(Activity) -> Unit)
): Job? {
val act = activity ?: return null
return CoroutineScope(Dispatchers.IO).launch {
try {
resumeApp.launch(id) {
work(act)
}
} catch (t: Throwable) {
logError(t)
main {
if (t is ActivityNotFoundException) {
showToast(txt(R.string.app_not_found_error), Toast.LENGTH_LONG)
} else {
showToast(t.toString(), Toast.LENGTH_LONG)
}
}
}
}
}
private fun playInWebVideo(
activity: Activity?,
link: ExtractorLink,
title: String?,
posterUrl: String?,
subtitles: List<SubtitleData>
) = launchActivity(activity, WEB_VIDEO) {
setDataAndType(Uri.parse(link.url), "video/*")
putExtra("subs", subtitles.map { it.url.toUri() }.toTypedArray())
title?.let { putExtra("title", title) }
posterUrl?.let { putExtra("poster", posterUrl) }
val headers = Bundle().apply {
if (link.referer.isNotBlank())
putString("Referer", link.referer)
putString("User-Agent", USER_AGENT)
for ((key, value) in link.headers) {
putString(key, value)
}
}
putExtra("android.media.intent.extra.HTTP_HEADERS", headers)
putExtra("secure_uri", true)
}
private fun playWithMpv(
activity: Activity?,
id: Int,
link: ExtractorLink,
subtitles: List<SubtitleData>,
resume: Boolean = true,
) = launchActivity(activity, MPV, id) {
putExtra("subs", subtitles.map { it.url.toUri() }.toTypedArray())
putExtra("subs.name", subtitles.map { it.name }.toTypedArray())
putExtra("subs.filename", subtitles.map { it.name }.toTypedArray())
setDataAndType(Uri.parse(link.url), "video/*")
component = MPV_COMPONENT
putExtra("secure_uri", true)
putExtra("return_result", true)
val position = getViewPos(id)?.position
if (resume && position != null)
putExtra("position", position.toInt())
}
private fun playWithMpvYtdl(
activity: Activity?,
id: Int,
link: ExtractorLink,
subtitles: List<SubtitleData>,
resume: Boolean = true,
) = launchActivity(activity, MPV_YTDL, id) {
putExtra("subs", subtitles.map { it.url.toUri() }.toTypedArray())
putExtra("subs.name", subtitles.map { it.name }.toTypedArray())
putExtra("subs.filename", subtitles.map { it.name }.toTypedArray())
setDataAndType(Uri.parse(link.url), "video/*")
component = MPV_YTDL_COMPONENT
putExtra("secure_uri", true)
putExtra("return_result", true)
val position = getViewPos(id)?.position
if (resume && position != null)
putExtra("position", position.toInt())
}
// https://wiki.videolan.org/Android_Player_Intents/
private fun playWithVlc(
activity: Activity?,
data: LinkLoadingResult,
id: Int,
resume: Boolean = true,
// if it is only a single link then resume works correctly
singleFile: Boolean? = null
) = launchActivity(activity, VLC, id) { act ->
addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
addFlags(Intent.FLAG_GRANT_PREFIX_URI_PERMISSION)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
val outputDir = act.cacheDir
if (singleFile ?: (data.links.size == 1)) {
setDataAndType(data.links.first().url.toUri(), "video/*")
} else {
val outputFile = File.createTempFile("mirrorlist", ".m3u8", outputDir)
var text = "#EXTM3U"
// With subtitles it doesn't work for no reason :(
// for (sub in data.subs) {
// text += "\n#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"${sub.name}\",DEFAULT=NO,AUTOSELECT=NO,FORCED=NO,LANGUAGE=\"${sub.name}\",URI=\"${sub.url}\""
// }
for (link in data.links) {
text += "\n#EXTINF:, ${link.name}\n${link.url}"
}
outputFile.writeText(text)
setDataAndType(
FileProvider.getUriForFile(
act,
act.applicationContext.packageName + ".provider",
outputFile
), "video/*"
)
}
val position = if (resume) {
getViewPos(id)?.position ?: 0L
} else {
1L
}
// Component no longer safe to use in A13 for VLC
// https://code.videolan.org/videolan/vlc-android/-/issues/2776
// This will likely need to be updated once VLC fixes their documentation.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
component = VLC_COMPONENT
}
putExtra("from_start", !resume)
putExtra("position", position)
}
fun handleAction(click: EpisodeClickEvent) =
viewModelScope.launchSafe {
handleEpisodeClickEvent(click)
}
data class ExternalApp(
val packageString: String,
val name: Int,
val action: Int,
)
private val apps = listOf(
ExternalApp(
VLC_PACKAGE,
R.string.player_settings_play_in_vlc,
ACTION_PLAY_EPISODE_IN_VLC_PLAYER
), ExternalApp(
WEB_VIDEO_CAST_PACKAGE,
R.string.player_settings_play_in_web,
ACTION_PLAY_EPISODE_IN_WEB_VIDEO
),
ExternalApp(
MPV_PACKAGE,
R.string.player_settings_play_in_mpv,
ACTION_PLAY_EPISODE_IN_MPV
),
ExternalApp(
MPV_YTDL_PACKAGE,
R.string.player_settings_play_in_mpvytdl,
ACTION_PLAY_EPISODE_IN_MPV_YTDL
)
)
fun releaseEpisodeSynopsis() {
_episodeSynopsis.postValue(null)
}
@ -1576,6 +1392,7 @@ class ResultViewModel2 : ViewModel() {
when (click.action) {
ACTION_SHOW_OPTIONS -> {
val options = mutableListOf<Pair<UiText, Int>>()
if (activity?.isConnectedToChromecast() == true) {
options.addAll(
listOf(
@ -1585,29 +1402,10 @@ class ResultViewModel2 : ViewModel() {
)
}
if (FcastManager.currentDevices.isNotEmpty()) {
options.add(
txt(R.string.player_settings_play_in_fcast) to ACTION_FCAST
)
}
options.add(txt(R.string.episode_action_play_in_app) to ACTION_PLAY_EPISODE_IN_PLAYER)
for (app in apps) {
if (activity?.isAppInstalled(app.packageString) == true) {
options.add(
txt(
R.string.episode_action_play_in_format,
txt(app.name)
) to app.action
)
}
}
options.addAll(
listOf(
txt(R.string.episode_action_play_in_browser) to ACTION_PLAY_EPISODE_IN_BROWSER,
txt(R.string.episode_action_copy_link) to ACTION_COPY_LINK,
txt(R.string.episode_action_auto_download) to ACTION_DOWNLOAD_EPISODE,
txt(R.string.episode_action_download_mirror) to ACTION_DOWNLOAD_MIRROR,
txt(R.string.episode_action_download_subtitle) to ACTION_DOWNLOAD_EPISODE_SUBTITLE_MIRROR,
@ -1615,6 +1413,10 @@ class ResultViewModel2 : ViewModel() {
)
)
options.addAll(
VideoClickActionHolder.makeOptionMap(activity, click.data)
)
// Do not add mark as watched on movies
if (!listOf(TvType.Movie, TvType.AnimeMovie).contains(click.data.tvType)) {
val isWatched =
@ -1716,7 +1518,7 @@ class ResultViewModel2 : ViewModel() {
val response = currentResponse ?: return
acquireSingleLink(
click.data,
LoadType.InAppDownload,
LOADTYPE_INAPP_DOWNLOAD,
txt(R.string.episode_action_download_mirror)
) { (result, index) ->
ioSafe {
@ -1746,7 +1548,7 @@ class ResultViewModel2 : ViewModel() {
loadLinks(
click.data,
isVisible = false,
type = LoadType.InApp,
LOADTYPE_INAPP,
clearCache = true
)
}
@ -1759,139 +1561,18 @@ class ResultViewModel2 : ViewModel() {
ACTION_CHROME_CAST_MIRROR -> {
acquireSingleLink(
click.data,
LoadType.Chromecast,
txt(R.string.episode_action_chromecast_mirror)
LOADTYPE_CHROMECAST,
txt(R.string.episode_action_chromecast_mirror),
isCasting = true
) { (result, index) ->
startChromecast(activity, click.data, result.links, result.subs, index)
}
}
ACTION_FCAST -> {
val devices = FcastManager.currentDevices.toList()
postPopup(
txt(R.string.player_settings_select_cast_device),
devices.map { txt(it.name) }) { index ->
if (index == null) return@postPopup
val device = devices.getOrNull(index)
acquireSingleLink(
click.data,
LoadType.Fcast,
txt(R.string.episode_action_cast_mirror)
) { (result, index) ->
val host = device?.host ?: return@acquireSingleLink
val link = result.links.getOrNull(index) ?: return@acquireSingleLink
FcastSession(host).use { session ->
session.sendMessage(
Opcode.Play,
PlayMessage(
link.type.getMimeType(),
link.url,
headers = mapOf(
"referer" to link.referer,
"user-agent" to USER_AGENT
) + link.headers
)
)
}
}
}
}
ACTION_PLAY_EPISODE_IN_BROWSER -> acquireSingleLink(
click.data,
LoadType.Browser,
txt(R.string.episode_action_play_in_browser)
) { (result, index) ->
try {
val i = Intent(Intent.ACTION_VIEW)
i.data = Uri.parse(result.links[index].url)
activity?.startActivity(i)
} catch (e: Exception) {
logError(e)
}
}
ACTION_COPY_LINK -> {
acquireSingleLink(
click.data,
LoadType.ExternalApp,
txt(R.string.episode_action_copy_link)
) { (result, index) ->
val link = result.links[index]
clipboardHelper(txt(link.name), link.url)
}
}
ACTION_CHROME_CAST_EPISODE -> {
startChromecast(activity, click.data)
}
ACTION_PLAY_EPISODE_IN_VLC_PLAYER -> {
loadLinks(click.data, isVisible = true, LoadType.ExternalApp) { links ->
if (links.links.isEmpty()) {
showToast(R.string.no_links_found_toast, Toast.LENGTH_SHORT)
return@loadLinks
}
playWithVlc(
activity,
links,
click.data.id
)
}
}
ACTION_PLAY_EPISODE_IN_WEB_VIDEO -> acquireSingleLink(
click.data,
LoadType.Chromecast,
txt(
R.string.episode_action_play_in_format,
txt(R.string.player_settings_play_in_web)
)
) { (result, index) ->
playInWebVideo(
activity,
result.links[index],
click.data.name ?: click.data.headerName,
click.data.poster,
result.subs
)
}
ACTION_PLAY_EPISODE_IN_MPV -> acquireSingleLink(
click.data,
LoadType.Chromecast,
txt(
R.string.episode_action_play_in_format,
txt(R.string.player_settings_play_in_mpv)
)
) { (result, index) ->
playWithMpv(
activity,
click.data.id,
result.links[index],
result.subs
)
}
ACTION_PLAY_EPISODE_IN_MPV_YTDL -> acquireSingleLink(
click.data,
LoadType.Chromecast,
txt(
R.string.episode_action_play_in_format,
txt(R.string.player_settings_play_in_mpvytdl)
)
) { (result, index) ->
playWithMpvYtdl(
activity,
click.data.id,
result.links[index],
result.subs
)
}
ACTION_PLAY_EPISODE_IN_PLAYER -> {
val data = currentResponse?.syncData?.toList() ?: emptyList()
val list =
@ -1907,7 +1588,7 @@ class ResultViewModel2 : ViewModel() {
if (currentResponse?.type == TvType.CustomMedia) {
generator?.generateLinks(
clearCache = true,
LoadType.Unknown,
LOADTYPE_ALL,
callback = {},
subtitleCallback = {})
} else {
@ -1933,6 +1614,35 @@ class ResultViewModel2 : ViewModel() {
// Kinda dirty to reload all episodes :(
reloadEpisodes()
}
else -> {
val action = VideoClickActionHolder.getActionById(click.action) ?: return
activity?.setKey("last_click_action", action.uniqueId())
if (action.oneSource) {
acquireSingleLink(
click.data,
action.sourceTypes,
action.name
) { (result, index) ->
action.runAction(
activity,
click.data,
result,
index
)
}
} else {
loadLinks(click.data, isVisible = true, action.sourceTypes) { links ->
action.runAction(
activity,
click.data,
links,
null
)
}
}
}
}
}
@ -2040,7 +1750,7 @@ class ResultViewModel2 : ViewModel() {
isResponseRequired = false
)
if (map.isNullOrEmpty()) return@argamap
updateEpisodes = DubStatus.values().map { dubStatus ->
updateEpisodes = DubStatus.entries.map { dubStatus ->
val current =
this.episodes[dubStatus]?.mapIndexed { index, episode ->
episode.apply {

View file

@ -6,6 +6,7 @@ import android.view.View
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceManager
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.actions.VideoClickActionHolder
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.ui.settings.Globals.EMULATOR
import com.lagradost.cloudstream3.ui.settings.Globals.PHONE
@ -155,10 +156,17 @@ class SettingsPlayer : PreferenceFragmentCompat() {
return@setOnPreferenceClickListener true
}
getPref(R.string.player_pref_key)?.setOnPreferenceClickListener {
val prefNames = resources.getStringArray(R.array.player_pref_names)
val prefValues = resources.getIntArray(R.array.player_pref_values)
val current = settingsManager.getInt(getString(R.string.player_pref_key), 1)
getPref(R.string.player_default_key)?.setOnPreferenceClickListener {
val players = VideoClickActionHolder.getPlayers(activity)
val prefNames = buildList {
add(getString(R.string.player_settings_play_in_app))
addAll(players.map { it.name.asStringNull(activity) ?: it.javaClass.simpleName })
}
val prefValues = buildList {
add("")
addAll(players.map { it.uniqueId() })
}
val current = settingsManager.getString(getString(R.string.player_default_key), "") ?: ""
activity?.showBottomDialog(
prefNames.toList(),
@ -166,7 +174,7 @@ class SettingsPlayer : PreferenceFragmentCompat() {
getString(R.string.player_pref),
true,
{}) {
settingsManager.edit().putInt(getString(R.string.player_pref_key), prefValues[it]).apply()
settingsManager.edit().putString(getString(R.string.player_default_key), prefValues[it]).apply()
}
return@setOnPreferenceClickListener true
}

View file

@ -221,9 +221,7 @@
<string name="video_disk_description">بسبِب أعطال إزا نحط على مستوى عالي كتير على الأجهزة يللي م بتساع كتير، متل تلفزيون \"أندرويد\".</string>
<string name="others">شي غير</string>
<string name="skip_update">أفي هيدا التجديد</string>
<string name="episode_action_copy_link">نسوخ الرابط</string>
<string name="episode_action_play_in_app">مَشي بال آپ</string>
<string name="episode_action_play_in_browser">مشي بمتصفح الويب</string>
<string name="dns_pref_summary">مفيد لتجاوز المنع من مزود خدمة الإنترنت</string>
<string name="tv_series_singular">مسلسل</string>
<string name="video_aspect_ratio_resize">غير الحجم</string>
@ -390,10 +388,8 @@
<string name="update_notification_failed">م قدرنا ننزل الإصدار الجديد تبع الآپ</string>
<string name="extension_authors">المؤلفين</string>
<string name="plugin_singular">إضافة</string>
<string name="player_settings_play_in_web">كاست ڤيديو ع الوَب</string>
<string name="duplicate_title">معقول يكون موجود أصلًا</string>
<string name="subscription_list_name">مشتركينلو</string>
<string name="player_settings_play_in_browser">متصفح الوَب</string>
<string name="all_languages_preference">كل اللغات</string>
<string name="uppercase_all_subtitles">دايمًا كتوب ب أحرف كاپيتال، A بدل a</string>
<string name="player_pref">مشغل الڤيديو المفضل</string>
@ -422,7 +418,6 @@
<string name="setup_done">خلصت</string>
<string name="clear_history">محي السجل</string>
<string name="sort_updated_old">تجَدَد (من قديم للجديد)</string>
<string name="player_settings_play_in_vlc">\"ڤي أل سي ميديا پلاير\"</string>
<string name="quality_cam_rip">كاميرا</string>
<string name="quality_webrip">وَب</string>
<string name="sort_alphabetical_z">أبجديًا (من الياء للألف)</string>
@ -504,7 +499,6 @@
<string name="upload_sync">مزامنة</string>
<string name="safe_mode_crash_info">شوفو معلومات عن المشكلة</string>
<string name="extension_types">مدعوم</string>
<string name="player_settings_play_in_mpv">\"أم پي ڤي\"</string>
<string name="subtitle_offset">ظبّط وقت الترجمة</string>
<string name="skip_type_mixed_op">افتتاح مختلط</string>
<string name="trailer">مقطع دعائي</string>
@ -627,7 +621,6 @@
<string name="episode_upcoming_format" formatted="true">رح ينزل ب %s</string>
<string name="next_season_episode_format" formatted="true">الحلقة ال %2$d من الجزء ال%1$d رح تنزل ب</string>
<string name="episode_action_cast_mirror">كاست مراية</string>
<string name="player_settings_play_in_fcast">إف كاست</string>
<string name="player_settings_select_cast_device">نقي جهاز الكاست</string>
<string name="cs3wiki">ويكي \"كلود ستريم\"</string>
<string name="pref_category_accounts">أكونتات</string>
@ -669,6 +662,5 @@
\n%s</string>
<string name="preview_seekbar">صورة زغيرة مع التقريب وال تبعيد</string>
<string name="preview_seekbar_desc">بت حط صورة زغير من الڤيديو إنت و عم بت قرب أو ترجع بال ڤيديو</string>
<string name="player_settings_play_in_mpvytdl">MPV YTDL</string>
<string name="no_subtitles_loaded">بعد مش معمول لود لولا ترجمة</string>
</resources>

View file

@ -233,8 +233,6 @@
<string name="episode_action_chromecast_mirror">مرآة كروم كاست</string>
<string name="episode_action_play_in_app">تشغيل في التطبيق</string>
<string name="episode_action_play_in_format">%s تشغيل في</string>
<string name="episode_action_play_in_browser">تشغيل في الويب</string>
<string name="episode_action_copy_link">نسخ الرابط</string>
<string name="episode_action_auto_download">التحميل التلقائي</string>
<string name="episode_action_download_mirror">تحميل بجودات مختلفة</string>
<string name="episode_action_reload_links">إعادة تحميل الروابط</string>
@ -464,10 +462,6 @@
<string name="action_open_play">فتح(تشغيل)</string>
<string name="season_format">%1$s %2$d%3$s</string>
<string name="plugins_updated" formatted="true">المكونات الإضافية المحدثة %d</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="player_settings_play_in_web">اسقاط فيديو الويب</string>
<string name="player_settings_play_in_browser">متصفح الإنترنت</string>
<string name="skip_type_format" formatted="true">تخطي %s</string>
<string name="skip_type_op">الافتتاح</string>
<string name="skip_type_ed">النهاية</string>
@ -653,7 +647,6 @@
<string name="episode_upcoming_format" formatted="true">قادم خلال %s</string>
<string name="next_season_episode_format" formatted="true">سيتم إصدار الحلقة %1$d من الموسم %2$d في</string>
<string name="episode_action_cast_mirror">مرآة البث</string>
<string name="player_settings_play_in_fcast">بث ف</string>
<string name="player_settings_select_cast_device">حدد جهاز البث</string>
<string name="cs3wiki">CloudStream ويكي</string>
<string name="pref_category_security">إعدادات الأمان</string>
@ -695,6 +688,5 @@
\n%s</string>
<string name="preview_seekbar">معاينة شريط البحث</string>
<string name="preview_seekbar_desc">تمكين معاينة الصورة المصغرة على شريط البحث</string>
<string name="player_settings_play_in_mpvytdl">MPV YTDL</string>
<string name="no_subtitles_loaded">لم يتم تحميل أي ترجمات بعد</string>
</resources>

View file

@ -311,11 +311,9 @@
<string name="others">اخرون</string>
<string name="skip_update">تخطي هذا التحديث</string>
<string name="jsdelivr_proxy_summary">.قد يتسبب في تأخير التحديثات لبضعة أيام .jsDelivr باستخدام GitHubيتجاوز حظر</string>
<string name="episode_action_copy_link">انسخ الرابط</string>
<string name="asian_drama">الدرامات الآسيوية</string>
<string name="queued">في قائمة الانتظار</string>
<string name="episode_action_play_in_app">افتح في التطبيق</string>
<string name="episode_action_play_in_browser">افتح في المتصفح</string>
<string name="dns_pref_summary">مفيد لتجاوز حجب مزودي خدمة الإنترنت</string>
<string name="tv_series_singular">مسلسل</string>
<string name="rating">تقييم</string>

View file

@ -89,7 +89,6 @@
<string name="setup_done">সম্পূৰ্ণ</string>
<string name="view_public_repositories_button_short">সৰ্বজনীন তালিকা</string>
<string name="stop">বন্ধ কৰক</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="battery_dialog_title">বেটাৰী অপ্টিমাইজেচন নিষ্ক্ৰিয় কৰক</string>
<string name="subscription_list_name">সদস্যতা গ্ৰহণ কৰা</string>
<string name="qualities">গুণসমূহ</string>
@ -302,8 +301,6 @@
<string name="episode_action_cast_mirror">কাষ্ট মিৰৰ</string>
<string name="show_dub">ডাব ছপা</string>
<string name="episode_action_play_in_format">প্লে %s ত</string>
<string name="episode_action_play_in_browser">ব্ৰাউজাৰত প্লে কৰক</string>
<string name="episode_action_copy_link">লিংক কপি কৰক</string>
<string name="episode_action_auto_download">স্বয়ংক্ৰিয় ডাউনলোড</string>
<string name="episode_action_download_mirror">ডাউনলোড মিৰৰ</string>
<string name="show_sub">সাব ছপা</string>
@ -498,10 +495,6 @@
<string name="hls_playlist">HLS প্লেলিস্ট</string>
<string name="player_pref">পছন্দৰ ভিডিঅ\' প্লেয়াৰ</string>
<string name="player_settings_play_in_app">আভ্যন্তৰীণ প্লেয়াৰ</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="player_settings_play_in_web">ৱেব ভিডিঅ\' কাষ্ট</string>
<string name="player_settings_play_in_fcast">Fcast</string>
<string name="player_settings_play_in_browser">ৱেব ব্ৰাউজাৰ</string>
<string name="player_settings_select_cast_device">কাষ্ট ডিভাইচ চয়ন কৰক</string>
<string name="skip_type_mixed_ed">মিশ্ৰিত সমাপ্তি</string>
<string name="skip_type_mixed_op">মিশ্ৰিত উদ্‌ঘাটনী</string>
@ -650,7 +643,6 @@
<string name="device_pin_error_message">ডিভাইচ পিন ক\'ড পোৱা নাই, স্থানীয় প্ৰমাণীকৰণ চেষ্টা কৰক</string>
<string name="device_pin_expired_message">পিন ক\'ডৰ মেয়াদ শেষ হৈছে!</string>
<string name="device_pin_counter_text">ক\'ড মেয়াদ শেষ হব %1$dm %2$ds</string>
<string name="player_settings_play_in_mpvytdl">MPV YTDL</string>
<string name="preview_seekbar">সীকবৰ প্ৰিভিউ</string>
<string name="preview_seekbar_desc">সীকবৰত প্ৰিভিউ থাম্বনেইল সক্ৰিয় কৰক</string>
<string name="play_from_beginning_img_des">আৰম্ভৰ পৰা প্লে কৰক</string>

View file

@ -238,8 +238,6 @@
<string name="episode_action_chromecast_mirror">Chromecast огледало</string>
<string name="episode_action_play_in_app">Пусни в приложението</string>
<string name="episode_action_play_in_format">Пусни в %s</string>
<string name="episode_action_play_in_browser">Пусни в браузър</string>
<string name="episode_action_copy_link">Копирай връзка</string>
<string name="episode_action_auto_download">Автоматично изтегляне</string>
<string name="episode_action_download_mirror">Изтегляне на огледало</string>
<string name="episode_action_reload_links">Презареждане на връзки</string>
@ -443,10 +441,6 @@
<string name="hls_playlist">HLS плейлист</string>
<string name="player_pref">Предпочитан видео плеър</string>
<string name="player_settings_play_in_app">Вътрешен плеър</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="player_settings_play_in_web">Уеб видео предаване</string>
<string name="player_settings_play_in_browser">Уеб браузър</string>
<string name="app_not_found_error">Приложението не е намерено</string>
<string name="automatic_plugin_download">Автоматично изтегли добавки</string>
<string name="all_languages_preference">Всички езици</string>

View file

@ -230,7 +230,6 @@
<string name="automatic_plugin_download_mode_title">প্লাগইন ডাউনলোড ফিল্টার করতে মোড নির্বাচন করুন</string>
<string name="links_reloaded_toast">লিঙ্ক পুনরায় লোড হয়েছে</string>
<string name="switch_account">সুইচ অ্যাকাউন্ট</string>
<string name="episode_action_play_in_browser">ব্রাউজারে প্লে করুন</string>
<string name="legal_notice">দাবিত্যাগ</string>
<string name="asian_drama_singular">এশিয়ান ড্রামা</string>
<string name="video_source">সোর্স</string>
@ -274,7 +273,6 @@
<string name="torrent_singular">টরেন্ট</string>
<string name="episode_action_chromecast_episode">এপিসোড ক্রোমকাস্ট করুন</string>
<string name="episode_action_play_in_format">প্লে হচ্ছে %s সময়ের মধ্যে</string>
<string name="episode_action_copy_link">লিঙ্ক কপি করুন</string>
<string name="episode_action_auto_download">স্বয়ংক্রিয় ডাউনলোড</string>
<string name="show_title">টাইটেল</string>
<string name="android_tv_interface_off_seek_settings">প্লেয়ার দেখা যাচ্ছে - সিকের পরিমাণ</string>

View file

@ -235,8 +235,6 @@
<string name="episode_action_chromecast_mirror">Alternativa pelo Chromecast</string>
<string name="episode_action_play_in_app">Assistir no App</string>
<string name="episode_action_play_in_format">Assistir no %s</string>
<string name="episode_action_play_in_browser">Assistir no navegador</string>
<string name="episode_action_copy_link">Copiar link</string>
<string name="episode_action_auto_download">Auto download</string>
<string name="episode_action_download_mirror">Baixar por servidor alternativo</string>
<string name="episode_action_reload_links">Recarregar links</string>
@ -538,16 +536,13 @@
<string name="start">Começar</string>
<string name="extension_types">Suportado</string>
<string name="extension_status">Status</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="skip_type_mixed_op">Abrindo mistura</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="apply_on_restart">Reinicie o aplicativo para ver as alterações.</string>
<string name="safe_mode_crash_info">Visualização info de crash</string>
<string name="audio_tracks">Faixas de áudio</string>
<string name="sort_updated_new">Adicionado em (novo para antigo)</string>
<string name="video_tracks">Faixas de video</string>
<string name="pref_category_subtitles">Legendas</string>
<string name="player_settings_play_in_browser">Navegador</string>
<string name="is_adult">18+</string>
<string name="pref_category_links">Links</string>
<string name="pref_category_player_features">Funcionalidades do Player</string>
@ -563,7 +558,6 @@
<string name="other_singular">Vídeo</string>
<string name="pref_category_android_tv">Android TV</string>
<string name="wifi">Wi-Fi</string>
<string name="player_settings_play_in_web">Lista de videos da web</string>
<string name="unable_to_inflate">A interface de usuário não foi gerada corretamente. Isto se trata de um bug importante e deve ser reportado imediatamente %s</string>
<string name="pref_category_ui_features">Características da interface de usuário</string>
<string name="category_provider_test">Provedor de teste</string>
@ -642,7 +636,6 @@
<string name="reset_btn">Redefinir</string>
<string name="episode_upcoming_format" formatted="true">Próximos em %s</string>
<string name="next_season_episode_format" formatted="true">Temporada %1$d Episódio %2$d será lançado em</string>
<string name="player_settings_play_in_fcast">Fcast</string>
<string name="player_settings_select_cast_device">Selecione o dispositivo de transmissão</string>
<string name="episode_action_cast_mirror">Espelhar transmissão</string>
<string name="cs3wiki">CloudStream Wiki</string>
@ -685,6 +678,5 @@
<string name="deselect_all">Desmarcar todos</string>
<string name="preview_seekbar_desc">Ativar visualização de miniatura na barra de busca</string>
<string name="preview_seekbar">Visualização da barra de busca</string>
<string name="player_settings_play_in_mpvytdl">MPV + YTDL</string>
<string name="no_subtitles_loaded">Ainda não há legendas carregadas</string>
</resources>

View file

@ -223,8 +223,6 @@
<string name="episode_action_chromecast_mirror">Chromecast jako zrcadlo</string>
<string name="episode_action_play_in_app">Přehrát v aplikace</string>
<string name="episode_action_play_in_format">Přehrát ve %s</string>
<string name="episode_action_play_in_browser">Přehrát v prohlížeči</string>
<string name="episode_action_copy_link">Zkopírovat odkaz</string>
<string name="episode_action_auto_download">Automaticky stáhnout</string>
<string name="episode_action_download_mirror">Zrcadlo stahování</string>
<string name="episode_action_reload_links">Obnovit odkazy</string>
@ -400,8 +398,6 @@
<string name="view_public_repositories_button_short">Veřejný seznam</string>
<string name="uppercase_all_subtitles">Velká písmena u všech titulků</string>
<string name="hls_playlist">Playlist HLS</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="player_settings_play_in_web">Webové vysílání videa</string>
<string name="app_not_found_error">Aplikace nenalezena</string>
<string name="skip_type_format" formatted="true">Přeskočit %s</string>
<string name="skip_type_op">Úvod</string>
@ -451,13 +447,11 @@
<string name="extension_description">Popis</string>
<string name="extension_status">Stav</string>
<string name="extension_install_first">Nejprve nainstalujte rozšíření</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="skip_type_mixed_ed">Smíšený konec</string>
<string name="extension_language">Jazyk</string>
<string name="player_settings_play_in_app">Interní přehrávač</string>
<string name="skip_type_recap">Rekapitulace</string>
<string name="clear_history">Vymazat historii</string>
<string name="player_settings_play_in_browser">Webový prohlížeč</string>
<string name="all_languages_preference">Všechny jazyky</string>
<string name="skip_type_mixed_op">Smíšený úvod</string>
<string name="skip_type_creddits">Poděkování</string>
@ -645,7 +639,6 @@
<string name="episode_upcoming_format" formatted="true">Vychází %s</string>
<string name="next_season_episode_format" formatted="true">Epizoda %2$d ze série %1$d bude vydána za</string>
<string name="episode_action_cast_mirror">Vysílat zrcadlení</string>
<string name="player_settings_play_in_fcast">Fcast</string>
<string name="player_settings_select_cast_device">Vyberte zařízení k vysílání</string>
<string name="cs3wiki">CloudStream Wiki</string>
<string name="pref_category_security">Zabezpečení</string>
@ -687,6 +680,5 @@
<string name="delete_format" formatted="true">Odstranit (%1$d | %2$s)</string>
<string name="preview_seekbar">Náhled v liště přehrávače</string>
<string name="preview_seekbar_desc">Povolit náhled miniatur na liště přehrávače</string>
<string name="player_settings_play_in_mpvytdl">MPV YTDL</string>
<string name="no_subtitles_loaded">Zatím nenačteny žádné titulky</string>
</resources>

View file

@ -241,8 +241,6 @@
<string name="storage_error">Downloadfehler, bitte überprüfen sie die Speicherberechtigungen</string>
<string name="episode_action_chromecast_episode">Chromecast-Episode</string>
<string name="episode_action_play_in_format">In %s wiedergeben</string>
<string name="episode_action_play_in_browser">In Browser wiedergeben</string>
<string name="episode_action_copy_link">Link kopieren</string>
<string name="episode_action_auto_download">Auto-Download</string>
<string name="episode_action_download_mirror">Alternativer Download</string>
<string name="episode_action_reload_links">Links neu laden</string>
@ -437,10 +435,6 @@
<string name="hls_playlist">HLS-Playlist</string>
<string name="player_pref">Bevorzugter Videoplayer</string>
<string name="player_settings_play_in_app">Interner Player</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="player_settings_play_in_web">Web Video Cast</string>
<string name="player_settings_play_in_browser">Browser</string>
<string name="app_not_found_error">App nicht gefunden</string>
<string name="all_languages_preference">Alle Sprachen</string>
<string name="skip_type_format" formatted="true">Überspringen %s</string>
@ -618,7 +612,6 @@
<string name="hide_player_control_names_key" translatable="false">hide_player_control_names_key</string>
<string name="next_season_episode_format" formatted="true">Staffel %1$d Episode %2$d wird veröffentlicht in</string>
<string name="episode_upcoming_format" formatted="true">Wird veröffentlicht in %s</string>
<string name="player_settings_play_in_fcast">Fcast</string>
<string name="pref_category_security">Sicherheit</string>
<string name="pref_category_accounts">Konten</string>
<string name="open_downloaded_repo">Repository öffnen</string>

View file

@ -194,8 +194,6 @@
<string name="episode_action_chromecast_episode">Chromecast επεισόδιο</string>
<string name="episode_action_play_in_app">Αναπαραγωγή εντός της εφαρμογής</string>
<string name="episode_action_play_in_format">Αναπαραγωγή σε %s</string>
<string name="episode_action_play_in_browser">Αναπαραγωγή στον περιηγητή</string>
<string name="episode_action_copy_link">Αντιγραφή συνδέσμου</string>
<string name="episode_action_auto_download">Αυτόματη λήψη</string>
<string name="episode_action_download_mirror">Λήψη mirror</string>
<string name="episode_action_reload_links">Επαναφόρτωση συνδέσμων</string>
@ -359,10 +357,6 @@
<string name="hls_playlist">HLS Playlist</string>
<string name="player_pref">Προτεινόμενο πρόγραμμα αναπαραγωγής</string>
<string name="player_settings_play_in_app">Ενσωματωμένο πρόγραμμα αναπαραγωγής</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="player_settings_play_in_web">Web Video Cast</string>
<string name="player_settings_play_in_browser">Περιηγητής</string>
<string name="app_not_found_error">Η εφαρμογή δεν βρέθηκε</string>
<string name="app_dub_sub_episode_text_format" formatted="true">%1$s Επ %2$d</string>
<string name="next_episode_format" formatted="true">Το επεισόδιο %d θα κυκλοφορήσει σε</string>
@ -580,7 +574,6 @@
<string name="android_tv_interface_on_seek_settings_summary">Δευτερόλεπτα Σκιπ όταν φαίνεται ο αναπαραγωγέας (πλειερ)</string>
<string name="test_extensions">Δοκιμή όλων των παροχών</string>
<string name="test_extensions_summary">Αυτό το τεστ προορίζεται μόνο για τους προγραμματιστές και δε επαληθείει ούτε απορρίπτει την λειτουργία οποιουδήποτε παρόχου.</string>
<string name="player_settings_play_in_fcast">Fcast</string>
<string name="player_settings_select_cast_device">Επιλογή συσκευής για αναμετάδοση</string>
<string name="clipboard_permission_error">Πρόβλημα στην πρόσβαση στο Clipboard, Παρακαλώ προσπαθήστε ξανά.</string>
<string name="clipboard_unknown_error">Πρόβλημα στην αντιγραφή , Παρακαλούμε αντιγράψτε το logcat και επικοινωνήστε με την υποστήριξη.</string>

View file

@ -152,32 +152,6 @@
<item>@string/show_title_key</item>
</array>
<array name="episode_long_click_options">
<item>@string/episode_action_chromecast_episode</item>
<item>@string/episode_action_chromecast_mirror</item>
<item>@string/episode_action_play_in_app</item>
<item>@string/episode_action_play_in_format</item>
<item>@string/episode_action_play_in_browser</item>
<item>@string/episode_action_copy_link</item>
<item>@string/episode_action_auto_download</item>
<item>@string/episode_action_download_mirror</item>
<item>@string/episode_action_download_subtitle</item>
<item>@string/episode_action_reload_links</item>
</array>
<array name="episode_long_click_options_values">
<item>4</item>
<item>5</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>9</item>
<item>6</item>
<item>7</item>
<item>13</item>
<item>8</item>
</array>
<array name="app_layout">
<item>@string/automatic</item>
<item>@string/phone_layout</item>

View file

@ -57,11 +57,7 @@
<string name="double_tap_to_seek_amount_settings">Cantidad de búsquedas del reproductor (segundos)</string>
<string name="use_system_brightness_settings_des">Use el brillo del sistema en el reproductor de la app en lugar de una superposición oscura</string>
<string name="limit_title_rez">Resolución del reproductor de video</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="category_player">Reproductor</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="player_settings_play_in_web">Web Video Cast</string>
<string name="player_settings_play_in_browser">Navegador Web</string>
<string name="autoplay_next_settings_des">Iniciar el siguiente episodio cuando el actual termine</string>
<string name="video_skip_op">Omitir Intro</string>
<string name="skip_type_op">Apertura</string>
@ -78,9 +74,7 @@
<string name="episode_sync_settings">Actualizar progreso de lo visto</string>
<string name="episode_action_chromecast_mirror">Duplicar en Chromecast</string>
<string name="no_episodes_found">No se encontraron Episodios</string>
<string name="episode_action_play_in_browser">Reproducir en Navegador</string>
<string name="episode_action_play_in_format">Reproducir en %s</string>
<string name="episode_action_copy_link">Copiar enlace</string>
<string name="episode_action_auto_download">Descarga automática</string>
<string name="episode_action_download_mirror">Descargar desde servidor alternativo</string>
<string name="episode_action_reload_links">Recargar enlaces</string>
@ -621,7 +615,6 @@
<string name="episode_upcoming_format" formatted="true">Próximamente en %s</string>
<string name="next_season_episode_format" formatted="true">La temporada %1$d y el episodio %2$d se estrenarán en</string>
<string name="player_settings_select_cast_device">Seleccionar el dispositivo para transmitir</string>
<string name="player_settings_play_in_fcast">Fcast</string>
<string name="episode_action_cast_mirror">Espejo de transmisión</string>
<string name="cs3wiki">Wiki de CloudStream</string>
<string name="pref_category_security">Seguridad</string>
@ -663,6 +656,5 @@
\n%s</string>
<string name="preview_seekbar_desc">Activar la previsualización para las miniaturas en la barra de búsqueda</string>
<string name="preview_seekbar">Previsualización de Seekbar</string>
<string name="player_settings_play_in_mpvytdl">MPV YTDL</string>
<string name="no_subtitles_loaded">Aún no hay subtítulos cargados</string>
</resources>

View file

@ -111,8 +111,6 @@
<string name="episode_action_chromecast_mirror">Miroir Chromecast</string>
<string name="episode_action_play_in_app">Lecture dans l\'application</string>
<string name="episode_action_play_in_format">Lecture dans %s</string>
<string name="episode_action_play_in_browser">Lecture dans le navigateur</string>
<string name="episode_action_copy_link">Copier le lien</string>
<string name="episode_action_auto_download">Téléchargement automatique</string>
<string name="episode_action_download_mirror">Télécharger depuis le miroir</string>
<string name="episode_action_reload_links">Recharger les liens</string>
@ -140,7 +138,7 @@
<string name="dns_pref">DNS avec HTTPS</string>
<string name="display_subbed_dubbed_settings">Afficher les animés en Anglais (Dub) / sous-titrés</string>
<string name="phone_layout">Disposition en mode téléphone</string>
<string name="app_dub_sub_episode_text_format">%1$s Episode %2$d</string>
<string name="app_dub_sub_episode_text_format">episode_action_copy_link</string>
<string name="rated_format" formatted="true">Note: %.1f</string>
<string name="resize_zoom">Zoom</string>
<string name="resize_fit">Adapter à l\'écran</string>
@ -430,12 +428,10 @@
<string name="extension_install_first">Installer l\'extension d\'abord</string>
<string name="hls_playlist">Playlist HLS</string>
<string name="player_pref">Lecteur vidéo préféré</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="skip_type_mixed_ed">Fin mitigée</string>
<string name="skip_type_mixed_op">Introduction mitigée</string>
<string name="update_notification_installing">Installation de la mise a jour de l\'application…</string>
<string name="update_notification_failed">Impossible d\'installer la nouvelle version de l\'application</string>
<string name="player_settings_play_in_browser">Navigateur Web</string>
<string name="apk_installer_settings_des">Certains téléphones ne supporte pas le nouvel installateur d\'application. Essayez l\'option de l\'ancien installateur si les mises-à-jour ne s\'installe pas.</string>
<string name="previous">Précédent</string>
<string name="skip_setup">Ignorer la configuration</string>
@ -456,7 +452,6 @@
<string name="player_settings_play_in_app">Lecteur interne</string>
<string name="app_not_found_error">Application introuvable</string>
<string name="clipboard_too_large">Trop de texte. Impossible de sauvegarder dans le presse papier.</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="apk_installer_package_installer">Installateur de paquet</string>
<string name="plugin">plugins</string>
<string name="delete_repository_plugins">Cela supprimera également tous les plugins du repository</string>
@ -466,7 +461,6 @@
<string name="extension_language">Langage</string>
<string name="enable_skip_op_from_database_des">Afficher les popups skip pour les intro / fins</string>
<string name="apk_installer_legacy">Ancienne méthode d\'installation</string>
<string name="player_settings_play_in_web">Web Video Cast</string>
<string name="pref_category_links">Liens</string>
<string name="pref_category_gestures">Gestes</string>
<string name="pref_category_player_features">Fonctionnalités du lecteur</string>

View file

@ -114,8 +114,6 @@
<string name="episode_action_chromecast_mirror">क्रोमकास्ट मिरर</string>
<string name="episode_action_play_in_app">एप्प में चलाएं</string>
<string name="episode_action_play_in_format">%s में चलाएं</string>
<string name="episode_action_play_in_browser">Browser में चलाएं</string>
<string name="episode_action_copy_link">लिंक कॉपी करें</string>
<string name="episode_action_auto_download">डाउनलोड करें</string>
<string name="episode_action_download_mirror">मिरर डाउनलोड</string>
<string name="episode_action_reload_links">लिंक दोबारा लोड करें</string>

View file

@ -253,8 +253,6 @@
<string name="episode_action_chromecast_mirror">Chromecast mirror</string>
<string name="episode_action_play_in_app">Pokreni u aplikaciji</string>
<string name="episode_action_play_in_format">Pokreni u %s</string>
<string name="episode_action_play_in_browser">Pokreni u pregledniku</string>
<string name="episode_action_copy_link">Kopiraj poveznicu</string>
<string name="episode_action_auto_download">Automatsko preuzimanje</string>
<string name="episode_action_download_mirror">Preuzmi zrcalo</string>
<string name="episode_action_reload_links">Ponovo učitaj poveznice</string>
@ -461,9 +459,6 @@
<string name="player_pref">Preferirani video player</string>
<string name="player_settings_play_in_app">Interni player</string>
<string name="extension_install_first">Najprije instaliraj proširenje</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="player_settings_play_in_web">Emitiranje na webu</string>
<string name="app_not_found_error">Aplikacija nije pronađena</string>
<string name="all_languages_preference">Svi jezici</string>
<string name="clipboard_too_large">Previše teksta. Nije moguće spremiti u međuspremnik.</string>
@ -495,7 +490,6 @@
<string name="pref_category_defaults">Zadane postavke</string>
<string name="pref_category_looks">Izgledi</string>
<string name="pref_category_ui_features">Značajke</string>
<string name="player_settings_play_in_browser">Web preglednik</string>
<string name="skip_type_format" formatted="true">Preskoči %s</string>
<string name="skip_type_ed">Kraj</string>
<string name="skip_type_recap">Sažetak</string>
@ -646,7 +640,6 @@
<string name="biometric_warning">Vaši CloudStream podaci su sada spremljeni u sigurnosnu kopiju. Iako je vjerojatnost mala, neki se uređaji mogu ponašati drugačije. Ako izgubite pristup aplikaciji, potpuno izbrišite podatke aplikacije i obnovite ih pomoću sigurnosne kopije. Ispričavamo se zbog mogućih neugodnosti.</string>
<string name="next_season_episode_format" formatted="true">Sezona %1$d epizoda %2$d izlazi</string>
<string name="episode_action_cast_mirror">Cast mirror</string>
<string name="player_settings_play_in_fcast">Fcast</string>
<string name="player_settings_select_cast_device">Odaberi uređaj za emitiranje</string>
<string name="cs3wiki">CloudStream Wiki</string>
<string name="pref_category_accounts">Računi</string>
@ -686,6 +679,5 @@
<string name="delete_message_series_only" formatted="true">Stvarno želite trajno izbrisati sve epizode u sljedećoj seriji?
\n
\n%s</string>
<string name="player_settings_play_in_mpvytdl">MPV YTDL</string>
<string name="no_subtitles_loaded">Još nije učitan nijedan titl</string>
</resources>

View file

@ -182,7 +182,6 @@
<string name="documentaries_singular">Dokumentumfilm</string>
<string name="asian_drama_singular">Ázsiai dráma</string>
<string name="episode_action_reload_links">Linkek újratöltése</string>
<string name="episode_action_copy_link">Link másolás</string>
<string name="episode_action_download_mirror">Letöltés mirror</string>
<string name="episode_action_auto_download">Automatikus letöltés</string>
<string name="backup_success">Adatok eltárolva</string>
@ -227,7 +226,6 @@
<string name="episode_action_chromecast_mirror">Chromecast mirror</string>
<string name="episode_action_play_in_app">Lejátszás az alkalmazásban</string>
<string name="episode_action_play_in_format">Lejátszás %s</string>
<string name="episode_action_play_in_browser">Lejátszás böngészőben</string>
<string name="episode_action_download_subtitle">Feliratok letöltése</string>
<string name="reload_error">Újracsatlakozás…</string>
<string name="swipe_to_seek_settings_des">Húzd balra vagy jobbra a videólejátszóban az idő vezérléséhez</string>
@ -352,7 +350,6 @@
<string name="preferred_media_subtext">Mit szeretnél látni</string>
<string name="batch_download_nothing_to_download_format" formatted="true">Minden %s már letöltött</string>
<string name="extension_install_first">Először telepítse a bővítményt</string>
<string name="player_settings_play_in_browser">Webböngésző</string>
<string name="pref_category_looks">Kinézet</string>
<string name="app_layout">Alkalmazás elrendezés</string>
<string name="upload_sync">Szinkronizálás</string>
@ -368,7 +365,6 @@
<string name="download_all_plugins_from_repo">Töltse le az összes bővítményt ebből a tárolóból?</string>
<string name="safe_mode_title">Biztonságos mód bekapcsolva</string>
<string name="extension_size">Méret</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="app_not_found_error">Alkalmazás nem található</string>
<string name="apk_installer_package_installer">PackageInstaller</string>
<string name="sort_by">Rendezés e szerint</string>
@ -403,7 +399,6 @@
<string name="subtitles_raised">Emelt</string>
<string name="quality_hd">HD</string>
<string name="hls_playlist">HLS lejátszási lista</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="update_notification_failed">Nem sikerült telepíteni az alkalmazás új verzióját</string>
<string name="authenticated_user" formatted="true">%s hitelesítve</string>
<string name="subtitles_outline">Körvonal</string>
@ -528,7 +523,6 @@
<string name="referer">Hivatkozó (opcionális)</string>
<string name="no_plugins_found_error">Nem találhatóak pluginek a repóban</string>
<string name="no_repository_found_error">Repó nem található, ellenőrizze a címet vagy próbálja VPN-el</string>
<string name="player_settings_play_in_web">Web Videó Cast</string>
<string name="skip_type_format" formatted="true">%s kihagyása</string>
<string name="enable_skip_op_from_database_des">A kihagyási felugró ablakok mutatása nyitás/zárás esetén</string>
<string name="set_default">Alapbeállítás</string>

View file

@ -221,8 +221,6 @@
<string name="episode_action_chromecast_mirror">Mirror Chromecast</string>
<string name="episode_action_play_in_app">Putar di aplikasi</string>
<string name="episode_action_play_in_format">Putar di %s</string>
<string name="episode_action_play_in_browser">Putar di browser</string>
<string name="episode_action_copy_link">Salin tautan</string>
<string name="episode_action_auto_download">Download otomatis</string>
<string name="episode_action_download_mirror">Download mirror</string>
<string name="episode_action_reload_links">Muat ulang tautan</string>
@ -442,8 +440,6 @@
<string name="extension_language">Bahasa</string>
<string name="player_pref">Pemutar video utama</string>
<string name="player_settings_play_in_app">Pemutar Bawaan</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="batch_download_finish_format" formatted="true">Terunduh %1$d %2$s</string>
<string name="batch_download_start_format" formatted="true">Memulai mengunduh %1$d %2$s…</string>
<string name="safe_mode_description">Semua fitur tambahkan dimatikan karena crash, untuk memudahkanmu mencari penyebab crash.</string>
@ -495,9 +491,7 @@
<string name="no">Tidak</string>
<string name="update_notification_installing">Memasang pembaruan…</string>
<string name="update_notification_failed">Tidak dapat memasang versi terbaru</string>
<string name="player_settings_play_in_browser">Web browser</string>
<string name="app_not_found_error">Aplikasi tidak ditemukan</string>
<string name="player_settings_play_in_web">Web Video Cast</string>
<string name="clear_history">Hapus Riwayat</string>
<string name="enable_skip_op_from_database_des">Tampilkan popup untuk skip sesi pembuka/akhir</string>
<string name="update_notification_downloading">Mengunduh pembaruan…</string>
@ -643,7 +637,6 @@
<string name="episode_upcoming_format" formatted="true">Akan datang di %s</string>
<string name="episode_action_cast_mirror">Cermin Cast</string>
<string name="player_settings_select_cast_device">Pilih perangkat cast</string>
<string name="player_settings_play_in_fcast">Fcast</string>
<string name="cs3wiki">CloudStream Wiki</string>
<string name="pref_category_security">Keamanan</string>
<string name="pref_category_accounts">Akun</string>

View file

@ -243,8 +243,6 @@
<string name="episode_action_chromecast_mirror">Mirror Chromecast</string>
<string name="episode_action_play_in_app">Riproduci in app</string>
<string name="episode_action_play_in_format">Riproduci in %s</string>
<string name="episode_action_play_in_browser">Riproduci nel browser</string>
<string name="episode_action_copy_link">Copia link</string>
<string name="episode_action_auto_download">Download</string>
<string name="episode_action_download_mirror">Mirror download</string>
<string name="episode_action_reload_links">Aggiorna link</string>
@ -448,10 +446,6 @@
<string name="hls_playlist">Playlist HLS</string>
<string name="player_pref">Video player preferito</string>
<string name="player_settings_play_in_app">Player interno</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="player_settings_play_in_web">Cast Web Video</string>
<string name="player_settings_play_in_browser">Web browser</string>
<string name="app_not_found_error">App non trovata</string>
<string name="all_languages_preference">Tutte le lingue</string>
<string name="skip_type_format" formatted="true">Salta %s</string>
@ -642,7 +636,6 @@
<string name="next_season_episode_format" formatted="true">L\'episodio %2$d della stagione %1$d uscirà tra</string>
<string name="episode_action_cast_mirror">Mirror cast</string>
<string name="player_settings_select_cast_device">Seleziona dispositivo per cast</string>
<string name="player_settings_play_in_fcast">Fcast</string>
<string name="cs3wiki">Wiki di CloudStream</string>
<string name="pref_category_accounts">Conti</string>
<string name="pref_category_security">Sicurezza</string>
@ -683,6 +676,5 @@
\n%s</string>
<string name="preview_seekbar">Anteprima barra di ricerca</string>
<string name="preview_seekbar_desc">Abilita miniatura di anteprima sulla barra di ricerca</string>
<string name="player_settings_play_in_mpvytdl">MPV YTDL</string>
<string name="no_subtitles_loaded">Nessun sottotitolo caricato</string>
</resources>

View file

@ -168,7 +168,6 @@
<string name="asian_drama_singular">דרמה אסייתית</string>
<string name="episode_action_chromecast_episode">כרומקאסט את הפרק</string>
<string name="episode_action_chromecast_mirror">כרומקאסט את המראה</string>
<string name="episode_action_play_in_browser">נגן בדפדפן</string>
<string name="show_sub">תווית כתוביות</string>
<string name="poster_ui_settings">החלף רכיבי ממשק משתמש בפוסטר</string>
<string name="video_skip_op">דלג על הפתיח</string>
@ -326,7 +325,6 @@
<string name="storage_error">שגיאת הורדה, בדוק הרשאות אחסון</string>
<string name="episode_action_play_in_app">נגן באפליקציה</string>
<string name="episode_action_play_in_format">נגן ב %s</string>
<string name="episode_action_copy_link">העתק קישור</string>
<string name="episode_action_auto_download">הורדה אוטומטית</string>
<string name="episode_action_reload_links">טען מחדש קישורים</string>
<string name="show_hd">תווית איכות</string>
@ -431,7 +429,6 @@
<string name="batch_download_nothing_to_download_format" formatted="true">כל %s כבר הורד</string>
<string name="extension_authors">מחברים</string>
<string name="extension_language">שפה</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="skip_type_creddits">קרדיטים</string>
<string name="sort">מיין</string>
<string name="select_library">בחר ספרייה</string>
@ -445,8 +442,6 @@
<string name="download_all_plugins_from_repo">הורד את כל התוספים ממאגר זה?</string>
<string name="audio_tracks">רצועות שמע</string>
<string name="tracks">מסלולים</string>
<string name="player_settings_play_in_web">Web Video Cast</string>
<string name="player_settings_play_in_browser">דפדפן אינטרנט</string>
<string name="safe_mode_description">כל התוספים נכבו עקב התרסקות כדי לעזור לך למצוא את האחד הגורם לצרות.</string>
<string name="apk_installer_package_installer">מוריד החבילות</string>
<string name="plugins_updated" formatted="true">עודכן %d תוספים</string>
@ -479,7 +474,6 @@
<string name="hls_playlist">פלייליסט HLS</string>
<string name="player_pref">נגן וידאו מועדף</string>
<string name="player_settings_play_in_app">נגן פנימי</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="app_not_found_error">האפליקציה לא נמצאה</string>
<string name="all_languages_preference">כל השפות</string>
<string name="skip_type_format" formatted="true">דלג %s</string>

View file

@ -144,9 +144,6 @@
<string name="status_completed">完成</string>
<string name="status_ongoing">進行中</string>
<string name="normal">デフォルト</string>
<string name="player_settings_play_in_browser">ウェブブラウザ</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="extension_language">言語</string>
<string name="extension_authors">作成者</string>
<string name="extension_size">サイズ</string>

View file

@ -186,8 +186,6 @@
<string name="episode_action_chromecast_mirror">Chromecast 미러링</string>
<string name="episode_action_play_in_app">앱에서 재생</string>
<string name="episode_action_play_in_format">%s에서 재생</string>
<string name="episode_action_play_in_browser">브라우저에서 재생</string>
<string name="episode_action_copy_link">링크 복사</string>
<string name="episode_action_auto_download">자동 다운로드</string>
<string name="episode_action_download_mirror">다운로드 미러</string>
<string name="episode_action_reload_links">링크 새로고침</string>
@ -445,7 +443,6 @@
<string name="extension_description">소개</string>
<string name="extension_types">유형</string>
<string name="extension_install_first">먼저 확장 프로그램을 설치하세요</string>
<string name="player_settings_play_in_browser">웹 브라우저</string>
<string name="app_not_found_error">앱을 찾을 수 없음</string>
<string name="all_languages_preference">모든 언어</string>
<string name="skip_type_format" formatted="true">건너뛰기 %s</string>
@ -482,11 +479,8 @@
\n파일이 제거될 때까지 시작 시 확장 프로그램을 로드하지 않습니다.</string>
<string name="hls_playlist">HLS 재생목록</string>
<string name="player_settings_play_in_app">내부 플레이어</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="player_pref">선호하는 동영상 플레이어</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="select_library">라이브러리 선택</string>
<string name="player_settings_play_in_web">웹 동영상 캐스트</string>
<string name="empty_library_logged_in_message">이 목록이 비어 있습니다. 다른 목록으로 전환해 보세요.</string>
<string name="filler" formatted="true">필러</string>
<string name="play_livestream_button">라이브 스트리밍 재생</string>
@ -579,7 +573,6 @@
<string name="auto_rotate_video">자동 회전</string>
<string name="mobile_data">모바일 데이터</string>
<string name="disable">사용 불가능</string>
<string name="player_settings_play_in_fcast">fcast</string>
<string name="player_settings_select_cast_device">캐스트 장치 선택</string>
<string name="clipboard_unknown_error">복사하는 중 오류가 발생했습니다. 로그캣을 복사하고 문의하십시오.</string>
<string name="action_unsubscribe">구독 취소</string>

View file

@ -163,10 +163,8 @@
<string name="sync_score">Įvertinta</string>
<string name="skip_update">Praleisti šį atnaujinimą</string>
<string name="pref_category_actions">Veiksmai</string>
<string name="episode_action_copy_link">Kopijuoti nuorodą</string>
<string name="episode_action_play_in_app">Paleisti programoje</string>
<string name="upload_sync">Sinchronizuoti</string>
<string name="episode_action_play_in_browser">Paleisti naršyklėje</string>
<string name="remove_site_pref">Pašalinti puslapį</string>
<string name="episode_action_reload_links">Perkrauti nuorodos</string>
<string name="disable">Išjungti</string>
@ -192,7 +190,6 @@
<string name="mobile_data">Mobilūs duomenys</string>
<string name="example_username">šaunusPrisijungimoVardas</string>
<string name="extension_authors">Autoriai</string>
<string name="player_settings_play_in_browser">Naršyklė</string>
<string name="all_languages_preference">Visos kalbos</string>
<string name="quality_4k">4K</string>
<string name="batch_download_start_format" formatted="true">Pradėta siųsti %1$d %2$s…</string>
@ -206,7 +203,6 @@
<string name="example_lang_name">Kalbos kodas (lt)</string>
<string name="setup_done">Baigta</string>
<string name="clear_history">Išvalyti istoriją</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="edit">Redaguoti</string>
<string name="wifi">Wi-Fi</string>
<string name="coming_soon">Greitai būs…</string>
@ -227,7 +223,6 @@
<string name="quality_uhd">UHD</string>
<string name="extension_size">Dydis</string>
<string name="extension_types">Palaikoma</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="example_site_name">ManoŠaunusPuslapis</string>
<string name="trailer">Anonsas</string>
<string name="history">Istorija</string>

View file

@ -241,8 +241,6 @@
<string name="episode_action_chromecast_mirror">Chromecast morror</string>
<string name="episode_action_play_in_app">Palaist aplikācijā</string>
<string name="episode_action_play_in_format">Atskaņot uekšā %s</string>
<string name="episode_action_play_in_browser">Atskaņot internetā</string>
<string name="episode_action_copy_link">Kopēt linku</string>
<string name="episode_action_auto_download">Automātiski ielādēt</string>
<string name="episode_action_download_mirror">Ielādēt spoguli</string>
<string name="episode_action_reload_links">Pārlādēt saites</string>
@ -437,8 +435,6 @@
<string name="hls_playlist">HLS atskaņošanas saraksts</string>
<string name="player_pref">Vēlamais video atskaņotājs</string>
<string name="player_settings_play_in_app">Iekšējais atskaņotājs</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="player_settings_play_in_web">Web video apraide</string>
<string name="app_not_found_error">Aplikācijs nav atrasta</string>
<string name="all_languages_preference">Visas valodas</string>
<string name="skip_type_ed">Beigas</string>
@ -513,8 +509,6 @@
<string name="setup_extensions_subtext">Lejupielādējiet to vietņu sarakstu, kuras vēlaties izmantot</string>
<string name="extension_install_first">Vispirms instalējiet paplašinājumu</string>
<string name="skip_type_op">Atvēršana</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="player_settings_play_in_browser">Interneta mekletājs</string>
<string name="skip_type_intro">Sākums</string>
<string name="skip_type_format" formatted="true">Izlaist %s</string>
<string name="action_remove_from_watched">Noņemt no skatītajiem</string>

View file

@ -164,8 +164,6 @@
<string name="episode_action_chromecast_mirror">Огледало на Chromecastr</string>
<string name="episode_action_play_in_app">Пушти во апликацијата</string>
<string name="episode_action_play_in_format">Пушти на %s</string>
<string name="episode_action_play_in_browser">Пушти на прелистувач</string>
<string name="episode_action_copy_link">Копирај линк</string>
<string name="episode_action_auto_download">Авто превземање</string>
<string name="episode_action_download_mirror">Превземи Mirror</string>
<string name="episode_action_reload_links">Вчитај повторно врски</string>
@ -297,7 +295,6 @@
<string name="android_tv_interface_off_seek_settings_summary">Износот на барањето што се користи кога плеерот е скриен</string>
<string name="episode_action_download_subtitle">Преземи преводи</string>
<string name="view_public_repositories_button_short">Јавна листа</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="apk_installer_package_installer">Инсталатор на пакети</string>
<string name="ova_singular">ОВА</string>
<string name="category_updates">Ажурирање и резервна копија</string>
@ -425,7 +422,6 @@
<string name="sync_total_episodes_none">/??</string>
<string name="example_email">hello@world.com</string>
<string name="go_forward_30">+30</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="restart">Рестартирај</string>
<string name="cartoons_singular">Цртан филм</string>
<string name="batch_download_start_format" formatted="true">Почна да презема %1$d %2$s…</string>
@ -448,7 +444,6 @@
<string name="quality_cam_rip">Камера</string>
<string name="quality_cam_hd">Камера</string>
<string name="quality_sdr">SDR</string>
<string name="player_settings_play_in_browser">Веб-прелистувач</string>
<string name="app_not_found_error">Апликацијата не е пронајдена</string>
<string name="example_username">Корисничко име</string>
<string name="open_with">Отвори со</string>
@ -488,7 +483,6 @@
<string name="safe_mode_description">Сите екстензии беа исклучени поради пад за да ви помогнат да ја пронајдете онаа што предизвикува проблеми.</string>
<string name="extension_rating" formatted="true">Оцена: %s</string>
<string name="extension_size">Големина</string>
<string name="player_settings_play_in_web">Веб-видео Cast</string>
<string name="all_languages_preference">Сите јазици</string>
<string name="clear_history">Исчисти историја</string>
<string name="action_mark_as_watched">Обележи како гледано</string>
@ -611,7 +605,6 @@
<string name="biometric_warning">Сега е направена резервна копија на вашите податоци на CloudStream. Иако можноста за ова е многу мала, сите уреди можат да се однесуваат поинаку. Во ретки случаи, кога ќе се заклучите од пристап до апликацијата, целосно исчистете ги податоците на апликацијата и вратете ги од резервна копија. Многу ни е жал за какви било непријатности што произлегуваат од ова.</string>
<string name="reset_btn">Ресетирај</string>
<string name="next_season_episode_format" formatted="true">Сезона %1$d Епизода %2$d ќе биде објавена за</string>
<string name="player_settings_play_in_fcast">Fcast</string>
<string name="player_settings_select_cast_device">Одбери уред да кастираш</string>
<string name="battery_dialog_title">Оневозможи оптимизација на батерија</string>
<string name="biometric_authentication_title">Отклучи CloudStream</string>

View file

@ -151,8 +151,6 @@
<string name="episode_action_chomecast_mirror">Chromecast Mirror</string> -->
<string name="episode_action_play_in_app">ആപ്പിൽ പ്ലേയ് ചെയ്യുക</string>
<string name="episode_action_play_in_format">%sയിൽ പ്ലേയ് ചെയ്യുക</string>
<string name="episode_action_play_in_browser">ബ്രൗസറിൽ പ്ലേയ് ചെയ്യുക</string>
<string name="episode_action_copy_link">ലിങ്ക് പകർത്തുക</string>
<string name="episode_action_auto_download">ഡൌൺലോഡ് ചെയ്യൂ</string>
<string name="episode_action_download_mirror">മിറർ ഡൗണ്ലോഡ്</string>
<string name="episode_action_reload_links">ലിങ്ക്സ് വീണ്ടും ലോഡുചെയ്യുക</string>

View file

@ -2,7 +2,6 @@
<resources>
<string name="all_languages_preference">Semua bahasa</string>
<string name="skip_type_format" formatted="true">Langkau %s</string>
<string name="player_settings_play_in_browser">Pelayar web</string>
<string name="history">Sejarah</string>
<string name="clear_history">Kosongkan sejarah</string>
<string name="skip_type_intro">Pengenalan</string>
@ -232,7 +231,6 @@
<string name="subtitles_raised">Dinaikkan</string>
<string name="provider_languages_tip">Lihat video dalam bahasa-bahasa ini</string>
<string name="normal">Normal</string>
<string name="episode_action_play_in_browser">Main dalam pelayar</string>
<string name="duplicate_add">Tambah</string>
<string name="used_storage">Diguna</string>
<string name="anime">Anime</string>
@ -323,7 +321,6 @@
<string name="episode_action_chromecast_episode">Chromecast episod</string>
<string name="episode_action_play_in_format">Main dalam %s</string>
<string name="storage_error">Muat turun gagal, cek keizinan storan</string>
<string name="episode_action_copy_link">Salin pautan</string>
<string name="episode_action_download_mirror">Muat turun cermin</string>
<string name="episode_action_download_subtitle">Muat turun sari kata</string>
<string name="show_sub">Label sub</string>
@ -449,8 +446,6 @@
<string name="password_pin_authentication_title">Pengesahan Password/PIN</string>
<string name="no_subtitles_loaded">Sari kata belum tetapkan lagi</string>
<string name="extension_types">Disokong</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="player_settings_play_in_fcast">Fcast</string>
<string name="clipboard_permission_error">Ralat tidak dapat akses Clipboard, Sila cuba sekali lagi.</string>
<string name="clipboard_unknown_error">Ralat menyalin, Sila salin logcat dan hubungi penyokong aplikasi.</string>
<string name="test_warning">Amaran</string>
@ -462,8 +457,6 @@
<string name="max">Maks</string>
<string name="download_all_plugins_from_repo">Amaran: CloudStream 3 tidak bertanggungjawab atas penggunaan tambahan pihak ketiga dan tidak memberi sumbang kepada mereka!</string>
<string name="apply_on_restart">Mula semula aplikasi untuk lihat perubahan.</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="player_settings_play_in_mpvytdl">MPV YTDL</string>
<string name="empty_library_logged_in_message">Senarai ini kosong. Sila tukar yang lain.</string>
<string name="mobile_data">Data mudah alih</string>
<string name="action_add_to_favorites">Tambah ke kegemaran</string>

View file

@ -157,8 +157,6 @@
<string name="episode_action_chromecast_mirror">Chromecast ဖန်သားပြင်</string>
<string name="episode_action_play_in_app">အက်ပ်တွင်းဖွင့်</string>
<string name="episode_action_play_in_format">ဖွင့်ရန် %s</string>
<string name="episode_action_play_in_browser">ဘရောက်ဇာထဲမှာ ဖွင့်ရန်</string>
<string name="episode_action_copy_link">လင့်ကူးယူရန်</string>
<string name="episode_action_auto_download">အလိုအလျောက်ဒေါင်းလုဒ်</string>
<string name="episode_action_reload_links">လင့်များကို ပြန်စစ်ရန်</string>
<string name="show_hd">အရည်အသွေး အမှတ်အသား</string>
@ -338,7 +336,6 @@
<string name="previous">နောက်သို့</string>
<string name="plugins_updated" formatted="true">အပ်ဒိတ်လုပ်ပြီး %d ဖြည့်စွက်များ</string>
<string name="plugins_not_downloaded" formatted="true">ဒေါင်းလုဒ်မလုပ်ရသေး: %d</string>
<string name="player_settings_play_in_browser">ဝဘ်ဘရောက်ဇာ</string>
<string name="app_not_found_error">အက်ပ်မတွေ့ပါ</string>
<string name="all_languages_preference">ဘာသာစကားအားလုံး</string>
<string name="skip_type_format" formatted="true">ကျော်ရန် %s</string>
@ -422,9 +419,6 @@
<string name="extension_types">ထောက်ပံ့ထားသော</string>
<string name="extension_language">ဘာသာစကား</string>
<string name="extension_install_first">အဆက်များကိုအရင်သွင်းပါ</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="player_settings_play_in_web">ဝဘ်ထဲတွင်ဖွင့်ရန်</string>
<string name="skip_type_op">အစပိုင်း</string>
<string name="skip_type_ed">အဆုံးပိုင်း</string>
<string name="clear_history">ကြည့်ရှုခဲ့သည်များကိုရှင်းရန်</string>

View file

@ -235,8 +235,6 @@
<string name="episode_action_chromecast_mirror">Chromecast mirror</string>
<string name="episode_action_play_in_app">Speel in app</string>
<string name="episode_action_play_in_format">Speel in %s</string>
<string name="episode_action_play_in_browser">Speel in browser</string>
<string name="episode_action_copy_link">Kopieer link</string>
<string name="episode_action_auto_download">Automatisch downloaden</string>
<string name="episode_action_download_mirror">Download mirror</string>
<string name="episode_action_reload_links">Herlaad Linkss</string>
@ -409,7 +407,6 @@
<string name="plugin_load_fail" formatted="true">Kan %s niet laden</string>
<string name="batch_download_nothing_to_download_format" formatted="true">Alle %s reeds gedownload</string>
<string name="plugin_singular">plugin</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="skip_type_format" formatted="true">Sla %s over</string>
<string name="pref_category_links">Links</string>
<string name="pref_category_app_updates">App updates</string>
@ -468,10 +465,7 @@
<string name="redo_setup_process">Herhaal installatieproces</string>
<string name="automatic_plugin_updates">Automatisch bijwerken plugin</string>
<string name="apk_installer_settings_des">Sommige telefoons ondersteunen het nieuwe installatieprogramma niet. Probeer de oude optie als de updates niet worden geïnstalleerd.</string>
<string name="player_settings_play_in_web">Web Video Cast</string>
<string name="player_settings_play_in_app">Interne speler</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="player_settings_play_in_browser">Web browser</string>
<string name="skip_type_mixed_ed">Gemengd einde</string>
<string name="skip_type_recap">Herhaling</string>
<string name="start">Start</string>

View file

@ -149,8 +149,6 @@
<string name="source_error">Kjeldefeil</string>
<string name="episode_action_play_in_app">Spel av i programmet</string>
<string name="episode_action_play_in_format">Spel av i %s</string>
<string name="episode_action_play_in_browser">Spel av i nettlesaren</string>
<string name="episode_action_copy_link">Kopier lenke</string>
<string name="episode_action_auto_download">Automatisk nedlasting</string>
<string name="episode_action_reload_links">Last inn lenker på nytt</string>
<string name="episode_action_download_subtitle">Last ned undertekstar</string>

View file

@ -171,8 +171,6 @@
<string name="episode_action_chromecast_mirror">Støpt Speil</string>
<string name="episode_action_play_in_app">Spill i appen</string>
<string name="episode_action_play_in_format">Spill i %s</string>
<string name="episode_action_play_in_browser">Spill i nettleseren</string>
<string name="episode_action_copy_link">Kopier link</string>
<string name="episode_action_auto_download">Automatisk nedlasting</string>
<string name="episode_action_download_mirror">Last ned speil</string>
<string name="episode_action_reload_links">Last inn lenker på nytt</string>
@ -250,7 +248,6 @@
<string name="hls_playlist">HLS-spilleliste</string>
<string name="player_pref">Foretrukket videospiller</string>
<string name="player_settings_play_in_app">Intern spiller</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="all_languages_preference">Alle språk</string>
<string name="skip_type_format" formatted="true">Hopp over %s</string>
<string name="clear_history">Tøm historikk</string>
@ -283,7 +280,6 @@
<string name="extension_description">Beskrivelse</string>
<string name="add_account">Legg til konto</string>
<string name="normal">Normal</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="double_tap_to_pause_settings">Dobbelttrykk for å sette på pause</string>
<string name="go_forward_30">+30</string>
<string name="subtitles_shadow">Skygge</string>
@ -416,7 +412,6 @@
<string name="authenticated_user_fail" formatted="true">Kunne ikke logge inn på %s</string>
<string name="uppercase_all_subtitles">Store bokstaver i undertekster</string>
<string name="extension_authors">Utviklere</string>
<string name="player_settings_play_in_browser">Nettleser</string>
<string name="nsfw">Sensurerbart</string>
<string name="quality_webrip">Vev</string>
<string name="network_adress_example">Lenke til strøm</string>
@ -450,7 +445,6 @@
<string name="subtitles_remove_bloat">Fjern unødvendig informasjon fra undertekster</string>
<string name="extras">Ekstra</string>
<string name="subtitles_filter_lang">Filtrer etter foretrukket mediaspråk</string>
<string name="player_settings_play_in_web">Vev-videosending</string>
<string name="skip_type_recap">Tilbakeblikk</string>
<string name="quality_sd">SD</string>
<string name="trailer">Forfilm</string>

View file

@ -28,14 +28,12 @@
<string name="episodes">ଟି ଅଧ୍ୟାୟ</string>
<string name="episode">ଅଧ୍ୟାୟ</string>
<string name="episode_action_play_in_format">%sରେ ଚଲାଅ</string>
<string name="episode_action_play_in_browser">ବ୍ରାଉଜର୍‌ରେ ଚଲାଅ</string>
<string name="episode_action_download_subtitle">ଉପଶୀର୍ଷକ ଡାଉନଲୋଡ୍ କରିବା</string>
<string name="sync_total_episodes_some" formatted="true">/%d</string>
<string name="sync_total_episodes_none">/??</string>
<string name="subscription_episode_released">ଅଧ୍ୟାୟ %d ମୁକ୍ତିଲାଭ କଲା!</string>
<string name="episode_action_auto_download">ସ୍ୱତଃ ଡାଉନଲୋଡ୍</string>
<string name="episode_action_reload_links">ଲିଙ୍କ୍‌ଗୁଡ଼ିକୁ ପୁନଃଲୋଡ୍ କରିବା</string>
<string name="episode_action_copy_link">ଲିଙ୍କ୍ କପି କରିନେବା</string>
<string name="episode_action_play_in_app">ଆପ୍‌ରେ ଚଲାଅ</string>
<string name="episode_action_chromecast_episode">Chromecast ଅଧ୍ୟାୟ</string>
<string name="episode_short"></string>
@ -61,8 +59,6 @@
<string name="skip_type_ed">ପ୍ରାନ୍ତ</string>
<string name="app_not_found_error">ଆପ୍ ମିଳିଲା ନାହିଁ</string>
<string name="all_languages_preference">ସବୁ ଭାଷା</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="skip_type_mixed_ed">ମିଶ୍ରିତ ପ୍ରାନ୍ତ</string>
<string name="skip_type_mixed_op">ମିଶ୍ରିତ ଆଦ୍ୟ</string>
<string name="skip_type_creddits">ଶ୍ରେୟ</string>

View file

@ -161,32 +161,6 @@
<item>@string/show_title_key</item>
</array>
<array name="episode_long_click_options">
<item>@string/episode_action_chromecast_episode</item>
<item>@string/episode_action_chromecast_mirror</item>
<item>@string/episode_action_play_in_app</item>
<item>@string/episode_action_play_in_format</item>
<item>@string/episode_action_play_in_browser</item>
<item>@string/episode_action_copy_link</item>
<item>@string/episode_action_auto_download</item>
<item>@string/episode_action_download_mirror</item>
<item>@string/episode_action_download_subtitle</item>
<item>@string/episode_action_reload_links</item>
</array>
<array name="episode_long_click_options_values">
<item>4</item>
<item>5</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>9</item>
<item>6</item>
<item>7</item>
<item>13</item>
<item>8</item>
</array>
<array name="app_layout">
<item>@string/automatic</item>
<item>@string/phone_layout</item>

View file

@ -232,8 +232,6 @@
<string name="episode_action_chromecast_mirror">Mirror dla Chromecast</string>
<string name="episode_action_play_in_app">Odtwórz w aplikacji</string>
<string name="episode_action_play_in_format">Odtwórz w %s</string>
<string name="episode_action_play_in_browser">Odtwórz w przeglądarce</string>
<string name="episode_action_copy_link">Kopiuj link</string>
<string name="episode_action_auto_download">Automatyczne pobieranie</string>
<string name="episode_action_download_mirror">Pobierz mirror</string>
<string name="episode_action_reload_links">Odśwież linki</string>
@ -421,10 +419,6 @@
<string name="hls_playlist">Playlista HLS</string>
<string name="player_pref">Preferowany odtwarzacz wideo</string>
<string name="player_settings_play_in_app">Odtwarzacz wewnętrzny</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="player_settings_play_in_web">Web Video Cast</string>
<string name="player_settings_play_in_browser">Przeglądarka</string>
<string name="app_not_found_error">Aplikacja nie została znaleziona</string>
<string name="all_languages_preference">Wszystkie języki</string>
<string name="clear_history">Wyczyść historię</string>
@ -621,7 +615,6 @@
<string name="reset_btn">Resetuj</string>
<string name="episode_upcoming_format" formatted="true">Nadchodzące w %s</string>
<string name="next_season_episode_format" formatted="true">Odcinek %2$d sezonu %1$d wyjdzie za</string>
<string name="player_settings_play_in_fcast">Fcast</string>
<string name="player_settings_select_cast_device">Wybierz urządzenie do transmisji</string>
<string name="episode_action_cast_mirror">Mirror transmisji</string>
<string name="cs3wiki">Wiki CloudStream</string>
@ -664,6 +657,5 @@
<string name="delete_format" formatted="true">Usuń (%1$d | %2$s)</string>
<string name="preview_seekbar">Podgląd paska przewijania</string>
<string name="preview_seekbar_desc">Włącz podgląd miniatury na pasku wyszukiwania</string>
<string name="player_settings_play_in_mpvytdl">MPV YTDL</string>
<string name="no_subtitles_loaded">Nie wczytano jeszcze napisów</string>
</resources>

View file

@ -228,8 +228,6 @@
<string name="episode_action_chromecast_mirror">Alternativa pelo Chromecast</string>
<string name="episode_action_play_in_app">Reproduzir na app</string>
<string name="episode_action_play_in_format">Reproduzir no %s</string>
<string name="episode_action_play_in_browser">Reproduzir no navegador</string>
<string name="episode_action_copy_link">Copiar link</string>
<string name="episode_action_auto_download">Transferência Automática</string>
<string name="episode_action_download_mirror">Transferir por servidor alternativo</string>
<string name="episode_action_reload_links">Recarregar links</string>
@ -441,18 +439,14 @@
<string name="skip_type_intro">Abertura</string>
<string name="select_library">Selecionar Biblioteca</string>
<string name="jsdelivr_proxy_summary">Contorna o bloqueio de URLs raw do GitHub usando jsDelivr. Pode atrasar as atualizações por uns dias.</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="all_languages_preference">Todas as linguagens</string>
<string name="sort_updated_new">Atualizado (Novo para Antigo)</string>
<string name="subscription_list_name">Inscrito</string>
<string name="quality_hdr">HDR</string>
<string name="restart">Reiniciar</string>
<string name="player_settings_play_in_browser">Navegador Web</string>
<string name="sort_updated_old">Atualizado (Antigo para Novo)</string>
<string name="player_settings_play_in_web">Web Video Cast</string>
<string name="quality_dvd">DVD</string>
<string name="apk_installer_package_installer">Instalador de pacotes</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="action_remove_from_watched">Remover dos assistidos</string>
<string name="update_notification_failed">Não foi possível instalar a nova versão do aplicativo</string>
<string name="subscription_deleted">Inscrição cancelada em %s</string>
@ -616,8 +610,7 @@
<string name="battery_dialog_title">Desativar a otimização da bateria</string>
<string name="battery_dialog_message">Para garantir descarregamentos ininterruptos e notificações de programas de TV subscritos, o CloudStream precisa de permissão para ser executado em segundo plano. Ao premir OK, será direcionado para informações da aplicação. Aí, desloque-se para utilização da bateria da aplicação e defina a utilização da bateria para sem restrições. Tenha em atenção que esta permissão não significa que o CS3 irá esgotar a sua bateria. Este só funcionará em segundo plano quando necessário, como ao receber notificações ou baixar vídeos de extensões oficiais. Se optar por cancelar, pode ajustar esta definição mais tarde em definições gerais.</string>
<string name="reset_btn">Reiniciar</string>
<string name="next_season_episode_format" formatted="true">Episódio %2$d da Temporada %1$d vai ser lançado em</string>
<string name="player_settings_play_in_fcast">Fcast</string>
<string name="next_season_episode_format" formatted="true">Episódio %1$d Episódio %2$d vai ser lançado em</string>
<string name="player_settings_select_cast_device">Escolha o dispositivo</string>
<string name="episode_action_cast_mirror">Transmitir</string>
<string name="hide_player_control_names_key" translatable="false">hide_player_control_names_key</string>

View file

@ -144,8 +144,6 @@
<string name="episode_action_chromecast_mirror">aoohaaahhu ahouuhhh</string>
<string name="episode_action_play_in_app">ooo-ahahaauuh aaahhu</string>
<string name="episode_action_play_in_format">ooo-ahah ohaauuh %s</string>
<string name="episode_action_play_in_browser">ahoha ooo-ahahohoohah oooohh</string>
<string name="episode_action_copy_link">aauugghhahhaauugghh</string>
<string name="episode_action_auto_download">aaaghhoooohh aaahhu ahooo</string>
<string name="episode_action_download_mirror">ohooo-ahahaohaohahhhoouuh</string>
<string name="episode_action_reload_links">ahoooaaahhuahaaahhuoha</string>
@ -318,7 +316,6 @@
<string name="batch_download">aaahh uuuugggh</string>
<string name="delete_repository">oooohh oooogggoog</string>
<string name="extension_description">uuuuhhhaagg</string>
<string name="player_settings_play_in_mpv">uuh</string>
<string name="clipboard_too_large">uuh aahh uugg oooogg ag aagg ug ooooggguh</string>
<string name="profile_number">ooooggg %d</string>
<string name="edit">aahh</string>
@ -472,8 +469,6 @@
<string name="safe_mode_description">ooh oooohhhooh oogg oooogg ooh uuh uh g ooogg oh uuhh uug uuhh ooh aah uuuuggg ooooggg</string>
<string name="extension_authors">ooooggg</string>
<string name="player_settings_play_in_app">aaaagggh uuuugg</string>
<string name="player_settings_play_in_web">ooh uuuhh aahh</string>
<string name="player_settings_play_in_browser">uuh uuuuhhh</string>
<string name="app_not_found_error">aah ooh uuugg</string>
<string name="skip_type_op">uuuuhhh</string>
<string name="action_remove_from_watched">uuuuhh aagg oooohhh</string>
@ -617,8 +612,6 @@
<string name="single_plugin_disabled" formatted="true">%s (Disabled)</string>
<string name="extension_rating" formatted="true">Rating: %s</string>
<string name="extension_status">aaaagg</string>
<string name="player_settings_play_in_vlc">oog</string>
<string name="player_settings_play_in_fcast">uuuhh</string>
<string name="player_settings_select_cast_device">aaaagg aahh oooohh</string>
<string name="skip_type_ed">uuuuuk</string>
<string name="skip_type_mixed_op">aaagg aaaahhh</string>

View file

@ -228,8 +228,6 @@
<string name="episode_action_chromecast_mirror">Chromecast alternativ</string>
<string name="episode_action_play_in_app">Redă în Aplicație</string>
<string name="episode_action_play_in_format">Redă în %s</string>
<string name="episode_action_play_in_browser">Redă în Browser</string>
<string name="episode_action_copy_link">Copiază link-ul</string>
<string name="episode_action_auto_download">Auto-descărcare</string>
<string name="episode_action_download_mirror">Descărcă prin Alernativă</string>
<string name="episode_action_reload_links">Reîncărcare link-uri</string>
@ -467,7 +465,6 @@
<string name="no">Nu</string>
<string name="subscription_new">Abonat la %s</string>
<string name="delayed_update_notice">Aplicația va fi actualizată la ieșire</string>
<string name="player_settings_play_in_web">Web Video Cast</string>
<string name="pref_category_bypass">Ocoliri ISP</string>
<string name="previous">Anterior</string>
<string name="sort">Sortează</string>
@ -475,7 +472,6 @@
<string name="subtitles_filter_lang">Filtrați în funcție de limba media preferată</string>
<string name="subscription_episode_released">Episodul %d a fost lansat!</string>
<string name="pref_category_android_tv">Android TV</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="provider_languages_tip">Urmăriți videoclipuri în aceste limbi</string>
<string name="revert">Revenire</string>
<string name="pref_category_actions">Acțiuni</string>
@ -483,7 +479,6 @@
<string name="error_invalid_url">URL invalid</string>
<string name="safe_mode_description">Toate extensiile au fost dezactivate din cauza unei defecțiuni pentru a vă ajuta să o găsiți pe cea care cauzează probleme.</string>
<string name="update_notification_downloading">Se descarcă actualizarea aplicației…</string>
<string name="player_settings_play_in_browser">Browser web</string>
<string name="blank_repo_message">CloudStream nu are niciun site instalat din start. Trebuie să instalați site-urile din depozite.
\n
\nAlăturați-vă Discord-ului nostru sau căutați online.</string>
@ -522,7 +517,6 @@
<string name="subscription_in_progress_notification">Se actualizează emisiunile abonate</string>
<string name="subscription_list_name">Abonat</string>
<string name="view_public_repositories_button_short">Lista publică</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="apk_installer_legacy">Moştenit</string>
<string name="category_provider_test">Test de furnizor</string>
<string name="category_providers">Furnizori</string>
@ -640,6 +634,5 @@
<string name="next_season_episode_format" formatted="true">Sezonul %1$d Episod %2$d va fi lansat în</string>
<string name="player_settings_select_cast_device">Selectați divece-ul pe care doriți să faceți cast</string>
<string name="episode_action_cast_mirror">Cast mirror</string>
<string name="player_settings_play_in_fcast">Fcast</string>
<string name="hide_player_control_names_key" translatable="false">hide_player_control_names_key</string>
</resources>

View file

@ -190,7 +190,6 @@
<string name="torrent">Торренты</string>
<string name="others">Другое</string>
<string name="storage_error">Ошибка загрузки, проверьте разрешения хранилища</string>
<string name="episode_action_copy_link">Копировать ссылку</string>
<string name="episode_action_auto_download">Автоскачивание</string>
<string name="episode_action_download_mirror">Загрузка. Зеркало</string>
<string name="season">Сезон</string>
@ -270,8 +269,6 @@
<string name="extension_size">Размер</string>
<string name="extension_authors">Авторы</string>
<string name="extension_types">Поддерживается</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="skip_type_format" formatted="true">Пропустить %s</string>
<string name="skip_type_ed">Концовка</string>
<string name="use_system_brightness_settings_des">Используйте яркость системы в проигрывателе приложения вместо темного наложения</string>
@ -293,7 +290,6 @@
<string name="unexpected_error">Неожиданная ошибка плеера</string>
<string name="episode_action_chromecast_episode">Эпизод Chromecast</string>
<string name="episode_action_play_in_format">Воспроизведение на %s</string>
<string name="episode_action_play_in_browser">Воспроизвести в браузере</string>
<string name="episode_action_download_subtitle">Скачать субтитры</string>
<string name="show_hd">Знак качества</string>
<string name="poster_ui_settings">Переключение элементов интерфейса на плакате</string>
@ -309,7 +305,6 @@
<string name="sync_score_format" formatted="true">%d из 10</string>
<string name="safe_mode_crash_info">Посмотреть информацию о сбое</string>
<string name="player_pref">Предпочитаемый видеоплеер</string>
<string name="player_settings_play_in_browser">Веб-браузер</string>
<string name="app_not_found_error">Приложение не найдено</string>
<string name="all_languages_preference">Все языки</string>
<string name="skip_type_op">Вступление</string>
@ -492,7 +487,6 @@
<string name="random_button_settings_desc">Отображать рандомную кнопку в библиотеке и главной странице</string>
<string name="random_button_settings">Рандомная кнопка</string>
<string name="apk_installer_legacy">Legacy (старый)</string>
<string name="player_settings_play_in_web">Web Video Cast</string>
<string name="bug_report_settings_on">Не отправляет данные</string>
<string name="episode_action_reload_links">Перезагрузить ссылки</string>
<string name="preferred_media_settings">Предпочтительные медиа</string>
@ -620,7 +614,6 @@
<string name="reset_btn">Сброс</string>
<string name="next_season_episode_format" formatted="true">Сезон %1$d Эпизод %2$d выйдет</string>
<string name="episode_upcoming_format" formatted="true">Выйдет %s</string>
<string name="player_settings_play_in_fcast">Fcast</string>
<string name="player_settings_select_cast_device">Выберите девайс для трансляции</string>
<string name="hide_player_control_names_key" translatable="false">hide_player_control_names_key</string>
<string name="downloads_empty">В данный момент загрузок нет.</string>

View file

@ -188,7 +188,6 @@
<string name="no_subtitles">Žiadne titulky</string>
<string name="anime">Anime</string>
<string name="cartoons">Kreslené</string>
<string name="episode_action_copy_link">Skopírovať odkaz</string>
<string name="episode_action_auto_download">Automaticky stiahnuť</string>
<string name="episode_action_download_mirror">Zrkadlo sťahovania</string>
<string name="video_lock">Zamknúť</string>
@ -320,7 +319,6 @@
<string name="asian_drama">Ázijské drámy</string>
<string name="anime_singular">Anime</string>
<string name="source_error">Chyba zdroja</string>
<string name="episode_action_play_in_browser">Prehrať v prehliadači</string>
<string name="show_dub">Štítok dabingu</string>
<string name="show_sub">Štítok titulkov</string>
<string name="show_title">Názov</string>

View file

@ -119,7 +119,6 @@
<string name="pref_category_defaults">Asalkiisa</string>
<string name="episode_action_play_in_app">Isla appkan ku daawo</string>
<string name="episode_action_play_in_format">Ku daawo %s</string>
<string name="episode_action_play_in_browser">Ku daawo barawsarka</string>
<string name="episode_action_auto_download">Dejinta iskeed ah</string>
<string name="episode_action_download_mirror">Deji toorentiga(mirror)</string>
<string name="episode_action_reload_links">Cusbooneysii lifaaqyada</string>
@ -239,7 +238,6 @@
<string name="show_log_cat">Eeg xogaha hoose 🐈</string>
<string name="player_size_settings">Badhinka xajmiga daaraha</string>
<string name="render_error">Fashil ka yimi dhiibaha</string>
<string name="episode_action_copy_link">Koobu garee lifaaqa</string>
<string name="torrent_no_plot">Sharraxaad ma leh</string>
<string name="torrent_plot">Sharraxaadda</string>
<string name="normal_no_plot">Duluc ma leh</string>
@ -472,10 +470,6 @@
<string name="extensions">Kordhiyeyaasha</string>
<string name="view_public_repositories_button_short">Liiska bulshada kale</string>
<string name="player_settings_play_in_app">Muqaal daaraha appka</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="player_settings_play_in_web">Web Video Cast</string>
<string name="player_settings_play_in_browser">Barawsarka</string>
<string name="app_not_found_error">Kuuguma jiro appkaasi</string>
<string name="all_languages_preference">Dhammaan luuqadaha</string>
<string name="skip_type_format" formatted="true">Is dhaafi %s</string>

View file

@ -148,8 +148,6 @@
<string name="episode_action_chromecast_mirror">Chromecasta en Länk</string>
<string name="episode_action_play_in_app">Spela upp i appen</string>
<string name="episode_action_play_in_format">Spela upp i %s</string>
<string name="episode_action_play_in_browser">Spela upp i webbläsaren</string>
<string name="episode_action_copy_link">Kopiera länk</string>
<string name="episode_action_auto_download">Automatisk nerladdning</string>
<string name="episode_action_download_mirror">Ladda ner en specifik länk</string>
<string name="episode_action_reload_links">Ladda om alla länkar</string>
@ -379,13 +377,11 @@
<string name="show_sub">Visa sub</string>
<string name="app_not_found_error">Kunde inte öppna appen</string>
<string name="jsdelivr_proxy">GitHub Proxy</string>
<string name="player_settings_play_in_browser">Webbläsarens videospelare</string>
<string name="update_notification_installing">Installerar uppdatering till appen…</string>
<string name="jsdelivr_enabled">Kunde inte nå GitHub, sätter på jsDelivr proxy…</string>
<string name="category_providers">Leverantörer</string>
<string name="example_site_name">Nytt webbplatsnamn</string>
<string name="subtitles_remove_bloat">Ta bort reklam från undertexter</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="all_languages_preference">Alla språk</string>
<string name="clear_history">Rensa historik</string>
<string name="apk_installer_package_installer">PackageInstaller</string>
@ -409,8 +405,6 @@
<string name="category_player">Videospelare</string>
<string name="open_with">Öppna med</string>
<string name="subtitle_offset">Synkronisera undertexter</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="player_settings_play_in_web">Web Video Cast</string>
<string name="test_failed">Misslyckades</string>
<string name="yes">Ja</string>
<string name="video_tracks">Videospår</string>
@ -619,7 +613,6 @@
<string name="episode_upcoming_format" formatted="true">Kommer ut om %s</string>
<string name="clipboard_unknown_error">Fel vid kopiering, kopiera logcat och kontakta appsupport.</string>
<string name="custom_media_singluar">Media</string>
<string name="player_settings_play_in_fcast">Fcast</string>
<string name="episode_action_cast_mirror">Cast mirror</string>
<string name="next_season_episode_format" formatted="true">Säsong %1$d Avsnitt %2$d kommer att släppas om</string>
<string name="player_settings_select_cast_device">Välj cast-enhet</string>

View file

@ -266,8 +266,6 @@
<string name="restart">மறுதொடக்கம்</string>
<string name="extension_description">விவரம்</string>
<string name="extension_authors">ஆசிரியர்கள்</string>
<string name="player_settings_play_in_web">வலை வீடியோ நடிகர்கள்</string>
<string name="player_settings_play_in_browser">இணைய உலாவி</string>
<string name="skip_type_format" formatted="true">%s ஐத் தவிர்க்கவும்</string>
<string name="skip_type_recap">மறுபரிசீலனை செய்யுங்கள்</string>
<string name="skip_type_intro">அறிமுகம்</string>
@ -365,7 +363,6 @@
<string name="emulator_layout">முன்மாதிரி தளவமைப்பு</string>
<string name="downloaded_file">பதிவிறக்கம் செய்யப்பட்ட கோப்பு</string>
<string name="resolution">பகுத்தல்</string>
<string name="player_settings_play_in_mpv">எம்.பி.வி.</string>
<string name="empty_library_no_accounts_message">உங்கள் நூலகம் காலியாக உள்ளது :(
\n நூலகக் கணக்கில் உள்நுழைக அல்லது உங்கள் உள்ளக நூலகத்தில் காட்சிகளைச் சேர்க்கவும்.</string>
<string name="action_unsubscribe">குழுவிலகவும்</string>
@ -431,8 +428,6 @@
<string name="source_error">மூல பிழை</string>
<string name="remote_error">தொலை பிழை</string>
<string name="render_error">ரெண்டரர் பிழை</string>
<string name="episode_action_play_in_browser">உலாவியில் விளையாடுங்கள்</string>
<string name="episode_action_copy_link">இணைப்பை நகலெடுக்கவும்</string>
<string name="episode_action_auto_download">ஆட்டோ பதிவிறக்கம்</string>
<string name="episode_action_download_mirror">கண்ணாடியைப் பதிவிறக்கவும்</string>
<string name="episode_action_reload_links">இணைப்புகளை மீண்டும் ஏற்றவும்</string>
@ -520,7 +515,6 @@
<string name="extension_size">அளவு</string>
<string name="extension_types">ஆதரிக்கப்பட்டது</string>
<string name="extension_install_first">முதலில் நீட்டிப்பை நிறுவவும்</string>
<string name="player_settings_play_in_fcast">Fcast</string>
<string name="player_settings_select_cast_device">காச்ட் சாதனத்தைத் தேர்ந்தெடுக்கவும்</string>
<string name="all_languages_preference">அனைத்து மொழிகளும்</string>
<string name="yes">ஆம்</string>
@ -551,7 +545,6 @@
<string name="plugins_not_downloaded" formatted="true">பதிவிறக்கம் செய்யப்படவில்லை: %d</string>
<string name="plugins_updated" formatted="true">புதுப்பிக்கப்பட்டது %d செருகுநிரல்கள்</string>
<string name="player_settings_play_in_app">உள் வீரர்</string>
<string name="player_settings_play_in_vlc">வி.எல்.சி.</string>
<string name="skip_type_op">திறப்பு</string>
<string name="skip_type_mixed_op">கலப்பு திறப்பு</string>
<string name="skip_type_creddits">வரவு</string>

View file

@ -174,8 +174,6 @@
<string name="episode_action_chromecast_mirror">Chromecast Mirror</string>
<string name="episode_action_play_in_app">I-play sa App</string>
<string name="episode_action_play_in_format">I-play sa %s</string>
<string name="episode_action_play_in_browser">I-play sa browser</string>
<string name="episode_action_copy_link">Kopyahin ang Link</string>
<string name="episode_action_auto_download">Awtomatiking i-download</string>
<string name="episode_action_download_mirror">Download mirror</string>
<string name="episode_action_reload_links">Subukan muli</string>

View file

@ -33,22 +33,6 @@
<item>6</item>
</array>
<array name="player_pref_names">
<item>@string/player_settings_play_in_app</item>
<item>@string/player_settings_play_in_vlc</item>
<item>@string/player_settings_play_in_mpv</item>
<item>@string/player_settings_play_in_web</item>
<item>@string/player_settings_play_in_browser</item>
</array>
<array name="player_pref_values">
<item>1</item>
<item>2</item>
<item>5</item>
<item>4</item>
<item>3</item>
</array>
<array name="limit_title_rez_pref_names">
<item>@string/resolution_and_title</item>
<item>@string/title</item>
@ -187,32 +171,6 @@
<item>@string/show_title_key</item>
</array>
<array name="episode_long_click_options">
<item>@string/episode_action_chromecast_episode</item>
<item>@string/episode_action_chromecast_mirror</item>
<item>@string/episode_action_play_in_app</item>
<item>@string/episode_action_play_in_format</item>
<item>@string/episode_action_play_in_browser</item>
<item>@string/episode_action_copy_link</item>
<item>@string/episode_action_auto_download</item>
<item>@string/episode_action_download_mirror</item>
<item>@string/episode_action_download_subtitle</item>
<item>@string/episode_action_reload_links</item>
</array>
<array name="episode_long_click_options_values">
<item>4</item>
<item>5</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>9</item>
<item>6</item>
<item>7</item>
<item>13</item>
<item>8</item>
</array>
<array name="app_layout">
<item>@string/automatic</item>
<item>@string/phone_layout</item>

View file

@ -258,8 +258,6 @@
<string name="episode_action_chromecast_mirror">Bağlantıyı Chromecast ile yayınla</string>
<string name="episode_action_play_in_app">Burada oynat</string>
<string name="episode_action_play_in_format">%s üzerinden oynat</string>
<string name="episode_action_play_in_browser">Tarayıcıda oynat</string>
<string name="episode_action_copy_link">Bağlantıyı kopyala</string>
<string name="episode_action_auto_download">Otomatik indir</string>
<string name="episode_action_download_mirror">Şu kaynaktan indir</string>
<string name="episode_action_reload_links">Bağlantıları yenile</string>
@ -482,10 +480,6 @@
<string name="hls_playlist">HLS Oynatma Listesi</string>
<string name="player_pref">Tercih edilen video oynatıcısı</string>
<string name="player_settings_play_in_app">Dahili oynatıcı</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="player_settings_play_in_web">Web Video Yayını</string>
<string name="player_settings_play_in_browser">İnternet tarayıcısı</string>
<string name="app_not_found_error">Uygulama bulunamadı</string>
<string name="history">Geçmiş</string>
<string name="action_mark_as_watched">İzlendi olarak işaretle</string>
@ -669,7 +663,6 @@
<string name="next_season_episode_format" formatted="true">Sezon %1$d Bölüm %2$d tarihinde yayınlanacak</string>
<string name="player_settings_select_cast_device">Yansıtılacak cihaz seç</string>
<string name="episode_action_cast_mirror">Ekran yansıtma</string>
<string name="player_settings_play_in_fcast">Fcast</string>
<string name="cs3wiki">CloudStream Viki</string>
<string name="pref_category_security">Güvenlik</string>
<string name="pref_category_accounts">Hesaplar</string>

View file

@ -248,7 +248,6 @@
<string name="video_aspect_ratio_resize">Змінити розмір</string>
<string name="synopsis">Короткий зміст</string>
<string name="movies">Фільми</string>
<string name="episode_action_copy_link">Скопіювати посилання</string>
<string name="episode_action_reload_links">Перезавантажити посилання</string>
<string name="documentaries">Документальні фільми</string>
<string name="nsfw">NSFW</string>
@ -257,7 +256,6 @@
<string name="torrent_singular">Торент</string>
<string name="show_hd">Мітка якості</string>
<string name="nsfw_singular">NSFW</string>
<string name="episode_action_play_in_browser">Переглянути в браузері</string>
<string name="unexpected_error">Несподівана помилка плеєра</string>
<string name="storage_error">Помилка завантаження, перевірте дозволи на зберігання</string>
<string name="episode_action_chromecast_episode">Епізод Chromecast</string>
@ -445,10 +443,6 @@
<string name="extension_install_first">Спочатку встановіть розширення</string>
<string name="hls_playlist">Список відтворення HLS</string>
<string name="player_settings_play_in_app">Вбудований плеєр</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="player_settings_play_in_web">Web Video Cast</string>
<string name="player_settings_play_in_browser">Веббраузер</string>
<string name="skip_type_ed">Ендінґ</string>
<string name="skip_type_recap">Коротке повторення</string>
<string name="skip_type_format" formatted="true">Пропустити %s</string>
@ -620,7 +614,6 @@
<string name="reset_btn">Скинути</string>
<string name="episode_upcoming_format" formatted="true">Наступний через %s</string>
<string name="next_season_episode_format" formatted="true">%1$d сезон %2$d епізод вийде через</string>
<string name="player_settings_play_in_fcast">Fcast</string>
<string name="player_settings_select_cast_device">Оберіть пристрій для трансляції</string>
<string name="episode_action_cast_mirror">Трансляція через дзеркало</string>
<string name="cs3wiki">CloudStream Wiki</string>
@ -663,6 +656,5 @@
\n%s</string>
<string name="preview_seekbar">Попередній перегляд повзунка</string>
<string name="preview_seekbar_desc">Ввімкнути мініатюру попереднього перегляду на повзунку</string>
<string name="player_settings_play_in_mpvytdl">MPV YTDL</string>
<string name="no_subtitles_loaded">Субтитри ще не завантажено</string>
</resources>

View file

@ -243,7 +243,6 @@
<string name="episode_action_chromecast_mirror">Chromecast mirror</string>
<string name="episode_action_play_in_app">ایپ میں چلائیں</string>
<string name="episode_action_play_in_format">%s میں چلائیں</string>
<string name="episode_action_copy_link">کاپی لنک</string>
<string name="episode_action_download_mirror">ڈاؤنلوڈ mirror</string>
<string name="episode_action_reload_links">لنکس کو دوبارہ لوڈ کریں</string>
<string name="episode_action_download_subtitle">سب ٹائٹلز ڈاؤن لوڈ</string>
@ -336,7 +335,6 @@
<string name="subtitle_offset_extra_hint_none_format">کوئی زیرنویس میں دیری نہیں</string>
<string name="nsfw_singular">این ایس ایف ڈبلیو</string>
<string name="episode_action_auto_download">آٹو ڈاؤن لوڈ</string>
<string name="episode_action_play_in_browser">browser میں چلائیں</string>
<string name="video_ram_description">بہت زیادہ سیٹ ہونے پر کم میموری والی ڈیوائس(جیسے کہ Android TV) پر کریشوں کا سبب بنتا ہے.</string>
<string name="remove_site_pref">Remove site</string>
<string name="add_site_summary">Add a clone of an existing site, with a different URL</string>
@ -361,7 +359,6 @@
<string name="resolution_and_title">قرارداد اور عنوان</string>
<string name="quality_hdr">HDR</string>
<string name="subscription_deleted">%s سے ان سبسکرائب کیا گیا</string>
<string name="player_settings_play_in_web">ویب ویڈیو کاسٹ</string>
<string name="is_adult">18+</string>
<string name="test_log">لاگ</string>
<string name="network_adress_example">https://example.com/example.mp4</string>
@ -427,11 +424,8 @@
<string name="extension_status">حالت</string>
<string name="extension_size">سائز</string>
<string name="extension_language">زبان</string>
<string name="player_settings_play_in_vlc">وی ایل سی</string>
<string name="player_pref">ترجیحی ویڈیو پلیئر</string>
<string name="player_settings_play_in_app">اندرونی پلیئر</string>
<string name="player_settings_play_in_mpv">ایم پی وی</string>
<string name="player_settings_play_in_browser">ویب براؤزر</string>
<string name="app_not_found_error">ایپ نہیں ملی</string>
<string name="skip_type_recap">Recap</string>
<string name="skip_type_mixed_ed">مخلوط اختتام</string>

View file

@ -153,32 +153,6 @@
<item>@string/show_title_key</item>
</array>
<array name="episode_long_click_options">
<item>@string/episode_action_chromecast_episode</item>
<item>@string/episode_action_chromecast_mirror</item>
<item>@string/episode_action_play_in_app</item>
<item>@string/episode_action_play_in_format</item>
<item>@string/episode_action_play_in_browser</item>
<item>@string/episode_action_copy_link</item>
<item>@string/episode_action_auto_download</item>
<item>@string/episode_action_download_mirror</item>
<item>@string/episode_action_download_subtitle</item>
<item>@string/episode_action_reload_links</item>
</array>
<array name="episode_long_click_options_values">
<item>4</item>
<item>5</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>9</item>
<item>6</item>
<item>7</item>
<item>13</item>
<item>8</item>
</array>
<array name="app_layout">
<item>@string/automatic</item>
<item>@string/phone_layout</item>

View file

@ -243,8 +243,6 @@
<string name="episode_action_chromecast_mirror">Chiếu Chromecast</string>
<string name="episode_action_play_in_app">Xem với trình phát mặc định</string>
<string name="episode_action_play_in_format">Xem với trình phát %s</string>
<string name="episode_action_play_in_browser">Xem tại trình duyệt</string>
<string name="episode_action_copy_link">Sao chép liên kết</string>
<string name="episode_action_auto_download">Tự động tải xuống</string>
<string name="episode_action_download_mirror">Nguồn tải xuống</string>
<string name="episode_action_reload_links">Lấy link mới nhất</string>
@ -472,10 +470,6 @@
<string name="extension_types">Hỗ trợ</string>
<string name="extension_language">Ngôn ngữ</string>
<string name="extension_install_first">Cài đặt tiện ích trước</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="player_settings_play_in_web">Web Video Cast</string>
<string name="player_settings_play_in_browser">Trình duyệt web</string>
<string name="app_not_found_error">Không thấy ứng dụng</string>
<string name="all_languages_preference">Tất cả ngôn ngữ</string>
<string name="skip_type_format" formatted="true">Tua %s</string>
@ -671,11 +665,9 @@
\n
\n%s</string>
<string name="delete_plugin">Xóa plugin</string>
<string name="player_settings_play_in_fcast">Fcast</string>
<string name="sort_release_date_old">Ngày phát hành (Cũ đến mới)</string>
<string name="hide_player_control_names">Ẩn tên các nút điều khiển</string>
<string name="preview_seekbar_desc">Bật chế độ xem trước hình thu nhỏ trên seekbar</string>
<string name="preview_seekbar">Xem trước Seekbar</string>
<string name="player_settings_play_in_mpvytdl">MPV YTDL</string>
<string name="no_subtitles_loaded">Chưa tải phụ đề</string>
</resources>

View file

@ -258,8 +258,6 @@
<string name="episode_action_chromecast_mirror">Chromecast 鏡像</string>
<string name="episode_action_play_in_app">在應用程式中播放</string>
<string name="episode_action_play_in_format">在 %s 中播放</string>
<string name="episode_action_play_in_browser">在瀏覽器中播放</string>
<string name="episode_action_copy_link">複製連結</string>
<string name="episode_action_auto_download">自動下載</string>
<string name="episode_action_download_mirror">下載鏡像</string>
<string name="episode_action_reload_links">重新載入連結</string>
@ -482,10 +480,6 @@
<string name="hls_playlist">HLS 播放清單</string>
<string name="player_pref">偏好影片播放器</string>
<string name="player_settings_play_in_app">內部播放器</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="player_settings_play_in_web">網路影片播放</string>
<string name="player_settings_play_in_browser">網頁瀏覽器</string>
<string name="app_not_found_error">未找到應用程式</string>
<string name="all_languages_preference">所有語言</string>
<string name="skip_type_format" formatted="true">跳過 %s</string>
@ -663,7 +657,6 @@
<string name="biometric_setting_summary">使用指紋、面容 ID、PIN、圖案和密碼解除鎖定應用程式。</string>
<string name="biometric_prompt_description">由於多次嘗試失敗,此畫面已關閉。請重新啟動應用程式。</string>
<string name="clipboard_permission_error">剪貼簿存取失敗,請再試一次。</string>
<string name="player_settings_play_in_fcast">Fcast</string>
<string name="clipboard_unknown_error">複製失敗,請複製 logcat 內容並聯繫應用程式支援者。</string>
<string name="app_info_intent_error">無法開啟 CloudStream 的應用程式資訊頁面。</string>
<string name="biometric_warning">您的 CloudStream 資料已完成備份。儘管可能性非常低,但因不同裝置的行為都有所不同,在極少數情況下,您可能會無法存取本應用程式。此時請完全清除本應用程式的資料,再使用已有的備份進行還原。若因此造成任何不便,我們深感抱歉。</string>

View file

@ -259,8 +259,6 @@
<string name="episode_action_chromecast_mirror">Chromecast 镜像</string>
<string name="episode_action_play_in_app">在应用中播放</string>
<string name="episode_action_play_in_format">在 %s 中播放</string>
<string name="episode_action_play_in_browser">在浏览器中播放</string>
<string name="episode_action_copy_link">复制链接</string>
<string name="episode_action_auto_download">自动下载</string>
<string name="episode_action_download_mirror">下载镜像</string>
<string name="episode_action_reload_links">重新加载链接</string>
@ -483,10 +481,6 @@
<string name="hls_playlist">HLS 播放列表</string>
<string name="player_pref">首选视频播放器</string>
<string name="player_settings_play_in_app">内部播放器</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="player_settings_play_in_web">投屏</string>
<string name="player_settings_play_in_browser">浏览器</string>
<string name="app_not_found_error">未找到应用</string>
<string name="all_languages_preference">所有语言</string>
<string name="skip_type_format" formatted="true">跳过 %s</string>
@ -665,7 +659,6 @@
<string name="biometric_prompt_description">在多次尝试失败后,提示将关闭。只需重启应用程序再试。</string>
<string name="episode_upcoming_format" formatted="true">即将在 %s</string>
<string name="cs3wiki">CloudStream Wiki</string>
<string name="player_settings_play_in_fcast">Fcast</string>
<string name="player_settings_select_cast_device">选择投射设备</string>
<string name="next_season_episode_format" formatted="true">%1$d季%2$d集将在</string>
<string name="episode_action_cast_mirror">投射镜像</string>
@ -674,7 +667,6 @@
<string name="open_local_video">打开本地视频</string>
<string name="pref_category_security">安全</string>
<string name="device_pin_url_message">访问智能手机或电脑上的 <b>%s</b> 并输入上述代码</string>
<string name="player_settings_play_in_mpvytdl">MPV YTDL</string>
<string name="preview_seekbar">进度条预览</string>
<string name="preview_seekbar_desc">启用进度条预览缩略图</string>
<string name="delete_plugin">删除插件</string>

View file

@ -50,24 +50,6 @@
<item>@string/nsfw</item>
</array>
<array name="player_pref_names">
<item>@string/player_settings_play_in_app</item>
<item>@string/player_settings_play_in_vlc</item>
<item>@string/player_settings_play_in_mpv</item>
<item>@string/player_settings_play_in_mpvytdl</item>
<item>@string/player_settings_play_in_web</item>
<item>@string/player_settings_play_in_browser</item>
</array>
<array name="player_pref_values">
<item>1</item>
<item>2</item>
<item>5</item>
<item>6</item>
<item>4</item>
<item>3</item>
</array>
<array name="limit_title_rez_pref_names">
<item>@string/resolution_and_title</item>
<item>@string/title</item>
@ -226,32 +208,6 @@
<item>@string/show_title_key</item>
</array>
<array name="episode_long_click_options">
<item>@string/episode_action_chromecast_episode</item>
<item>@string/episode_action_chromecast_mirror</item>
<item>@string/episode_action_play_in_app</item>
<item>@string/episode_action_play_in_format</item>
<item>@string/episode_action_play_in_browser</item>
<item>@string/episode_action_copy_link</item>
<item>@string/episode_action_auto_download</item>
<item>@string/episode_action_download_mirror</item>
<item>@string/episode_action_download_subtitle</item>
<item>@string/episode_action_reload_links</item>
</array>
<array name="episode_long_click_options_values">
<item>4</item>
<item>5</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>9</item>
<item>6</item>
<item>7</item>
<item>13</item>
<item>8</item>
</array>
<array name="app_layout">
<item>@string/automatic</item>
<item>@string/phone_layout</item>

View file

@ -17,7 +17,7 @@
<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_mobile_data_key" translatable="false">quality_pref_mobile_data_key</string>
<string name="player_pref_key" translatable="false">player_pref_key</string>
<string name="player_default_key" translatable="false">player_default_key</string>
<string name="prefer_limit_title_key" translatable="false">prefer_limit_title_key</string>
<string name="prefer_limit_title_rez_key" translatable="false">prefer_limit_title_rez_key</string>
<string name="apk_installer_key" translatable="false">apk_installer_key</string>
@ -381,8 +381,6 @@
<string name="episode_action_cast_mirror">Cast mirror</string>
<string name="episode_action_play_in_app">Play in app</string>
<string name="episode_action_play_in_format">Play in %s</string>
<string name="episode_action_play_in_browser">Play in browser</string>
<string name="episode_action_copy_link">Copy link</string>
<string name="episode_action_auto_download">Auto download</string>
<string name="episode_action_download_mirror">Download mirror</string>
<string name="episode_action_reload_links">Reload links</string>
@ -662,12 +660,6 @@
<string name="hls_playlist">HLS Playlist</string>
<string name="player_pref">Preferred video player</string>
<string name="player_settings_play_in_app">Internal player</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="player_settings_play_in_mpvytdl">MPV YTDL</string>
<string name="player_settings_play_in_web">Web Video Cast</string>
<string name="player_settings_play_in_fcast">Fcast</string>
<string name="player_settings_play_in_browser">Web browser</string>
<string name="player_settings_select_cast_device">Select cast device</string>
<string name="app_not_found_error">App not found</string>
<string name="all_languages_preference">All Languages</string>

View file

@ -22,7 +22,7 @@
<Preference
android:icon="@drawable/netflix_play"
android:key="@string/player_pref_key"
android:key="@string/player_default_key"
android:title="@string/player_pref" />
</PreferenceCategory>