diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 1aeef5550..a04504acd 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -17,7 +17,7 @@
-
+
@@ -30,13 +30,6 @@
android:name="android.software.leanback"
android:required="false" />
-
-
-
-
-
-
-
- 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("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")
+ }
}
// Ask for notification permissions on Android 13
diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt
index 3581a3d29..fa54545cf 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt
@@ -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? = 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? = null
const val TAG = "MAINACT"
const val ANIMATED_OUTLINE: Boolean = false
diff --git a/app/src/main/java/com/lagradost/cloudstream3/actions/OpenInAppAction.kt b/app/src/main/java/com/lagradost/cloudstream3/actions/OpenInAppAction.kt
new file mode 100644
index 000000000..99c1ac38b
--- /dev/null
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/OpenInAppAction.kt
@@ -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?)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/lagradost/cloudstream3/actions/VideoClickAction.kt b/app/src/main/java/com/lagradost/cloudstream3/actions/VideoClickAction.kt
new file mode 100644
index 000000000..f66ed74d9
--- /dev/null
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/VideoClickAction.kt
@@ -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(
+ 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.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?)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/lagradost/cloudstream3/actions/temp/CopyClipboardAction.kt b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/CopyClipboardAction.kt
new file mode 100644
index 000000000..e054b5ce2
--- /dev/null
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/CopyClipboardAction.kt
@@ -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)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/lagradost/cloudstream3/actions/temp/MpvKtPackage.kt b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/MpvKtPackage.kt
new file mode 100644
index 000000000..f5ded49b8
--- /dev/null
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/MpvKtPackage.kt
@@ -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)
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/lagradost/cloudstream3/actions/temp/MpvPackage.kt b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/MpvPackage.kt
new file mode 100644
index 000000000..4c66d0450
--- /dev/null
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/MpvPackage.kt
@@ -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())
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/lagradost/cloudstream3/actions/temp/PlayInBrowserAction.kt b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/PlayInBrowserAction.kt
new file mode 100644
index 000000000..de32bb4b3
--- /dev/null
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/PlayInBrowserAction.kt
@@ -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 = 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)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/lagradost/cloudstream3/actions/temp/ViewM3U8Action.kt b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/ViewM3U8Action.kt
new file mode 100644
index 000000000..c14168e96
--- /dev/null
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/ViewM3U8Action.kt
@@ -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)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/lagradost/cloudstream3/actions/temp/VlcPackage.kt b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/VlcPackage.kt
new file mode 100644
index 000000000..ecb37fdc6
--- /dev/null
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/VlcPackage.kt
@@ -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)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/lagradost/cloudstream3/actions/temp/WebVideoCastPackage.kt b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/WebVideoCastPackage.kt
new file mode 100644
index 000000000..f8419f63c
--- /dev/null
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/WebVideoCastPackage.kt
@@ -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
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/lagradost/cloudstream3/actions/temp/fcast/FcastAction.kt b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/fcast/FcastAction.kt
new file mode 100644
index 000000000..c0f92e4df
--- /dev/null
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/fcast/FcastAction.kt
@@ -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
+ )
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/fcast/FcastManager.kt b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/fcast/FcastManager.kt
similarity index 98%
rename from app/src/main/java/com/lagradost/cloudstream3/utils/fcast/FcastManager.kt
rename to app/src/main/java/com/lagradost/cloudstream3/actions/temp/fcast/FcastManager.kt
index e7c36a872..78682ca1c 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/utils/fcast/FcastManager.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/fcast/FcastManager.kt
@@ -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
diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/fcast/FcastSession.kt b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/fcast/FcastSession.kt
similarity index 96%
rename from app/src/main/java/com/lagradost/cloudstream3/utils/fcast/FcastSession.kt
rename to app/src/main/java/com/lagradost/cloudstream3/actions/temp/fcast/FcastSession.kt
index 1f33bca43..326d11191 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/utils/fcast/FcastSession.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/fcast/FcastSession.kt
@@ -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
diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/fcast/Packets.kt b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/fcast/Packets.kt
similarity index 95%
rename from app/src/main/java/com/lagradost/cloudstream3/utils/fcast/Packets.kt
rename to app/src/main/java/com/lagradost/cloudstream3/actions/temp/fcast/Packets.kt
index 61c00d6ed..26f5cec53 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/utils/fcast/Packets.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/fcast/Packets.kt
@@ -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) {
diff --git a/app/src/main/java/com/lagradost/cloudstream3/plugins/Plugin.kt b/app/src/main/java/com/lagradost/cloudstream3/plugins/Plugin.kt
index fc8365876..e35ae24b9 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/plugins/Plugin.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/plugins/Plugin.kt
@@ -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
diff --git a/app/src/main/java/com/lagradost/cloudstream3/plugins/PluginManager.kt b/app/src/main/java/com/lagradost/cloudstream3/plugins/PluginManager.kt
index c7f416883..8535592d4 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/plugins/PluginManager.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/plugins/PluginManager.kt
@@ -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)
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt
index 1eaac5056..4b5d680c3 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt
@@ -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)
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/DownloadFileGenerator.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/DownloadFileGenerator.kt
index c7db7d045..7d3d18ca9 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/DownloadFileGenerator.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/DownloadFileGenerator.kt
@@ -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,
callback: (Pair) -> Unit,
subtitleCallback: (SubtitleData) -> Unit,
- offset: Int
+ offset: Int,
+ isCasting: Boolean
): Boolean {
val meta = episodes[currentIndex + offset]
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/ExtractorLinkGenerator.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/ExtractorLinkGenerator.kt
index ec485f1c8..794dd762d 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/ExtractorLinkGenerator.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/ExtractorLinkGenerator.kt
@@ -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,
@@ -37,15 +38,15 @@ class ExtractorLinkGenerator(
override suspend fun generateLinks(
clearCache: Boolean,
- type: LoadType,
+ sourceTypes: Set,
callback: (Pair) -> 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)
}
}
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/IGenerator.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/IGenerator.kt
index 6b8e6ea88..31cf0c70f 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/IGenerator.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/IGenerator.kt
@@ -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
+)
+
+val LOADTYPE_INAPP_DOWNLOAD = setOf(
+ ExtractorLinkType.VIDEO,
+ ExtractorLinkType.M3U8
+)
+
+val LOADTYPE_CHROMECAST = setOf(
+ ExtractorLinkType.VIDEO,
+ ExtractorLinkType.DASH,
+ ExtractorLinkType.M3U8
+)
+
+val LOADTYPE_ALL = ExtractorLinkType.entries.toSet()
-fun LoadType.toSet() : Set {
- return when(this) {
- LoadType.InApp -> 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
- )
- }
-}
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,
callback: (Pair) -> Unit,
subtitleCallback: (SubtitleData) -> Unit,
offset: Int = 0,
+ isCasting: Boolean = false
): Boolean
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/LinkGenerator.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/LinkGenerator.kt
index 20feae413..109e3137b 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/LinkGenerator.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/LinkGenerator.kt
@@ -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,
callback: (Pair) -> Unit,
subtitleCallback: (SubtitleData) -> Unit,
- offset: Int
+ offset: Int,
+ isCasting: Boolean
): Boolean {
links.amap { link ->
if (!extract || !loadExtractor(link.url, referer, {
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerGeneratorViewModel.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerGeneratorViewModel.kt
index 122eaa975..67cd9de6d 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerGeneratorViewModel.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerGeneratorViewModel.kt
@@ -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 = 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 {
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/RepoLinkGenerator.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/RepoLinkGenerator.kt
index 588afbb50..b97ca155b 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/RepoLinkGenerator.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/RepoLinkGenerator.kt
@@ -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,
callback: (Pair) -> 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)) {
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt
index 4cd9cc9ea..2dd8e2ab4 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt
@@ -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() {
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
}
}
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt
index a29941d11..b5f83201e 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt
@@ -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()
val currentSubs = mutableSetOf()
- 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, callback: suspend (Int?) -> Unit) {
+ fun postPopup(text: UiText, options: List, 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 = 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,
text: UiText,
- callback: (Pair) -> Unit,
+ isCasting: Boolean = false,
+ callback: (Pair) -> 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) -> 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 = 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, _) ->
- if (link != null) {
- links += link
- updatePage()
- }
- }, { sub ->
+ tempGenerator.generateLinks(clearCache,
+ allowedTypes = sourceTypes,
+ callback = { (link, _) ->
+ if (link != null) {
+ links += link
+ updatePage()
+ }
+ },
+ 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
- ) = 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,
- 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,
- 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>()
+
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 {
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsPlayer.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsPlayer.kt
index 1753032ac..17580236f 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsPlayer.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsPlayer.kt
@@ -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
}
diff --git a/app/src/main/res/values-ajp/strings.xml b/app/src/main/res/values-ajp/strings.xml
index 6896cf2af..0b30cebac 100644
--- a/app/src/main/res/values-ajp/strings.xml
+++ b/app/src/main/res/values-ajp/strings.xml
@@ -221,9 +221,7 @@
بسبِب أعطال إزا نحط على مستوى عالي كتير على الأجهزة يللي م بتساع كتير، متل تلفزيون \"أندرويد\".
شي غير
أفي هيدا التجديد
- نسوخ الرابط
مَشي بال آپ
- مشي بمتصفح الويب
مفيد لتجاوز المنع من مزود خدمة الإنترنت
مسلسل
غير الحجم
@@ -390,10 +388,8 @@
م قدرنا ننزل الإصدار الجديد تبع الآپ
المؤلفين
إضافة
- كاست ڤيديو ع الوَب
معقول يكون موجود أصلًا
مشتركينلو
- متصفح الوَب
كل اللغات
دايمًا كتوب ب أحرف كاپيتال، A بدل a
مشغل الڤيديو المفضل
@@ -422,7 +418,6 @@
خلصت
محي السجل
تجَدَد (من قديم للجديد)
- \"ڤي أل سي ميديا پلاير\"
كاميرا
وَب
أبجديًا (من الياء للألف)
@@ -504,7 +499,6 @@
مزامنة
شوفو معلومات عن المشكلة
مدعوم
- \"أم پي ڤي\"
ظبّط وقت الترجمة
افتتاح مختلط
مقطع دعائي
@@ -627,7 +621,6 @@
رح ينزل ب %s
الحلقة ال %2$d من الجزء ال%1$d رح تنزل ب
كاست مراية
- إف كاست
نقي جهاز الكاست
ويكي \"كلود ستريم\"
أكونتات
@@ -669,6 +662,5 @@
\n%s
صورة زغيرة مع التقريب وال تبعيد
بت حط صورة زغير من الڤيديو إنت و عم بت قرب أو ترجع بال ڤيديو
- MPV YTDL
بعد مش معمول لود لولا ترجمة
\ No newline at end of file
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index 25118d963..56bb4b4a0 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -233,8 +233,6 @@
مرآة كروم كاست
تشغيل في التطبيق
%s تشغيل في
- تشغيل في الويب
- نسخ الرابط
التحميل التلقائي
تحميل بجودات مختلفة
إعادة تحميل الروابط
@@ -464,10 +462,6 @@
فتح(تشغيل)
%1$s %2$d%3$s
المكونات الإضافية المحدثة %d
- VLC
- MPV
- اسقاط فيديو الويب
- متصفح الإنترنت
تخطي %s
الافتتاح
النهاية
@@ -653,7 +647,6 @@
قادم خلال %s
سيتم إصدار الحلقة %1$d من الموسم %2$d في
مرآة البث
- بث ف
حدد جهاز البث
CloudStream ويكي
إعدادات الأمان
@@ -695,6 +688,5 @@
\n%s
معاينة شريط البحث
تمكين معاينة الصورة المصغرة على شريط البحث
- MPV YTDL
لم يتم تحميل أي ترجمات بعد
\ No newline at end of file
diff --git a/app/src/main/res/values-ars/strings.xml b/app/src/main/res/values-ars/strings.xml
index 873c55bf3..d1efdbbc5 100644
--- a/app/src/main/res/values-ars/strings.xml
+++ b/app/src/main/res/values-ars/strings.xml
@@ -311,11 +311,9 @@
اخرون
تخطي هذا التحديث
.قد يتسبب في تأخير التحديثات لبضعة أيام .jsDelivr باستخدام GitHubيتجاوز حظر
- انسخ الرابط
الدرامات الآسيوية
في قائمة الانتظار
افتح في التطبيق
- افتح في المتصفح
مفيد لتجاوز حجب مزودي خدمة الإنترنت
مسلسل
تقييم
diff --git a/app/src/main/res/values-as/strings.xml b/app/src/main/res/values-as/strings.xml
index fc50d2d02..2fdd469b4 100644
--- a/app/src/main/res/values-as/strings.xml
+++ b/app/src/main/res/values-as/strings.xml
@@ -89,7 +89,6 @@
সম্পূৰ্ণ
সৰ্বজনীন তালিকা
বন্ধ কৰক
- VLC
বেটাৰী অপ্টিমাইজেচন নিষ্ক্ৰিয় কৰক
সদস্যতা গ্ৰহণ কৰা
গুণসমূহ
@@ -302,8 +301,6 @@
কাষ্ট মিৰৰ
ডাব ছপা
প্লে %s ত
- ব্ৰাউজাৰত প্লে কৰক
- লিংক কপি কৰক
স্বয়ংক্ৰিয় ডাউনলোড
ডাউনলোড মিৰৰ
সাব ছপা
@@ -498,10 +495,6 @@
HLS প্লেলিস্ট
পছন্দৰ ভিডিঅ\' প্লেয়াৰ
আভ্যন্তৰীণ প্লেয়াৰ
- MPV
- ৱেব ভিডিঅ\' কাষ্ট
- Fcast
- ৱেব ব্ৰাউজাৰ
কাষ্ট ডিভাইচ চয়ন কৰক
মিশ্ৰিত সমাপ্তি
মিশ্ৰিত উদ্ঘাটনী
@@ -650,7 +643,6 @@
ডিভাইচ পিন ক\'ড পোৱা নাই, স্থানীয় প্ৰমাণীকৰণ চেষ্টা কৰক
পিন ক\'ডৰ মেয়াদ শেষ হৈছে!
ক\'ড মেয়াদ শেষ হব %1$dm %2$ds
- MPV YTDL
সীকবৰ প্ৰিভিউ
সীকবৰত প্ৰিভিউ থাম্বনেইল সক্ৰিয় কৰক
আৰম্ভৰ পৰা প্লে কৰক
diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml
index 3579c8353..218fa5e57 100644
--- a/app/src/main/res/values-bg/strings.xml
+++ b/app/src/main/res/values-bg/strings.xml
@@ -238,8 +238,6 @@
Chromecast огледало
Пусни в приложението
Пусни в %s
- Пусни в браузър
- Копирай връзка
Автоматично изтегляне
Изтегляне на огледало
Презареждане на връзки
@@ -443,10 +441,6 @@
HLS плейлист
Предпочитан видео плеър
Вътрешен плеър
- VLC
- MPV
- Уеб видео предаване
- Уеб браузър
Приложението не е намерено
Автоматично изтегли добавки
Всички езици
diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml
index c5ed86514..f1bc8f82a 100644
--- a/app/src/main/res/values-bn/strings.xml
+++ b/app/src/main/res/values-bn/strings.xml
@@ -230,7 +230,6 @@
প্লাগইন ডাউনলোড ফিল্টার করতে মোড নির্বাচন করুন
লিঙ্ক পুনরায় লোড হয়েছে
সুইচ অ্যাকাউন্ট
- ব্রাউজারে প্লে করুন
দাবিত্যাগ
এশিয়ান ড্রামা
সোর্স
@@ -274,7 +273,6 @@
টরেন্ট
এপিসোড ক্রোমকাস্ট করুন
প্লে হচ্ছে %s সময়ের মধ্যে
- লিঙ্ক কপি করুন
স্বয়ংক্রিয় ডাউনলোড
টাইটেল
প্লেয়ার দেখা যাচ্ছে - সিকের পরিমাণ
diff --git a/app/src/main/res/values-bp/strings.xml b/app/src/main/res/values-bp/strings.xml
index 4c29a99e7..55e1ce180 100644
--- a/app/src/main/res/values-bp/strings.xml
+++ b/app/src/main/res/values-bp/strings.xml
@@ -235,8 +235,6 @@
Alternativa pelo Chromecast
Assistir no App
Assistir no %s
- Assistir no navegador
- Copiar link
Auto download
Baixar por servidor alternativo
Recarregar links
@@ -538,16 +536,13 @@
Começar
Suportado
Status
- MPV
Abrindo mistura
- VLC
Reinicie o aplicativo para ver as alterações.
Visualização info de crash
Faixas de áudio
Adicionado em (novo para antigo)
Faixas de video
Legendas
- Navegador
18+
Links
Funcionalidades do Player
@@ -563,7 +558,6 @@
Vídeo
Android TV
Wi-Fi
- Lista de videos da web
A interface de usuário não foi gerada corretamente. Isto se trata de um bug importante e deve ser reportado imediatamente %s
Características da interface de usuário
Provedor de teste
@@ -642,7 +636,6 @@
Redefinir
Próximos em %s
Temporada %1$d Episódio %2$d será lançado em
- Fcast
Selecione o dispositivo de transmissão
Espelhar transmissão
CloudStream Wiki
@@ -685,6 +678,5 @@
Desmarcar todos
Ativar visualização de miniatura na barra de busca
Visualização da barra de busca
- MPV + YTDL
Ainda não há legendas carregadas
\ No newline at end of file
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index 04b4b213b..ba03b05fb 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -223,8 +223,6 @@
Chromecast jako zrcadlo
Přehrát v aplikace
Přehrát ve %s
- Přehrát v prohlížeči
- Zkopírovat odkaz
Automaticky stáhnout
Zrcadlo stahování
Obnovit odkazy
@@ -400,8 +398,6 @@
Veřejný seznam
Velká písmena u všech titulků
Playlist HLS
- MPV
- Webové vysílání videa
Aplikace nenalezena
Přeskočit %s
Úvod
@@ -451,13 +447,11 @@
Popis
Stav
Nejprve nainstalujte rozšíření
- VLC
Smíšený konec
Jazyk
Interní přehrávač
Rekapitulace
Vymazat historii
- Webový prohlížeč
Všechny jazyky
Smíšený úvod
Poděkování
@@ -645,7 +639,6 @@
Vychází %s
Epizoda %2$d ze série %1$d bude vydána za
Vysílat zrcadlení
- Fcast
Vyberte zařízení k vysílání
CloudStream Wiki
Zabezpečení
@@ -687,6 +680,5 @@
Odstranit (%1$d | %2$s)
Náhled v liště přehrávače
Povolit náhled miniatur na liště přehrávače
- MPV YTDL
Zatím nenačteny žádné titulky
\ No newline at end of file
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index c9656d9de..6cf8ff3bd 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -241,8 +241,6 @@
Downloadfehler, bitte überprüfen sie die Speicherberechtigungen
Chromecast-Episode
In %s wiedergeben
- In Browser wiedergeben
- Link kopieren
Auto-Download
Alternativer Download
Links neu laden
@@ -437,10 +435,6 @@
HLS-Playlist
Bevorzugter Videoplayer
Interner Player
- VLC
- MPV
- Web Video Cast
- Browser
App nicht gefunden
Alle Sprachen
Überspringen %s
@@ -618,7 +612,6 @@
hide_player_control_names_key
Staffel %1$d Episode %2$d wird veröffentlicht in
Wird veröffentlicht in %s
- Fcast
Sicherheit
Konten
Repository öffnen
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index e22182d23..268ea7bd1 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -194,8 +194,6 @@
Chromecast επεισόδιο
Αναπαραγωγή εντός της εφαρμογής
Αναπαραγωγή σε %s
- Αναπαραγωγή στον περιηγητή
- Αντιγραφή συνδέσμου
Αυτόματη λήψη
Λήψη mirror
Επαναφόρτωση συνδέσμων
@@ -359,10 +357,6 @@
HLS Playlist
Προτεινόμενο πρόγραμμα αναπαραγωγής
Ενσωματωμένο πρόγραμμα αναπαραγωγής
- VLC
- MPV
- Web Video Cast
- Περιηγητής
Η εφαρμογή δεν βρέθηκε
%1$s Επ %2$d
Το επεισόδιο %d θα κυκλοφορήσει σε
@@ -580,7 +574,6 @@
Δευτερόλεπτα Σκιπ όταν φαίνεται ο αναπαραγωγέας (πλειερ)
Δοκιμή όλων των παροχών
Αυτό το τεστ προορίζεται μόνο για τους προγραμματιστές και δε επαληθείει ούτε απορρίπτει την λειτουργία οποιουδήποτε παρόχου.
- Fcast
Επιλογή συσκευής για αναμετάδοση
Πρόβλημα στην πρόσβαση στο Clipboard, Παρακαλώ προσπαθήστε ξανά.
Πρόβλημα στην αντιγραφή , Παρακαλούμε αντιγράψτε το logcat και επικοινωνήστε με την υποστήριξη.
diff --git a/app/src/main/res/values-es/array.xml b/app/src/main/res/values-es/array.xml
index eb197f43e..fddd832a5 100644
--- a/app/src/main/res/values-es/array.xml
+++ b/app/src/main/res/values-es/array.xml
@@ -152,32 +152,6 @@
- @string/show_title_key
-
- - @string/episode_action_chromecast_episode
- - @string/episode_action_chromecast_mirror
- - @string/episode_action_play_in_app
- - @string/episode_action_play_in_format
- - @string/episode_action_play_in_browser
- - @string/episode_action_copy_link
- - @string/episode_action_auto_download
- - @string/episode_action_download_mirror
- - @string/episode_action_download_subtitle
- - @string/episode_action_reload_links
-
-
-
- - 4
- - 5
- - 1
- - 2
- - 3
- - 9
- - 6
- - 7
- - 13
- - 8
-
-
- @string/automatic
- @string/phone_layout
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 155c5f746..a0c4587f5 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -57,11 +57,7 @@
Cantidad de búsquedas del reproductor (segundos)
Use el brillo del sistema en el reproductor de la app en lugar de una superposición oscura
Resolución del reproductor de video
- MPV
Reproductor
- VLC
- Web Video Cast
- Navegador Web
Iniciar el siguiente episodio cuando el actual termine
Omitir Intro
Apertura
@@ -78,9 +74,7 @@
Actualizar progreso de lo visto
Duplicar en Chromecast
No se encontraron Episodios
- Reproducir en Navegador
Reproducir en %s
- Copiar enlace
Descarga automática
Descargar desde servidor alternativo
Recargar enlaces
@@ -621,7 +615,6 @@
Próximamente en %s
La temporada %1$d y el episodio %2$d se estrenarán en
Seleccionar el dispositivo para transmitir
- Fcast
Espejo de transmisión
Wiki de CloudStream
Seguridad
@@ -663,6 +656,5 @@
\n%s
Activar la previsualización para las miniaturas en la barra de búsqueda
Previsualización de Seekbar
- MPV YTDL
Aún no hay subtítulos cargados
\ No newline at end of file
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 0483cb2ea..5b3f09120 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -111,8 +111,6 @@
Miroir Chromecast
Lecture dans l\'application
Lecture dans %s
- Lecture dans le navigateur
- Copier le lien
Téléchargement automatique
Télécharger depuis le miroir
Recharger les liens
@@ -140,7 +138,7 @@
DNS avec HTTPS
Afficher les animés en Anglais (Dub) / sous-titrés
Disposition en mode téléphone
- %1$s Episode %2$d
+ episode_action_copy_link
Note : %.1f
Zoom
Adapter à l\'écran
@@ -430,12 +428,10 @@
Installer l\'extension d\'abord
Playlist HLS
Lecteur vidéo préféré
- VLC
Fin mitigée
Introduction mitigée
Installation de la mise a jour de l\'application…
Impossible d\'installer la nouvelle version de l\'application
- Navigateur Web
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.
Précédent
Ignorer la configuration
@@ -456,7 +452,6 @@
Lecteur interne
Application introuvable
Trop de texte. Impossible de sauvegarder dans le presse papier.
- MPV
Installateur de paquet
plugins
Cela supprimera également tous les plugins du repository
@@ -466,7 +461,6 @@
Langage
Afficher les popups skip pour les intro / fins
Ancienne méthode d\'installation
- Web Video Cast
Liens
Gestes
Fonctionnalités du lecteur
diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml
index eed5e44aa..4457b0ec4 100644
--- a/app/src/main/res/values-hi/strings.xml
+++ b/app/src/main/res/values-hi/strings.xml
@@ -114,8 +114,6 @@
क्रोमकास्ट मिरर
एप्प में चलाएं
%s में चलाएं
- Browser में चलाएं
- लिंक कॉपी करें
डाउनलोड करें
मिरर डाउनलोड
लिंक दोबारा लोड करें
diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml
index 44f1bd5b9..dcacbeee3 100644
--- a/app/src/main/res/values-hr/strings.xml
+++ b/app/src/main/res/values-hr/strings.xml
@@ -253,8 +253,6 @@
Chromecast mirror
Pokreni u aplikaciji
Pokreni u %s
- Pokreni u pregledniku
- Kopiraj poveznicu
Automatsko preuzimanje
Preuzmi zrcalo
Ponovo učitaj poveznice
@@ -461,9 +459,6 @@
Preferirani video player
Interni player
Najprije instaliraj proširenje
- VLC
- MPV
- Emitiranje na webu
Aplikacija nije pronađena
Svi jezici
Previše teksta. Nije moguće spremiti u međuspremnik.
@@ -495,7 +490,6 @@
Zadane postavke
Izgledi
Značajke
- Web preglednik
Preskoči %s
Kraj
Sažetak
@@ -646,7 +640,6 @@
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.
Sezona %1$d epizoda %2$d izlazi
Cast mirror
- Fcast
Odaberi uređaj za emitiranje
CloudStream Wiki
Računi
@@ -686,6 +679,5 @@
Stvarno želite trajno izbrisati sve epizode u sljedećoj seriji?
\n
\n%s
- MPV YTDL
Još nije učitan nijedan titl
\ No newline at end of file
diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml
index 1426e8a38..f124ad062 100644
--- a/app/src/main/res/values-hu/strings.xml
+++ b/app/src/main/res/values-hu/strings.xml
@@ -182,7 +182,6 @@
Dokumentumfilm
Ázsiai dráma
Linkek újratöltése
- Link másolás
Letöltés mirror
Automatikus letöltés
Adatok eltárolva
@@ -227,7 +226,6 @@
Chromecast mirror
Lejátszás az alkalmazásban
Lejátszás %s
- Lejátszás böngészőben
Feliratok letöltése
Újracsatlakozás…
Húzd balra vagy jobbra a videólejátszóban az idő vezérléséhez
@@ -352,7 +350,6 @@
Mit szeretnél látni
Minden %s már letöltött
Először telepítse a bővítményt
- Webböngésző
Kinézet
Alkalmazás elrendezés
Szinkronizálás
@@ -368,7 +365,6 @@
Töltse le az összes bővítményt ebből a tárolóból?
Biztonságos mód bekapcsolva
Méret
- MPV
Alkalmazás nem található
PackageInstaller
Rendezés e szerint
@@ -403,7 +399,6 @@
Emelt
HD
HLS lejátszási lista
- VLC
Nem sikerült telepíteni az alkalmazás új verzióját
%s hitelesítve
Körvonal
@@ -528,7 +523,6 @@
Hivatkozó (opcionális)
Nem találhatóak pluginek a repóban
Repó nem található, ellenőrizze a címet vagy próbálja VPN-el
- Web Videó Cast
%s kihagyása
A kihagyási felugró ablakok mutatása nyitás/zárás esetén
Alapbeállítás
diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml
index 09dfb5322..efd0ed0cf 100644
--- a/app/src/main/res/values-in/strings.xml
+++ b/app/src/main/res/values-in/strings.xml
@@ -221,8 +221,6 @@
Mirror Chromecast
Putar di aplikasi
Putar di %s
- Putar di browser
- Salin tautan
Download otomatis
Download mirror
Muat ulang tautan
@@ -442,8 +440,6 @@
Bahasa
Pemutar video utama
Pemutar Bawaan
- VLC
- MPV
Terunduh %1$d %2$s
Memulai mengunduh %1$d %2$s…
Semua fitur tambahkan dimatikan karena crash, untuk memudahkanmu mencari penyebab crash.
@@ -495,9 +491,7 @@
Tidak
Memasang pembaruan…
Tidak dapat memasang versi terbaru
- Web browser
Aplikasi tidak ditemukan
- Web Video Cast
Hapus Riwayat
Tampilkan popup untuk skip sesi pembuka/akhir
Mengunduh pembaruan…
@@ -643,7 +637,6 @@
Akan datang di %s
Cermin Cast
Pilih perangkat cast
- Fcast
CloudStream Wiki
Keamanan
Akun
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index f498ccae1..590c167d9 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -243,8 +243,6 @@
Mirror Chromecast
Riproduci in app
Riproduci in %s
- Riproduci nel browser
- Copia link
Download
Mirror download
Aggiorna link
@@ -448,10 +446,6 @@
Playlist HLS
Video player preferito
Player interno
- VLC
- MPV
- Cast Web Video
- Web browser
App non trovata
Tutte le lingue
Salta %s
@@ -642,7 +636,6 @@
L\'episodio %2$d della stagione %1$d uscirà tra
Mirror cast
Seleziona dispositivo per cast
- Fcast
Wiki di CloudStream
Conti
Sicurezza
@@ -683,6 +676,5 @@
\n%s
Anteprima barra di ricerca
Abilita miniatura di anteprima sulla barra di ricerca
- MPV YTDL
Nessun sottotitolo caricato
\ No newline at end of file
diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml
index 6316d7f79..6ebe405bc 100644
--- a/app/src/main/res/values-iw/strings.xml
+++ b/app/src/main/res/values-iw/strings.xml
@@ -168,7 +168,6 @@
דרמה אסייתית
כרומקאסט את הפרק
כרומקאסט את המראה
- נגן בדפדפן
תווית כתוביות
החלף רכיבי ממשק משתמש בפוסטר
דלג על הפתיח
@@ -326,7 +325,6 @@
שגיאת הורדה, בדוק הרשאות אחסון
נגן באפליקציה
נגן ב %s
- העתק קישור
הורדה אוטומטית
טען מחדש קישורים
תווית איכות
@@ -431,7 +429,6 @@
כל %s כבר הורד
מחברים
שפה
- MPV
קרדיטים
מיין
בחר ספרייה
@@ -445,8 +442,6 @@
הורד את כל התוספים ממאגר זה?
רצועות שמע
מסלולים
- Web Video Cast
- דפדפן אינטרנט
כל התוספים נכבו עקב התרסקות כדי לעזור לך למצוא את האחד הגורם לצרות.
מוריד החבילות
עודכן %d תוספים
@@ -479,7 +474,6 @@
פלייליסט HLS
נגן וידאו מועדף
נגן פנימי
- VLC
האפליקציה לא נמצאה
כל השפות
דלג %s
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index ed9850e8e..3ca79b3d5 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -144,9 +144,6 @@
完成
進行中
デフォルト
- ウェブブラウザ
- VLC
- MPV
言語
作成者
サイズ
diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml
index 6993ec1c9..d62ecb69b 100644
--- a/app/src/main/res/values-ko/strings.xml
+++ b/app/src/main/res/values-ko/strings.xml
@@ -186,8 +186,6 @@
Chromecast 미러링
앱에서 재생
%s에서 재생
- 브라우저에서 재생
- 링크 복사
자동 다운로드
다운로드 미러
링크 새로고침
@@ -445,7 +443,6 @@
소개
유형
먼저 확장 프로그램을 설치하세요
- 웹 브라우저
앱을 찾을 수 없음
모든 언어
건너뛰기 %s
@@ -482,11 +479,8 @@
\n파일이 제거될 때까지 시작 시 확장 프로그램을 로드하지 않습니다.
HLS 재생목록
내부 플레이어
- MPV
선호하는 동영상 플레이어
- VLC
라이브러리 선택
- 웹 동영상 캐스트
이 목록이 비어 있습니다. 다른 목록으로 전환해 보세요.
필러
라이브 스트리밍 재생
@@ -579,7 +573,6 @@
자동 회전
모바일 데이터
사용 불가능
- fcast
캐스트 장치 선택
복사하는 중 오류가 발생했습니다. 로그캣을 복사하고 문의하십시오.
구독 취소
diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml
index fe205dab7..cc68d77eb 100644
--- a/app/src/main/res/values-lt/strings.xml
+++ b/app/src/main/res/values-lt/strings.xml
@@ -163,10 +163,8 @@
Įvertinta
Praleisti šį atnaujinimą
Veiksmai
- Kopijuoti nuorodą
Paleisti programoje
Sinchronizuoti
- Paleisti naršyklėje
Pašalinti puslapį
Perkrauti nuorodos
Išjungti
@@ -192,7 +190,6 @@
Mobilūs duomenys
šaunusPrisijungimoVardas
Autoriai
- Naršyklė
Visos kalbos
4K
Pradėta siųsti %1$d %2$s…
@@ -206,7 +203,6 @@
Kalbos kodas (lt)
Baigta
Išvalyti istoriją
- VLC
Redaguoti
Wi-Fi
Greitai būs…
@@ -227,7 +223,6 @@
UHD
Dydis
Palaikoma
- MPV
ManoŠaunusPuslapis
Anonsas
Istorija
diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml
index 8f13b93c0..9469aa8e8 100644
--- a/app/src/main/res/values-lv/strings.xml
+++ b/app/src/main/res/values-lv/strings.xml
@@ -241,8 +241,6 @@
Chromecast morror
Palaist aplikācijā
Atskaņot uekšā %s
- Atskaņot internetā
- Kopēt linku
Automātiski ielādēt
Ielādēt spoguli
Pārlādēt saites
@@ -437,8 +435,6 @@
HLS atskaņošanas saraksts
Vēlamais video atskaņotājs
Iekšējais atskaņotājs
- MPV
- Web video apraide
Aplikācijs nav atrasta
Visas valodas
Beigas
@@ -513,8 +509,6 @@
Lejupielādējiet to vietņu sarakstu, kuras vēlaties izmantot
Vispirms instalējiet paplašinājumu
Atvēršana
- VLC
- Interneta mekletājs
Sākums
Izlaist %s
Noņemt no skatītajiem
diff --git a/app/src/main/res/values-mk/strings.xml b/app/src/main/res/values-mk/strings.xml
index 671257492..79dc1ee7e 100644
--- a/app/src/main/res/values-mk/strings.xml
+++ b/app/src/main/res/values-mk/strings.xml
@@ -164,8 +164,6 @@
Огледало на Chromecastr
Пушти во апликацијата
Пушти на %s
- Пушти на прелистувач
- Копирај линк
Авто превземање
Превземи Mirror
Вчитај повторно врски
@@ -297,7 +295,6 @@
Износот на барањето што се користи кога плеерот е скриен
Преземи преводи
Јавна листа
- MPV
Инсталатор на пакети
ОВА
Ажурирање и резервна копија
@@ -425,7 +422,6 @@
/??
hello@world.com
+30
- VLC
Рестартирај
Цртан филм
Почна да презема %1$d %2$s…
@@ -448,7 +444,6 @@
Камера
Камера
SDR
- Веб-прелистувач
Апликацијата не е пронајдена
Корисничко име
Отвори со
@@ -488,7 +483,6 @@
Сите екстензии беа исклучени поради пад за да ви помогнат да ја пронајдете онаа што предизвикува проблеми.
Оцена: %s
Големина
- Веб-видео Cast
Сите јазици
Исчисти историја
Обележи како гледано
@@ -611,7 +605,6 @@
Сега е направена резервна копија на вашите податоци на CloudStream. Иако можноста за ова е многу мала, сите уреди можат да се однесуваат поинаку. Во ретки случаи, кога ќе се заклучите од пристап до апликацијата, целосно исчистете ги податоците на апликацијата и вратете ги од резервна копија. Многу ни е жал за какви било непријатности што произлегуваат од ова.
Ресетирај
Сезона %1$d Епизода %2$d ќе биде објавена за
- Fcast
Одбери уред да кастираш
Оневозможи оптимизација на батерија
Отклучи CloudStream
diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml
index 1c2d855e5..bf0fede72 100644
--- a/app/src/main/res/values-ml/strings.xml
+++ b/app/src/main/res/values-ml/strings.xml
@@ -151,8 +151,6 @@
Chromecast Mirror -->
ആപ്പിൽ പ്ലേയ് ചെയ്യുക
%sയിൽ പ്ലേയ് ചെയ്യുക
- ബ്രൗസറിൽ പ്ലേയ് ചെയ്യുക
- ലിങ്ക് പകർത്തുക
ഡൌൺലോഡ് ചെയ്യൂ
മിറർ ഡൗണ്ലോഡ്
ലിങ്ക്സ് വീണ്ടും ലോഡുചെയ്യുക
diff --git a/app/src/main/res/values-ms/strings.xml b/app/src/main/res/values-ms/strings.xml
index 07154776d..e865d58db 100644
--- a/app/src/main/res/values-ms/strings.xml
+++ b/app/src/main/res/values-ms/strings.xml
@@ -2,7 +2,6 @@
Semua bahasa
Langkau %s
- Pelayar web
Sejarah
Kosongkan sejarah
Pengenalan
@@ -232,7 +231,6 @@
Dinaikkan
Lihat video dalam bahasa-bahasa ini
Normal
- Main dalam pelayar
Tambah
Diguna
Anime
@@ -323,7 +321,6 @@
Chromecast episod
Main dalam %s
Muat turun gagal, cek keizinan storan
- Salin pautan
Muat turun cermin
Muat turun sari kata
Label sub
@@ -449,8 +446,6 @@
Pengesahan Password/PIN
Sari kata belum tetapkan lagi
Disokong
- MPV
- Fcast
Ralat tidak dapat akses Clipboard, Sila cuba sekali lagi.
Ralat menyalin, Sila salin logcat dan hubungi penyokong aplikasi.
Amaran
@@ -462,8 +457,6 @@
Maks
Amaran: CloudStream 3 tidak bertanggungjawab atas penggunaan tambahan pihak ketiga dan tidak memberi sumbang kepada mereka!
Mula semula aplikasi untuk lihat perubahan.
- VLC
- MPV YTDL
Senarai ini kosong. Sila tukar yang lain.
Data mudah alih
Tambah ke kegemaran
diff --git a/app/src/main/res/values-my/strings.xml b/app/src/main/res/values-my/strings.xml
index 31e6ef276..9d82dd47d 100644
--- a/app/src/main/res/values-my/strings.xml
+++ b/app/src/main/res/values-my/strings.xml
@@ -157,8 +157,6 @@
Chromecast ဖန်သားပြင်
အက်ပ်တွင်းဖွင့်
ဖွင့်ရန် %s
- ဘရောက်ဇာထဲမှာ ဖွင့်ရန်
- လင့်ကူးယူရန်
အလိုအလျောက်ဒေါင်းလုဒ်
လင့်များကို ပြန်စစ်ရန်
အရည်အသွေး အမှတ်အသား
@@ -338,7 +336,6 @@
နောက်သို့
အပ်ဒိတ်လုပ်ပြီး %d ဖြည့်စွက်များ
ဒေါင်းလုဒ်မလုပ်ရသေး: %d
- ဝဘ်ဘရောက်ဇာ
အက်ပ်မတွေ့ပါ
ဘာသာစကားအားလုံး
ကျော်ရန် %s
@@ -422,9 +419,6 @@
ထောက်ပံ့ထားသော
ဘာသာစကား
အဆက်များကိုအရင်သွင်းပါ
- VLC
- MPV
- ဝဘ်ထဲတွင်ဖွင့်ရန်
အစပိုင်း
အဆုံးပိုင်း
ကြည့်ရှုခဲ့သည်များကိုရှင်းရန်
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index 4bef20cc2..6518eb0e7 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -235,8 +235,6 @@
Chromecast mirror
Speel in app
Speel in %s
- Speel in browser
- Kopieer link
Automatisch downloaden
Download mirror
Herlaad Linkss
@@ -409,7 +407,6 @@
Kan %s niet laden
Alle %s reeds gedownload
plugin
- VLC
Sla %s over
Links
App updates
@@ -468,10 +465,7 @@
Herhaal installatieproces
Automatisch bijwerken plugin
Sommige telefoons ondersteunen het nieuwe installatieprogramma niet. Probeer de oude optie als de updates niet worden geïnstalleerd.
- Web Video Cast
Interne speler
- MPV
- Web browser
Gemengd einde
Herhaling
Start
diff --git a/app/src/main/res/values-nn/strings.xml b/app/src/main/res/values-nn/strings.xml
index 33ebe1b51..5b5577c2e 100644
--- a/app/src/main/res/values-nn/strings.xml
+++ b/app/src/main/res/values-nn/strings.xml
@@ -149,8 +149,6 @@
Kjeldefeil
Spel av i programmet
Spel av i %s
- Spel av i nettlesaren
- Kopier lenke
Automatisk nedlasting
Last inn lenker på nytt
Last ned undertekstar
diff --git a/app/src/main/res/values-no/strings.xml b/app/src/main/res/values-no/strings.xml
index 41117f104..ac13f57f9 100644
--- a/app/src/main/res/values-no/strings.xml
+++ b/app/src/main/res/values-no/strings.xml
@@ -171,8 +171,6 @@
Støpt Speil
Spill i appen
Spill i %s
- Spill i nettleseren
- Kopier link
Automatisk nedlasting
Last ned speil
Last inn lenker på nytt
@@ -250,7 +248,6 @@
HLS-spilleliste
Foretrukket videospiller
Intern spiller
- VLC
Alle språk
Hopp over %s
Tøm historikk
@@ -283,7 +280,6 @@
Beskrivelse
Legg til konto
Normal
- MPV
Dobbelttrykk for å sette på pause
+30
Skygge
@@ -416,7 +412,6 @@
Kunne ikke logge inn på %s
Store bokstaver i undertekster
Utviklere
- Nettleser
Sensurerbart
Vev
Lenke til strøm
@@ -450,7 +445,6 @@
Fjern unødvendig informasjon fra undertekster
Ekstra
Filtrer etter foretrukket mediaspråk
- Vev-videosending
Tilbakeblikk
SD
Forfilm
diff --git a/app/src/main/res/values-or/strings.xml b/app/src/main/res/values-or/strings.xml
index a9cff7edf..1a7d9c72f 100644
--- a/app/src/main/res/values-or/strings.xml
+++ b/app/src/main/res/values-or/strings.xml
@@ -28,14 +28,12 @@
ଟି ଅଧ୍ୟାୟ
ଅଧ୍ୟାୟ
%sରେ ଚଲାଅ
- ବ୍ରାଉଜର୍ରେ ଚଲାଅ
ଉପଶୀର୍ଷକ ଡାଉନଲୋଡ୍ କରିବା
/%d
/??
ଅଧ୍ୟାୟ %d ମୁକ୍ତିଲାଭ କଲା!
ସ୍ୱତଃ ଡାଉନଲୋଡ୍
ଲିଙ୍କ୍ଗୁଡ଼ିକୁ ପୁନଃଲୋଡ୍ କରିବା
- ଲିଙ୍କ୍ କପି କରିନେବା
ଆପ୍ରେ ଚଲାଅ
Chromecast ଅଧ୍ୟାୟ
ଅ
@@ -61,8 +59,6 @@
ପ୍ରାନ୍ତ
ଆପ୍ ମିଳିଲା ନାହିଁ
ସବୁ ଭାଷା
- VLC
- MPV
ମିଶ୍ରିତ ପ୍ରାନ୍ତ
ମିଶ୍ରିତ ଆଦ୍ୟ
ଶ୍ରେୟ
diff --git a/app/src/main/res/values-pl/array.xml b/app/src/main/res/values-pl/array.xml
index a43d7bcfe..45a8e56e1 100644
--- a/app/src/main/res/values-pl/array.xml
+++ b/app/src/main/res/values-pl/array.xml
@@ -161,32 +161,6 @@
- @string/show_title_key
-
- - @string/episode_action_chromecast_episode
- - @string/episode_action_chromecast_mirror
- - @string/episode_action_play_in_app
- - @string/episode_action_play_in_format
- - @string/episode_action_play_in_browser
- - @string/episode_action_copy_link
- - @string/episode_action_auto_download
- - @string/episode_action_download_mirror
- - @string/episode_action_download_subtitle
- - @string/episode_action_reload_links
-
-
-
- - 4
- - 5
- - 1
- - 2
- - 3
- - 9
- - 6
- - 7
- - 13
- - 8
-
-
- @string/automatic
- @string/phone_layout
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 8f0c0b125..2f26c3f5b 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -232,8 +232,6 @@
Mirror dla Chromecast
Odtwórz w aplikacji
Odtwórz w %s
- Odtwórz w przeglądarce
- Kopiuj link
Automatyczne pobieranie
Pobierz mirror
Odśwież linki
@@ -421,10 +419,6 @@
Playlista HLS
Preferowany odtwarzacz wideo
Odtwarzacz wewnętrzny
- VLC
- MPV
- Web Video Cast
- Przeglądarka
Aplikacja nie została znaleziona
Wszystkie języki
Wyczyść historię
@@ -621,7 +615,6 @@
Resetuj
Nadchodzące w %s
Odcinek %2$d sezonu %1$d wyjdzie za
- Fcast
Wybierz urządzenie do transmisji
Mirror transmisji
Wiki CloudStream
@@ -664,6 +657,5 @@
Usuń (%1$d | %2$s)
Podgląd paska przewijania
Włącz podgląd miniatury na pasku wyszukiwania
- MPV YTDL
Nie wczytano jeszcze napisów
\ No newline at end of file
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
index 2afd50310..7fdbc6bee 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -228,8 +228,6 @@
Alternativa pelo Chromecast
Reproduzir na app
Reproduzir no %s
- Reproduzir no navegador
- Copiar link
Transferência Automática
Transferir por servidor alternativo
Recarregar links
@@ -441,18 +439,14 @@
Abertura
Selecionar Biblioteca
Contorna o bloqueio de URLs raw do GitHub usando jsDelivr. Pode atrasar as atualizações por uns dias.
- VLC
Todas as linguagens
Atualizado (Novo para Antigo)
Inscrito
HDR
Reiniciar
- Navegador Web
Atualizado (Antigo para Novo)
- Web Video Cast
DVD
Instalador de pacotes
- MPV
Remover dos assistidos
Não foi possível instalar a nova versão do aplicativo
Inscrição cancelada em %s
@@ -616,8 +610,7 @@
Desativar a otimização da bateria
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.
Reiniciar
- Episódio %2$d da Temporada %1$d vai ser lançado em
- Fcast
+ Episódio %1$d Episódio %2$d vai ser lançado em
Escolha o dispositivo
Transmitir
hide_player_control_names_key
diff --git a/app/src/main/res/values-qt/strings.xml b/app/src/main/res/values-qt/strings.xml
index 378e3aaec..8f0e14cbc 100644
--- a/app/src/main/res/values-qt/strings.xml
+++ b/app/src/main/res/values-qt/strings.xml
@@ -144,8 +144,6 @@
aoohaaahhu ahouuhhh
ooo-ahahaauuh aaahhu
ooo-ahah ohaauuh %s
- ahoha ooo-ahahohoohah oooohh
- aauugghhahhaauugghh
aaaghhoooohh aaahhu ahooo
ohooo-ahahaohaohahhhoouuh
ahoooaaahhuahaaahhuoha
@@ -318,7 +316,6 @@
aaahh uuuugggh
oooohh oooogggoog
uuuuhhhaagg
- uuh
uuh aahh uugg oooogg ag aagg ug ooooggguh
ooooggg %d
aahh
@@ -472,8 +469,6 @@
ooh oooohhhooh oogg oooogg ooh uuh uh g ooogg oh uuhh uug uuhh ooh aah uuuuggg ooooggg
ooooggg
aaaagggh uuuugg
- ooh uuuhh aahh
- uuh uuuuhhh
aah ooh uuugg
uuuuhhh
uuuuhh aagg oooohhh
@@ -617,8 +612,6 @@
%s (Disabled)
Rating: %s
aaaagg
- oog
- uuuhh
aaaagg aahh oooohh
uuuuuk
aaagg aaaahhh
diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml
index 8105aa3e8..ec1115112 100644
--- a/app/src/main/res/values-ro/strings.xml
+++ b/app/src/main/res/values-ro/strings.xml
@@ -228,8 +228,6 @@
Chromecast alternativ
Redă în Aplicație
Redă în %s
- Redă în Browser
- Copiază link-ul
Auto-descărcare
Descărcă prin Alernativă
Reîncărcare link-uri
@@ -467,7 +465,6 @@
Nu
Abonat la %s
Aplicația va fi actualizată la ieșire
- Web Video Cast
Ocoliri ISP
Anterior
Sortează
@@ -475,7 +472,6 @@
Filtrați în funcție de limba media preferată
Episodul %d a fost lansat!
Android TV
- VLC
Urmăriți videoclipuri în aceste limbi
Revenire
Acțiuni
@@ -483,7 +479,6 @@
URL invalid
Toate extensiile au fost dezactivate din cauza unei defecțiuni pentru a vă ajuta să o găsiți pe cea care cauzează probleme.
Se descarcă actualizarea aplicației…
- Browser web
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.
@@ -522,7 +517,6 @@
Se actualizează emisiunile abonate
Abonat
Lista publică
- MPV
Moştenit
Test de furnizor
Furnizori
@@ -640,6 +634,5 @@
Sezonul %1$d Episod %2$d va fi lansat în
Selectați divece-ul pe care doriți să faceți cast
Cast mirror
- Fcast
hide_player_control_names_key
\ No newline at end of file
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index e2f6a4b13..c251ca9bb 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -190,7 +190,6 @@
Торренты
Другое
Ошибка загрузки, проверьте разрешения хранилища
- Копировать ссылку
Автоскачивание
Загрузка. Зеркало
Сезон
@@ -270,8 +269,6 @@
Размер
Авторы
Поддерживается
- VLC
- MPV
Пропустить %s
Концовка
Используйте яркость системы в проигрывателе приложения вместо темного наложения
@@ -293,7 +290,6 @@
Неожиданная ошибка плеера
Эпизод Chromecast
Воспроизведение на %s
- Воспроизвести в браузере
Скачать субтитры
Знак качества
Переключение элементов интерфейса на плакате
@@ -309,7 +305,6 @@
%d из 10
Посмотреть информацию о сбое
Предпочитаемый видеоплеер
- Веб-браузер
Приложение не найдено
Все языки
Вступление
@@ -492,7 +487,6 @@
Отображать рандомную кнопку в библиотеке и главной странице
Рандомная кнопка
Legacy (старый)
- Web Video Cast
Не отправляет данные
Перезагрузить ссылки
Предпочтительные медиа
@@ -620,7 +614,6 @@
Сброс
Сезон %1$d Эпизод %2$d выйдет
Выйдет %s
- Fcast
Выберите девайс для трансляции
hide_player_control_names_key
В данный момент загрузок нет.
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index 4e38be6b9..196ed1d60 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -188,7 +188,6 @@
Žiadne titulky
Anime
Kreslené
- Skopírovať odkaz
Automaticky stiahnuť
Zrkadlo sťahovania
Zamknúť
@@ -320,7 +319,6 @@
Ázijské drámy
Anime
Chyba zdroja
- Prehrať v prehliadači
Štítok dabingu
Štítok titulkov
Názov
diff --git a/app/src/main/res/values-so/strings.xml b/app/src/main/res/values-so/strings.xml
index e4ee98f96..8b1e4cc15 100644
--- a/app/src/main/res/values-so/strings.xml
+++ b/app/src/main/res/values-so/strings.xml
@@ -119,7 +119,6 @@
Asalkiisa
Isla appkan ku daawo
Ku daawo %s
- Ku daawo barawsarka
Dejinta iskeed ah
Deji toorentiga(mirror)
Cusbooneysii lifaaqyada
@@ -239,7 +238,6 @@
Eeg xogaha hoose 🐈
Badhinka xajmiga daaraha
Fashil ka yimi dhiibaha
- Koobu garee lifaaqa
Sharraxaad ma leh
Sharraxaadda
Duluc ma leh
@@ -472,10 +470,6 @@
Kordhiyeyaasha
Liiska bulshada kale
Muqaal daaraha appka
- VLC
- MPV
- Web Video Cast
- Barawsarka
Kuuguma jiro appkaasi
Dhammaan luuqadaha
Is dhaafi %s
diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml
index 9757fdf67..06f388848 100644
--- a/app/src/main/res/values-sv/strings.xml
+++ b/app/src/main/res/values-sv/strings.xml
@@ -148,8 +148,6 @@
Chromecasta en Länk
Spela upp i appen
Spela upp i %s
- Spela upp i webbläsaren
- Kopiera länk
Automatisk nerladdning
Ladda ner en specifik länk
Ladda om alla länkar
@@ -379,13 +377,11 @@
Visa sub
Kunde inte öppna appen
GitHub Proxy
- Webbläsarens videospelare
Installerar uppdatering till appen…
Kunde inte nå GitHub, sätter på jsDelivr proxy…
Leverantörer
Nytt webbplatsnamn
Ta bort reklam från undertexter
- VLC
Alla språk
Rensa historik
PackageInstaller
@@ -409,8 +405,6 @@
Videospelare
Öppna med
Synkronisera undertexter
- MPV
- Web Video Cast
Misslyckades
Ja
Videospår
@@ -619,7 +613,6 @@
Kommer ut om %s
Fel vid kopiering, kopiera logcat och kontakta appsupport.
Media
- Fcast
Cast mirror
Säsong %1$d Avsnitt %2$d kommer att släppas om
Välj cast-enhet
diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml
index c8c3243cd..a2b4cadd2 100644
--- a/app/src/main/res/values-ta/strings.xml
+++ b/app/src/main/res/values-ta/strings.xml
@@ -266,8 +266,6 @@
மறுதொடக்கம்
விவரம்
ஆசிரியர்கள்
- வலை வீடியோ நடிகர்கள்
- இணைய உலாவி
%s ஐத் தவிர்க்கவும்
மறுபரிசீலனை செய்யுங்கள்
அறிமுகம்
@@ -365,7 +363,6 @@
முன்மாதிரி தளவமைப்பு
பதிவிறக்கம் செய்யப்பட்ட கோப்பு
பகுத்தல்
- எம்.பி.வி.
உங்கள் நூலகம் காலியாக உள்ளது :(
\n நூலகக் கணக்கில் உள்நுழைக அல்லது உங்கள் உள்ளக நூலகத்தில் காட்சிகளைச் சேர்க்கவும்.
குழுவிலகவும்
@@ -431,8 +428,6 @@
மூல பிழை
தொலை பிழை
ரெண்டரர் பிழை
- உலாவியில் விளையாடுங்கள்
- இணைப்பை நகலெடுக்கவும்
ஆட்டோ பதிவிறக்கம்
கண்ணாடியைப் பதிவிறக்கவும்
இணைப்புகளை மீண்டும் ஏற்றவும்
@@ -520,7 +515,6 @@
அளவு
ஆதரிக்கப்பட்டது
முதலில் நீட்டிப்பை நிறுவவும்
- Fcast
காச்ட் சாதனத்தைத் தேர்ந்தெடுக்கவும்
அனைத்து மொழிகளும்
ஆம்
@@ -551,7 +545,6 @@
பதிவிறக்கம் செய்யப்படவில்லை: %d
புதுப்பிக்கப்பட்டது %d செருகுநிரல்கள்
உள் வீரர்
- வி.எல்.சி.
திறப்பு
கலப்பு திறப்பு
வரவு
diff --git a/app/src/main/res/values-tl/strings.xml b/app/src/main/res/values-tl/strings.xml
index d832144dd..5fd25031e 100644
--- a/app/src/main/res/values-tl/strings.xml
+++ b/app/src/main/res/values-tl/strings.xml
@@ -174,8 +174,6 @@
Chromecast Mirror
I-play sa App
I-play sa %s
- I-play sa browser
- Kopyahin ang Link
Awtomatiking i-download
Download mirror
Subukan muli
diff --git a/app/src/main/res/values-tr/array.xml b/app/src/main/res/values-tr/array.xml
index 22a94ebf0..4ec45e6d1 100644
--- a/app/src/main/res/values-tr/array.xml
+++ b/app/src/main/res/values-tr/array.xml
@@ -33,22 +33,6 @@
- 6
-
- - @string/player_settings_play_in_app
- - @string/player_settings_play_in_vlc
- - @string/player_settings_play_in_mpv
- - @string/player_settings_play_in_web
- - @string/player_settings_play_in_browser
-
-
-
- - 1
- - 2
- - 5
- - 4
- - 3
-
-
- @string/resolution_and_title
- @string/title
@@ -187,32 +171,6 @@
- @string/show_title_key
-
- - @string/episode_action_chromecast_episode
- - @string/episode_action_chromecast_mirror
- - @string/episode_action_play_in_app
- - @string/episode_action_play_in_format
- - @string/episode_action_play_in_browser
- - @string/episode_action_copy_link
- - @string/episode_action_auto_download
- - @string/episode_action_download_mirror
- - @string/episode_action_download_subtitle
- - @string/episode_action_reload_links
-
-
-
- - 4
- - 5
- - 1
- - 2
- - 3
- - 9
- - 6
- - 7
- - 13
- - 8
-
-
- @string/automatic
- @string/phone_layout
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index d40e5d7aa..b516de738 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -258,8 +258,6 @@
Bağlantıyı Chromecast ile yayınla
Burada oynat
%s üzerinden oynat
- Tarayıcıda oynat
- Bağlantıyı kopyala
Otomatik indir
Şu kaynaktan indir
Bağlantıları yenile
@@ -482,10 +480,6 @@
HLS Oynatma Listesi
Tercih edilen video oynatıcısı
Dahili oynatıcı
- VLC
- MPV
- Web Video Yayını
- İnternet tarayıcısı
Uygulama bulunamadı
Geçmiş
İzlendi olarak işaretle
@@ -669,7 +663,6 @@
Sezon %1$d Bölüm %2$d tarihinde yayınlanacak
Yansıtılacak cihaz seç
Ekran yansıtma
- Fcast
CloudStream Viki
Güvenlik
Hesaplar
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index 010af23c9..c5e234f0d 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -248,7 +248,6 @@
Змінити розмір
Короткий зміст
Фільми
- Скопіювати посилання
Перезавантажити посилання
Документальні фільми
NSFW
@@ -257,7 +256,6 @@
Торент
Мітка якості
NSFW
- Переглянути в браузері
Несподівана помилка плеєра
Помилка завантаження, перевірте дозволи на зберігання
Епізод Chromecast
@@ -445,10 +443,6 @@
Спочатку встановіть розширення
Список відтворення HLS
Вбудований плеєр
- VLC
- MPV
- Web Video Cast
- Веббраузер
Ендінґ
Коротке повторення
Пропустити %s
@@ -620,7 +614,6 @@
Скинути
Наступний через %s
%1$d сезон %2$d епізод вийде через
- Fcast
Оберіть пристрій для трансляції
Трансляція через дзеркало
CloudStream Wiki
@@ -663,6 +656,5 @@
\n%s
Попередній перегляд повзунка
Ввімкнути мініатюру попереднього перегляду на повзунку
- MPV YTDL
Субтитри ще не завантажено
\ No newline at end of file
diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml
index 5a32dfe8a..06508bc9e 100644
--- a/app/src/main/res/values-ur/strings.xml
+++ b/app/src/main/res/values-ur/strings.xml
@@ -243,7 +243,6 @@
Chromecast mirror
ایپ میں چلائیں
%s میں چلائیں
- کاپی لنک
ڈاؤنلوڈ mirror
لنکس کو دوبارہ لوڈ کریں
سب ٹائٹلز ڈاؤن لوڈ
@@ -336,7 +335,6 @@
کوئی زیرنویس میں دیری نہیں
این ایس ایف ڈبلیو
آٹو ڈاؤن لوڈ
- browser میں چلائیں
بہت زیادہ سیٹ ہونے پر کم میموری والی ڈیوائس(جیسے کہ Android TV) پر کریشوں کا سبب بنتا ہے.
Remove site
Add a clone of an existing site, with a different URL
@@ -361,7 +359,6 @@
قرارداد اور عنوان
HDR
%s سے ان سبسکرائب کیا گیا
- ویب ویڈیو کاسٹ
18+
لاگ
https://example.com/example.mp4
@@ -427,11 +424,8 @@
حالت
سائز
زبان
- وی ایل سی
ترجیحی ویڈیو پلیئر
اندرونی پلیئر
- ایم پی وی
- ویب براؤزر
ایپ نہیں ملی
Recap
مخلوط اختتام
diff --git a/app/src/main/res/values-vi/array.xml b/app/src/main/res/values-vi/array.xml
index f363befda..c6ff1c4e2 100644
--- a/app/src/main/res/values-vi/array.xml
+++ b/app/src/main/res/values-vi/array.xml
@@ -153,32 +153,6 @@
- @string/show_title_key
-
- - @string/episode_action_chromecast_episode
- - @string/episode_action_chromecast_mirror
- - @string/episode_action_play_in_app
- - @string/episode_action_play_in_format
- - @string/episode_action_play_in_browser
- - @string/episode_action_copy_link
- - @string/episode_action_auto_download
- - @string/episode_action_download_mirror
- - @string/episode_action_download_subtitle
- - @string/episode_action_reload_links
-
-
-
- - 4
- - 5
- - 1
- - 2
- - 3
- - 9
- - 6
- - 7
- - 13
- - 8
-
-
- @string/automatic
- @string/phone_layout
diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml
index 53b19bd8b..5c4cd380e 100644
--- a/app/src/main/res/values-vi/strings.xml
+++ b/app/src/main/res/values-vi/strings.xml
@@ -243,8 +243,6 @@
Chiếu Chromecast
Xem với trình phát mặc định
Xem với trình phát %s
- Xem tại trình duyệt
- Sao chép liên kết
Tự động tải xuống
Nguồn tải xuống
Lấy link mới nhất
@@ -472,10 +470,6 @@
Hỗ trợ
Ngôn ngữ
Cài đặt tiện ích trước
- VLC
- MPV
- Web Video Cast
- Trình duyệt web
Không thấy ứng dụng
Tất cả ngôn ngữ
Tua %s
@@ -671,11 +665,9 @@
\n
\n%s
Xóa plugin
- Fcast
Ngày phát hành (Cũ đến mới)
Ẩn tên các nút điều khiển
Bật chế độ xem trước hình thu nhỏ trên seekbar
Xem trước Seekbar
- MPV YTDL
Chưa tải phụ đề
\ No newline at end of file
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index b8b8b4884..3c002c29a 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -258,8 +258,6 @@
Chromecast 鏡像
在應用程式中播放
在 %s 中播放
- 在瀏覽器中播放
- 複製連結
自動下載
下載鏡像
重新載入連結
@@ -482,10 +480,6 @@
HLS 播放清單
偏好影片播放器
內部播放器
- VLC
- MPV
- 網路影片播放
- 網頁瀏覽器
未找到應用程式
所有語言
跳過 %s
@@ -663,7 +657,6 @@
使用指紋、面容 ID、PIN、圖案和密碼解除鎖定應用程式。
由於多次嘗試失敗,此畫面已關閉。請重新啟動應用程式。
剪貼簿存取失敗,請再試一次。
- Fcast
複製失敗,請複製 logcat 內容並聯繫應用程式支援者。
無法開啟 CloudStream 的應用程式資訊頁面。
您的 CloudStream 資料已完成備份。儘管可能性非常低,但因不同裝置的行為都有所不同,在極少數情況下,您可能會無法存取本應用程式。此時請完全清除本應用程式的資料,再使用已有的備份進行還原。若因此造成任何不便,我們深感抱歉。
diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml
index ff85df32e..45e350439 100644
--- a/app/src/main/res/values-zh/strings.xml
+++ b/app/src/main/res/values-zh/strings.xml
@@ -259,8 +259,6 @@
Chromecast 镜像
在应用中播放
在 %s 中播放
- 在浏览器中播放
- 复制链接
自动下载
下载镜像
重新加载链接
@@ -483,10 +481,6 @@
HLS 播放列表
首选视频播放器
内部播放器
- VLC
- MPV
- 投屏
- 浏览器
未找到应用
所有语言
跳过 %s
@@ -665,7 +659,6 @@
在多次尝试失败后,提示将关闭。只需重启应用程序再试。
即将在 %s
CloudStream Wiki
- Fcast
选择投射设备
%1$d季%2$d集将在
投射镜像
@@ -674,7 +667,6 @@
打开本地视频
安全
访问智能手机或电脑上的 %s 并输入上述代码
- MPV YTDL
进度条预览
启用进度条预览缩略图
删除插件
diff --git a/app/src/main/res/values/array.xml b/app/src/main/res/values/array.xml
index b077997fe..a987420e9 100644
--- a/app/src/main/res/values/array.xml
+++ b/app/src/main/res/values/array.xml
@@ -50,24 +50,6 @@
- @string/nsfw
-
- - @string/player_settings_play_in_app
- - @string/player_settings_play_in_vlc
- - @string/player_settings_play_in_mpv
- - @string/player_settings_play_in_mpvytdl
- - @string/player_settings_play_in_web
- - @string/player_settings_play_in_browser
-
-
-
- - 1
- - 2
- - 5
- - 6
- - 4
- - 3
-
-
- @string/resolution_and_title
- @string/title
@@ -226,32 +208,6 @@
- @string/show_title_key
-
- - @string/episode_action_chromecast_episode
- - @string/episode_action_chromecast_mirror
- - @string/episode_action_play_in_app
- - @string/episode_action_play_in_format
- - @string/episode_action_play_in_browser
- - @string/episode_action_copy_link
- - @string/episode_action_auto_download
- - @string/episode_action_download_mirror
- - @string/episode_action_download_subtitle
- - @string/episode_action_reload_links
-
-
-
- - 4
- - 5
- - 1
- - 2
- - 3
- - 9
- - 6
- - 7
- - 13
- - 8
-
-
- @string/automatic
- @string/phone_layout
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 9d9362bec..56f2465d2 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -17,7 +17,7 @@
subtitle_settings_chromecast_key
quality_pref_key
quality_pref_mobile_data_key
- player_pref_key
+ player_default_key
prefer_limit_title_key
prefer_limit_title_rez_key
apk_installer_key
@@ -381,8 +381,6 @@
Cast mirror
Play in app
Play in %s
- Play in browser
- Copy link
Auto download
Download mirror
Reload links
@@ -662,12 +660,6 @@
HLS Playlist
Preferred video player
Internal player
- VLC
- MPV
- MPV YTDL
- Web Video Cast
- Fcast
- Web browser
Select cast device
App not found
All Languages
diff --git a/app/src/main/res/xml/settings_player.xml b/app/src/main/res/xml/settings_player.xml
index 73f9bb5bf..a2575e315 100644
--- a/app/src/main/res/xml/settings_player.xml
+++ b/app/src/main/res/xml/settings_player.xml
@@ -22,7 +22,7 @@