From 1d5561068574b5c783e052751ee16fcc8ca11c93 Mon Sep 17 00:00:00 2001
From: Cloudburst <18114966+C10udburst@users.noreply.github.com>
Date: Sun, 8 Sep 2024 22:51:19 +0200
Subject: [PATCH 1/4] initial start on the VideoClickAction api
---
app/src/main/AndroidManifest.xml | 9 +---
.../lagradost/cloudstream3/MainActivity.kt | 2 +
.../cloudstream3/actions/OpenInAppAction.kt | 48 +++++++++++++++++++
.../cloudstream3/actions/VideoClickAction.kt | 44 +++++++++++++++++
.../lagradost/cloudstream3/plugins/Plugin.kt | 14 ++++++
.../cloudstream3/plugins/PluginManager.kt | 7 +++
.../cloudstream3/ui/result/EpisodeAdapter.kt | 5 ++
.../ui/result/ResultViewModel2.kt | 37 ++++++++++++++
8 files changed, 158 insertions(+), 8 deletions(-)
create mode 100644 app/src/main/java/com/lagradost/cloudstream3/actions/OpenInAppAction.kt
create mode 100644 app/src/main/java/com/lagradost/cloudstream3/actions/VideoClickAction.kt
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" />
-
-
-
-
-
-
-
? = null
+
//TODO REFACTOR AF
open class ResultResume(
val packageString: String,
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..4673af3f3
--- /dev/null
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/OpenInAppAction.kt
@@ -0,0 +1,48 @@
+package com.lagradost.cloudstream3.actions
+
+import android.app.Activity
+import android.content.ComponentName
+import android.content.Intent
+import com.lagradost.cloudstream3.MainActivity.Companion.activityResultLauncher
+import com.lagradost.cloudstream3.R
+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.ui.result.txt
+import com.lagradost.cloudstream3.utils.AppContextUtils.isAppInstalled
+
+abstract class OpenInAppAction(
+ open val appName: UiText,
+ open val packageName: String,
+ private val intentClass: String?,
+ private val action: String = Intent.ACTION_VIEW
+): VideoClickAction() {
+ override val name: UiText
+ get() = txt(R.string.episode_action_play_in_format, appName)
+
+ override fun shouldShow(activity: Activity?, video: ResultEpisode) = activity?.isAppInstalled(packageName) == true
+
+ override fun runAction(
+ activity: Activity?,
+ video: ResultEpisode,
+ result: LinkLoadingResult,
+ index: Int?
+ ) {
+ if (activity == null) return
+ val intent = Intent(action)
+ intent.setPackage(packageName)
+ if (intentClass != null) {
+ intent.component = ComponentName(packageName, intentClass)
+ }
+ putExtra(activity, intent, video, result, index)
+
+ // TODO: understand the spaghetti that is ResultResume
+ activityResultLauncher?.launch(intent)
+ }
+
+ /**
+ * Before intent is sent, this function is called to put extra data into the intent.
+ * @see VideoClickAction.runAction
+ * */
+ abstract fun putExtra(activity: Activity, intent: Intent, video: ResultEpisode, result: LinkLoadingResult, index: Int?)
+}
\ 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..ab188a702
--- /dev/null
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/VideoClickAction.kt
@@ -0,0 +1,44 @@
+package com.lagradost.cloudstream3.actions
+
+import android.app.Activity
+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
+
+object VideoClickActionHolder {
+ val allVideoClickActions = threadSafeListOf()
+
+ private const val ACTION_ID_OFFSET = 1000
+
+ fun makeOptionMap(activity: Activity?, video: ResultEpisode) = allVideoClickActions
+ .filter { it.shouldShow(activity, video) }
+ .mapIndexed { index, it -> it.name to index + ACTION_ID_OFFSET }
+
+ fun getActionById(id: Int): VideoClickAction? = allVideoClickActions.getOrNull(id - ACTION_ID_OFFSET)
+}
+
+abstract class VideoClickAction {
+ abstract val name: UiText
+
+ /** if true, the app will show dialog to select source - result.links[index] */
+ val oneSource : Boolean = false
+
+ /** Which type of sources this action can handle. */
+ 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
+
+ abstract fun shouldShow(activity: Activity?, video: ResultEpisode): Boolean
+
+ /**
+ * This function is called when the action is clicked.
+ * @param activity 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(activity: Activity?, video: ResultEpisode, result: LinkLoadingResult, index: Int?)
+}
\ No newline at end of file
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/result/EpisodeAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt
index 4cd9cc9ea..a19adc4e8 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
@@ -30,6 +30,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
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..99fc65f81 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
@@ -41,6 +41,7 @@ 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
@@ -1576,6 +1577,9 @@ class ResultViewModel2 : ViewModel() {
when (click.action) {
ACTION_SHOW_OPTIONS -> {
val options = mutableListOf>()
+
+ VideoClickActionHolder.makeOptionMap(activity, click.data)
+
if (activity?.isConnectedToChromecast() == true) {
options.addAll(
listOf(
@@ -1615,6 +1619,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 =
@@ -1933,6 +1941,35 @@ class ResultViewModel2 : ViewModel() {
// Kinda dirty to reload all episodes :(
reloadEpisodes()
}
+
+ else -> {
+ val action = VideoClickActionHolder.getActionById(click.action) ?: return
+
+ // TODO: use action.sourceTypes
+ if (action.oneSource) {
+ loadLinks(click.data, isVisible = true, LoadType.ExternalApp) { links ->
+ action.runAction(
+ activity,
+ click.data,
+ links,
+ null
+ )
+ }
+ } else {
+ acquireSingleLink(
+ click.data,
+ LoadType.ExternalApp,
+ action.name
+ ) { (result, index) ->
+ action.runAction(
+ activity,
+ click.data,
+ result,
+ index
+ )
+ }
+ }
+ }
}
}
From 9505ca259255c545471278a071339d8dabf47041 Mon Sep 17 00:00:00 2001
From: Cloudburst <18114966+C10udburst@users.noreply.github.com>
Date: Mon, 9 Sep 2024 17:21:45 +0200
Subject: [PATCH 2/4] move all app actions to new api, handle some todos
---
.../lagradost/cloudstream3/CommonActivity.kt | 28 +-
.../lagradost/cloudstream3/MainActivity.kt | 105 +-----
.../cloudstream3/actions/OpenInAppAction.kt | 93 ++++-
.../cloudstream3/actions/VideoClickAction.kt | 32 +-
.../cloudstream3/actions/temp/MpvKtPackage.kt | 67 ++++
.../cloudstream3/actions/temp/MpvPackage.kt | 61 ++++
.../actions/temp/PlayInBrowserAction.kt | 41 +++
.../cloudstream3/actions/temp/TestAction.kt | 47 +++
.../cloudstream3/actions/temp/VlcPackage.kt | 55 +++
.../actions/temp/WebVideoCastPackage.kt | 61 ++++
.../cloudstream3/ui/ControllerActivity.kt | 16 +-
.../ui/player/DownloadFileGenerator.kt | 6 +-
.../ui/player/ExtractorLinkGenerator.kt | 9 +-
.../cloudstream3/ui/player/IGenerator.kt | 65 ++--
.../cloudstream3/ui/player/LinkGenerator.kt | 6 +-
.../ui/player/PlayerGeneratorViewModel.kt | 7 +-
.../ui/player/RepoLinkGenerator.kt | 10 +-
.../ui/result/ResultViewModel2.kt | 345 ++----------------
18 files changed, 552 insertions(+), 502 deletions(-)
create mode 100644 app/src/main/java/com/lagradost/cloudstream3/actions/temp/MpvKtPackage.kt
create mode 100644 app/src/main/java/com/lagradost/cloudstream3/actions/temp/MpvPackage.kt
create mode 100644 app/src/main/java/com/lagradost/cloudstream3/actions/temp/PlayInBrowserAction.kt
create mode 100644 app/src/main/java/com/lagradost/cloudstream3/actions/temp/TestAction.kt
create mode 100644 app/src/main/java/com/lagradost/cloudstream3/actions/temp/VlcPackage.kt
create mode 100644 app/src/main/java/com/lagradost/cloudstream3/actions/temp/WebVideoCastPackage.kt
diff --git a/app/src/main/java/com/lagradost/cloudstream3/CommonActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/CommonActivity.kt
index ee3a5d122..50e6d8c98 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/CommonActivity.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/CommonActivity.kt
@@ -30,15 +30,14 @@ import com.google.android.material.chip.ChipGroup
import com.google.android.material.navigationrail.NavigationRailView
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey
-import com.lagradost.cloudstream3.MainActivity.Companion.resumeApps
+import com.lagradost.cloudstream3.actions.OpenInAppAction
+import com.lagradost.cloudstream3.actions.VideoClickActionHolder
import com.lagradost.cloudstream3.databinding.ToastBinding
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.ui.player.PlayerEventType
-import com.lagradost.cloudstream3.ui.result.ResultFragment
import com.lagradost.cloudstream3.ui.result.UiText
import com.lagradost.cloudstream3.ui.settings.Globals.updateTv
import com.lagradost.cloudstream3.utils.AppContextUtils.isRtl
-import com.lagradost.cloudstream3.utils.DataStoreHelper
import com.lagradost.cloudstream3.utils.Event
import com.lagradost.cloudstream3.utils.UIHelper
import com.lagradost.cloudstream3.utils.UIHelper.hasPIPPermission
@@ -218,20 +217,15 @@ object CommonActivity {
componentActivity.updateTv()
NewPipe.init(DownloaderTestImpl.getInstance())
- for (resumeApp in resumeApps) {
- resumeApp.launcher =
- componentActivity.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
- val resultCode = result.resultCode
- val data = result.data
- if (resultCode == AppCompatActivity.RESULT_OK && data != null && resumeApp.position != null && resumeApp.duration != null) {
- val pos = resumeApp.getPosition(data)
- val dur = resumeApp.getDuration(data)
- if (dur > 0L && pos > 0L)
- DataStoreHelper.setViewPos(getKey(resumeApp.lastId), pos, dur)
- removeKey(resumeApp.lastId)
- ResultFragment.updateUI()
- }
- }
+ MainActivity.activityResultLauncher = componentActivity.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
+ if (result.resultCode == AppCompatActivity.RESULT_OK) {
+ val actionUid = getKey("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 d99283593..0625f572e 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt
@@ -198,110 +198,7 @@ import kotlin.system.exitProcess
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")
-
- val activityResultLauncher: ActivityResultLauncher? = null
-
- //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
index 4673af3f3..534102fea 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/actions/OpenInAppAction.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/OpenInAppAction.kt
@@ -1,20 +1,86 @@
package com.lagradost.cloudstream3.actions
import android.app.Activity
+import android.content.ActivityNotFoundException
import android.content.ComponentName
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.Coroutines.main
+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(activity: Activity,
+ 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 = activity.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"
+
+ //With subtitles it doesn't work for no reason :(
+ /*for (sub in result.subs) {
+ val normalizedName = sub.name.replace("[^a-zA-Z0-9 ]".toRegex(), "")
+ val language = fromLanguageToTwoLetters(sub.name, true) ?: "und"
+ text += "\n#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"${normalizedName}\",DEFAULT=NO,AUTOSELECT=NO,FORCED=NO,LANGUAGE=\"${language}\",URI=\"${sub.url}\""
+ }*/
+
+ for (link in result.links) {
+ text += "\n#EXTINF:, ${link.name}\n${link.url}"
+ }
+ outputFile.writeText(text)
+
+ intent.setDataAndType(
+ FileProvider.getUriForFile(
+ activity,
+ activity.applicationContext.packageName + ".provider",
+ outputFile
+ ), "video/*"
+ )
+ }
+}
abstract class OpenInAppAction(
open val appName: UiText,
open val packageName: String,
- private val intentClass: String?,
+ private val intentClass: String? = null,
private val action: String = Intent.ACTION_VIEW
): VideoClickAction() {
override val name: UiText
@@ -35,9 +101,21 @@ abstract class OpenInAppAction(
intent.component = ComponentName(packageName, intentClass)
}
putExtra(activity, intent, video, result, index)
-
- // TODO: understand the spaghetti that is ResultResume
- activityResultLauncher?.launch(intent)
+ setKey("last_opened_id", video.id)
+ try {
+ CoroutineScope(Dispatchers.IO).launch {
+ activityResultLauncher?.launch(intent)
+ }
+ } 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)
+ }
+ }
+ }
}
/**
@@ -45,4 +123,11 @@ abstract class OpenInAppAction(
* @see VideoClickAction.runAction
* */
abstract fun putExtra(activity: Activity, 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 read 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
index ab188a702..75d3747ae 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/actions/VideoClickAction.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/VideoClickAction.kt
@@ -1,6 +1,14 @@
package com.lagradost.cloudstream3.actions
import android.app.Activity
+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.TestAction
+import com.lagradost.cloudstream3.actions.temp.VlcPackage
+import com.lagradost.cloudstream3.actions.temp.WebVideoCastPackage
import com.lagradost.cloudstream3.ui.result.LinkLoadingResult
import com.lagradost.cloudstream3.ui.result.ResultEpisode
import com.lagradost.cloudstream3.ui.result.UiText
@@ -8,29 +16,43 @@ import com.lagradost.cloudstream3.utils.Coroutines.threadSafeListOf
import com.lagradost.cloudstream3.utils.ExtractorLinkType
object VideoClickActionHolder {
- val allVideoClickActions = threadSafeListOf()
+ val allVideoClickActions = threadSafeListOf(
+ PlayInBrowserAction(), VlcPackage(), TestAction(),
+ MpvPackage(), MpvYTDLPackage(),
+ WebVideoCastPackage(), MpvKtPackage(), MpvKtPreviewPackage()
+ )
private const val ACTION_ID_OFFSET = 1000
fun makeOptionMap(activity: Activity?, video: ResultEpisode) = allVideoClickActions
- .filter { it.shouldShow(activity, video) }
- .mapIndexed { index, it -> it.name to index + ACTION_ID_OFFSET }
+ // We need to have index before filtering
+ .mapIndexed { index, it -> it to index + 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 }
}
abstract class VideoClickAction {
abstract val name: UiText
/** if true, the app will show dialog to select source - result.links[index] */
- val oneSource : Boolean = false
+ open val oneSource : Boolean = false
+
+ /** if true, this action could be selected as default one press action in settings */
+ open val canBeDefault: Boolean = false
/** Which type of sources this action can handle. */
- val sourceTypes: Set = ExtractorLinkType.entries.toSet()
+ 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.simpleName}"
+
abstract fun shouldShow(activity: Activity?, video: ResultEpisode): Boolean
/**
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..57f564d24
--- /dev/null
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/MpvKtPackage.kt
@@ -0,0 +1,67 @@
+package com.lagradost.cloudstream3.actions.temp
+
+import android.app.Activity
+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(
+ activity: Activity,
+ intent: Intent,
+ video: ResultEpisode,
+ result: LinkLoadingResult,
+ index: Int?
+ ) {
+ val link = result.links[index ?: 0]
+
+ intent.apply {
+ putExtra("subs", result.subs.map { it.url.toUri() }.toTypedArray())
+ putExtra("subs.name", result.subs.map { it.name }.toTypedArray())
+ putExtra("subs.filename", result.subs.map { it.name }.toTypedArray())
+ setDataAndType(Uri.parse(link.url), "video/*")
+ // m3u8 plays, but changing sources feature is not available
+ // makeTempM3U8Intent(activity, this, result)
+ putExtra("secure_uri", true)
+ putExtra("return_result", true)
+ //putExtra("headers", link.headers.flatMap { listOf(it.key, it.value) }.toTypedArray())
+ val position = getViewPos(video.id)?.position
+ if (position != null)
+ putExtra("position", position.toInt())
+ }
+ }
+
+ 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..7ff05a3f1
--- /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.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
+
+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 val sourceTypes = setOf(
+ ExtractorLinkType.VIDEO,
+ ExtractorLinkType.DASH,
+ ExtractorLinkType.M3U8
+ )
+
+ override fun putExtra(
+ activity: Activity,
+ intent: Intent,
+ video: ResultEpisode,
+ result: LinkLoadingResult,
+ index: Int?
+ ) {
+ intent.apply {
+ putExtra("subs", result.subs.map { it.url.toUri() }.toTypedArray())
+ putExtra("subs.name", result.subs.map { it.name }.toTypedArray())
+ putExtra("subs.filename", result.subs.map { it.name }.toTypedArray())
+ makeTempM3U8Intent(activity, this, result)
+ putExtra("secure_uri", true)
+ putExtra("return_result", true)
+ val position = getViewPos(video.id)?.position
+ if (position != null)
+ putExtra("position", position.toInt())
+ }
+ }
+
+ 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..6d6f78f51
--- /dev/null
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/PlayInBrowserAction.kt
@@ -0,0 +1,41 @@
+package com.lagradost.cloudstream3.actions.temp
+
+import android.app.Activity
+import android.content.Intent
+import android.net.Uri
+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("Play in browser")
+
+ override val oneSource = true
+
+ override val sourceTypes: Set = setOf(
+ ExtractorLinkType.VIDEO,
+ ExtractorLinkType.DASH,
+ ExtractorLinkType.M3U8
+ )
+
+ override fun shouldShow(activity: Activity?, video: ResultEpisode) = true
+
+ override fun runAction(
+ activity: Activity?,
+ video: ResultEpisode,
+ result: LinkLoadingResult,
+ index: Int?
+ ) {
+ if (index == null) return
+ try {
+ val i = Intent(Intent.ACTION_VIEW)
+ i.data = Uri.parse(result.links[index].url)
+ activity?.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/TestAction.kt b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/TestAction.kt
new file mode 100644
index 000000000..3c7464a05
--- /dev/null
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/TestAction.kt
@@ -0,0 +1,47 @@
+package com.lagradost.cloudstream3.actions.temp
+
+import android.app.Activity
+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.AppUtils.toJson
+
+class TestAction: VideoClickAction() {
+ override val name = txt("Test action")
+
+ override fun shouldShow(activity: Activity?, video: ResultEpisode): Boolean {
+ return true
+ }
+
+ override fun runAction(
+ activity: Activity?,
+ video: ResultEpisode,
+ result: LinkLoadingResult,
+ index: Int?
+ ) {
+ // Show dialog box
+ val text = """
+Result links:
+${result.links.joinToString("\n") { if (it.url.length > 50) it.url.take(25) + "..." + it.url.takeLast(25) else it.url }}
+Result subs:
+${result.subs.joinToString("\n") { if (it.url.length > 50) it.url.take(25) + "..." + it.url.takeLast(25) else it.url }}
+Video:
+${video.toJson()}
+ """.trim()
+
+
+ activity?.runOnUiThread {
+ val dialog = android.app.AlertDialog.Builder(activity)
+ dialog.apply {
+ setTitle("Action: ${video.name}")
+ setMessage(text)
+ setPositiveButton("OK") { dialog, _ ->
+ dialog.dismiss()
+ }
+ }
+ dialog.show()
+ }
+
+ }
+}
\ 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..7f3b34d01
--- /dev/null
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/VlcPackage.kt
@@ -0,0 +1,55 @@
+package com.lagradost.cloudstream3.actions.temp
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Build
+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
+
+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
+
+ // https://wiki.videolan.org/Android_Player_Intents/
+ override fun putExtra(
+ activity: Activity,
+ intent: Intent,
+ video: ResultEpisode,
+ result: LinkLoadingResult,
+ index: Int?
+ ) {
+
+ makeTempM3U8Intent(activity, intent, result)
+
+ val position = getViewPos(video.id)?.position ?: 0L
+
+ intent.putExtra("from_start", false)
+ intent.putExtra("position", position)
+ }
+
+ 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..468b2e4e4
--- /dev/null
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/WebVideoCastPackage.kt
@@ -0,0 +1,61 @@
+package com.lagradost.cloudstream3.actions.temp
+
+import android.app.Activity
+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
+
+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(
+ activity: Activity,
+ 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?) {
+
+ }
+}
\ No newline at end of file
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..b6556cbfe 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,7 +303,8 @@ 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)
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..89ce7974f 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,31 @@ 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_FCAST = 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 +46,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/ResultViewModel2.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt
index 99fc65f81..bbb835e1c 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,17 +25,6 @@ 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.*
@@ -48,20 +32,22 @@ 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_FCAST
+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
@@ -70,6 +56,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
@@ -102,7 +89,6 @@ 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 */
@@ -804,7 +790,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_CHROMECAST, callback = {
it.first?.let { link ->
currentLinks.add(link)
}
@@ -955,7 +941,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) { data ->
startChromecast(activity, result, data.links, data.subs, 0)
}
}
@@ -1301,7 +1287,7 @@ class ResultViewModel2 : ViewModel() {
private fun loadLinks(
result: ResultEpisode,
isVisible: Boolean,
- type: LoadType,
+ sourceTypes: Set = LOADTYPE_ALL,
clearCache: Boolean = false,
work: suspend (CoroutineScope.(LinkLoadingResult) -> Unit)
) {
@@ -1310,7 +1296,7 @@ class ResultViewModel2 : ViewModel() {
val links = loadLinks(
result,
isVisible = isVisible,
- type = type,
+ sourceTypes = sourceTypes,
clearCache = clearCache
)
if (!this.isActive) return@ioSafe
@@ -1321,11 +1307,11 @@ class ResultViewModel2 : ViewModel() {
private var currentLoadLinkJob: Job? = null
private fun acquireSingleLink(
result: ResultEpisode,
- type: LoadType,
+ sourceTypes: Set,
text: UiText,
callback: (Pair) -> Unit,
) {
- loadLinks(result, isVisible = true, type) { links ->
+ loadLinks(result, isVisible = true, sourceTypes) { links ->
// Could not find a better way to do this
val context = AcraApplication.context
postPopup(
@@ -1345,7 +1331,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) })
@@ -1358,7 +1344,7 @@ class ResultViewModel2 : ViewModel() {
private suspend fun CoroutineScope.loadLinks(
result: ResultEpisode,
isVisible: Boolean,
- type: LoadType,
+ sourceTypes: Set = LOADTYPE_ALL,
clearCache: Boolean = false,
): LinkLoadingResult {
val tempGenerator = RepoLinkGenerator(listOf(result))
@@ -1372,7 +1358,7 @@ class ResultViewModel2 : ViewModel() {
}
try {
updatePage()
- tempGenerator.generateLinks(clearCache, type, { (link, _) ->
+ tempGenerator.generateLinks(clearCache, sourceTypes, { (link, _) ->
if (link != null) {
links += link
updatePage()
@@ -1390,185 +1376,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)
}
@@ -1578,8 +1390,6 @@ class ResultViewModel2 : ViewModel() {
ACTION_SHOW_OPTIONS -> {
val options = mutableListOf>()
- VideoClickActionHolder.makeOptionMap(activity, click.data)
-
if (activity?.isConnectedToChromecast() == true) {
options.addAll(
listOf(
@@ -1597,20 +1407,8 @@ class ResultViewModel2 : ViewModel() {
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,
@@ -1724,7 +1522,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 {
@@ -1754,7 +1552,7 @@ class ResultViewModel2 : ViewModel() {
loadLinks(
click.data,
isVisible = false,
- type = LoadType.InApp,
+ LOADTYPE_INAPP,
clearCache = true
)
}
@@ -1767,7 +1565,7 @@ class ResultViewModel2 : ViewModel() {
ACTION_CHROME_CAST_MIRROR -> {
acquireSingleLink(
click.data,
- LoadType.Chromecast,
+ LOADTYPE_CHROMECAST,
txt(R.string.episode_action_chromecast_mirror)
) { (result, index) ->
startChromecast(activity, click.data, result.links, result.subs, index)
@@ -1784,7 +1582,7 @@ class ResultViewModel2 : ViewModel() {
acquireSingleLink(
click.data,
- LoadType.Fcast,
+ LOADTYPE_FCAST,
txt(R.string.episode_action_cast_mirror)
) { (result, index) ->
val host = device?.host ?: return@acquireSingleLink
@@ -1807,24 +1605,10 @@ class ResultViewModel2 : ViewModel() {
}
}
- 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,
+ LOADTYPE_ALL,
txt(R.string.episode_action_copy_link)
) { (result, index) ->
val link = result.links[index]
@@ -1836,70 +1620,6 @@ class ResultViewModel2 : ViewModel() {
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 =
@@ -1915,7 +1635,7 @@ class ResultViewModel2 : ViewModel() {
if (currentResponse?.type == TvType.CustomMedia) {
generator?.generateLinks(
clearCache = true,
- LoadType.Unknown,
+ LOADTYPE_ALL,
callback = {},
subtitleCallback = {})
} else {
@@ -1945,20 +1665,12 @@ class ResultViewModel2 : ViewModel() {
else -> {
val action = VideoClickActionHolder.getActionById(click.action) ?: return
+ activity?.setKey("last_click_action", action.uniqueId())
// TODO: use action.sourceTypes
if (action.oneSource) {
- loadLinks(click.data, isVisible = true, LoadType.ExternalApp) { links ->
- action.runAction(
- activity,
- click.data,
- links,
- null
- )
- }
- } else {
acquireSingleLink(
click.data,
- LoadType.ExternalApp,
+ action.sourceTypes,
action.name
) { (result, index) ->
action.runAction(
@@ -1968,6 +1680,15 @@ class ResultViewModel2 : ViewModel() {
index
)
}
+ } else {
+ loadLinks(click.data, isVisible = true, action.sourceTypes) { links ->
+ action.runAction(
+ activity,
+ click.data,
+ links,
+ null
+ )
+ }
}
}
}
@@ -2077,7 +1798,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 {
From 6f76352cbea21312c02f0306e996ef470f7a2ebd Mon Sep 17 00:00:00 2001
From: Cloudburst <18114966+C10udburst@users.noreply.github.com>
Date: Tue, 10 Sep 2024 21:17:36 +0200
Subject: [PATCH 3/4] move all possible actions to new api, handle some todos
---
.../lagradost/cloudstream3/MainActivity.kt | 12 +--
.../cloudstream3/actions/OpenInAppAction.kt | 46 ++++++-----
.../cloudstream3/actions/VideoClickAction.kt | 35 ++++++--
.../cloudstream3/actions/temp/MpvKtPackage.kt | 14 ++--
.../cloudstream3/actions/temp/MpvPackage.kt | 22 ++---
.../actions/temp/PlayInBrowserAction.kt | 14 ++--
.../cloudstream3/actions/temp/TestAction.kt | 38 ++-------
.../cloudstream3/actions/temp/VlcPackage.kt | 10 ++-
.../actions/temp/WebVideoCastPackage.kt | 9 +-
.../actions/temp/fcast/FcastAction.kt | 66 +++++++++++++++
.../temp}/fcast/FcastManager.kt | 2 +-
.../temp}/fcast/FcastSession.kt | 2 +-
.../{utils => actions/temp}/fcast/Packets.kt | 2 +-
.../cloudstream3/ui/ControllerActivity.kt | 3 +-
.../cloudstream3/ui/player/IGenerator.kt | 6 --
.../cloudstream3/ui/result/EpisodeAdapter.kt | 25 +-----
.../ui/result/ResultViewModel2.kt | 82 ++++++-------------
.../ui/settings/SettingsPlayer.kt | 18 ++--
app/src/main/res/values/strings.xml | 2 +-
app/src/main/res/xml/settings_player.xml | 2 +-
20 files changed, 214 insertions(+), 196 deletions(-)
create mode 100644 app/src/main/java/com/lagradost/cloudstream3/actions/temp/fcast/FcastAction.kt
rename app/src/main/java/com/lagradost/cloudstream3/{utils => actions/temp}/fcast/FcastManager.kt (98%)
rename app/src/main/java/com/lagradost/cloudstream3/{utils => actions/temp}/fcast/FcastSession.kt (96%)
rename app/src/main/java/com/lagradost/cloudstream3/{utils => actions/temp}/fcast/Packets.kt (95%)
diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt
index 0625f572e..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,16 +186,6 @@ 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 {
var activityResultLauncher: ActivityResultLauncher? = null
diff --git a/app/src/main/java/com/lagradost/cloudstream3/actions/OpenInAppAction.kt b/app/src/main/java/com/lagradost/cloudstream3/actions/OpenInAppAction.kt
index 534102fea..45e61f2a8 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/actions/OpenInAppAction.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/OpenInAppAction.kt
@@ -3,6 +3,7 @@ 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
@@ -36,9 +37,10 @@ fun updateDurationAndPosition(position: Long, duration: Long) {
* 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(activity: Activity,
- intent: Intent,
- result: LinkLoadingResult) {
+fun makeTempM3U8Intent(
+ context: Context,
+ intent: Intent,
+ result: LinkLoadingResult) {
intent.apply {
addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
addFlags(Intent.FLAG_GRANT_PREFIX_URI_PERMISSION)
@@ -46,33 +48,35 @@ fun makeTempM3U8Intent(activity: Activity,
addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
}
- val outputDir = activity.cacheDir
+ 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"
+ var text = "#EXTM3U\n#EXT-X-VERSION:3"
- //With subtitles it doesn't work for no reason :(
+ 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(), "")
- val language = fromLanguageToTwoLetters(sub.name, true) ?: "und"
- text += "\n#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"${normalizedName}\",DEFAULT=NO,AUTOSELECT=NO,FORCED=NO,LANGUAGE=\"${language}\",URI=\"${sub.url}\""
+ text += "\n#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"${normalizedName}\",DEFAULT=NO,AUTOSELECT=NO,FORCED=NO,LANGUAGE=\"${sub.languageCode}\",URI=\"${sub.url}\""
}*/
- for (link in result.links) {
- text += "\n#EXTINF:, ${link.name}\n${link.url}"
- }
+ text += "\n#EXT-X-ENDLIST"
+
outputFile.writeText(text)
intent.setDataAndType(
FileProvider.getUriForFile(
- activity,
- activity.applicationContext.packageName + ".provider",
+ context,
+ context.applicationContext.packageName + ".provider",
outputFile
- ), "video/*"
+ ), "application/x-mpegURL"
)
}
}
@@ -86,21 +90,23 @@ abstract class OpenInAppAction(
override val name: UiText
get() = txt(R.string.episode_action_play_in_format, appName)
- override fun shouldShow(activity: Activity?, video: ResultEpisode) = activity?.isAppInstalled(packageName) == true
+ override val isPlayer = true
+
+ override fun shouldShow(context: Context?, video: ResultEpisode?) = context?.isAppInstalled(packageName) == true
override fun runAction(
- activity: Activity?,
+ context: Context?,
video: ResultEpisode,
result: LinkLoadingResult,
index: Int?
) {
- if (activity == null) return
+ if (context == null) return
val intent = Intent(action)
intent.setPackage(packageName)
if (intentClass != null) {
intent.component = ComponentName(packageName, intentClass)
}
- putExtra(activity, intent, video, result, index)
+ putExtra(context, intent, video, result, index)
setKey("last_opened_id", video.id)
try {
CoroutineScope(Dispatchers.IO).launch {
@@ -122,11 +128,11 @@ abstract class OpenInAppAction(
* Before intent is sent, this function is called to put extra data into the intent.
* @see VideoClickAction.runAction
* */
- abstract fun putExtra(activity: Activity, intent: Intent, video: ResultEpisode, result: LinkLoadingResult, index: Int?)
+ 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 read duration and position.
+ * You can use it to for example update duration and position.
* @see updateDurationAndPosition
*/
abstract fun onResult(activity: Activity, intent: Intent?)
diff --git a/app/src/main/java/com/lagradost/cloudstream3/actions/VideoClickAction.kt b/app/src/main/java/com/lagradost/cloudstream3/actions/VideoClickAction.kt
index 75d3747ae..a19553901 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/actions/VideoClickAction.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/VideoClickAction.kt
@@ -1,6 +1,8 @@
package com.lagradost.cloudstream3.actions
import android.app.Activity
+import android.content.Context
+import com.lagradost.api.Log
import com.lagradost.cloudstream3.actions.temp.MpvKtPackage
import com.lagradost.cloudstream3.actions.temp.MpvKtPreviewPackage
import com.lagradost.cloudstream3.actions.temp.MpvPackage
@@ -9,24 +11,31 @@ import com.lagradost.cloudstream3.actions.temp.PlayInBrowserAction
import com.lagradost.cloudstream3.actions.temp.TestAction
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(), VlcPackage(), TestAction(),
MpvPackage(), MpvYTDLPackage(),
- WebVideoCastPackage(), MpvKtPackage(), MpvKtPreviewPackage()
+ 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 { index, it -> it to index + ACTION_ID_OFFSET }
+ .mapIndexed { id, it -> it to id + ACTION_ID_OFFSET }
.filter { it.first.shouldShow(activity, video) }
.map { it.first.name to it.second }
@@ -34,6 +43,16 @@ object VideoClickActionHolder {
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 {
@@ -42,8 +61,8 @@ abstract class VideoClickAction {
/** 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 one press action in settings */
- open val canBeDefault: 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()
@@ -51,16 +70,16 @@ abstract class VideoClickAction {
/** 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.simpleName}"
+ fun uniqueId() = "$sourcePlugin:${this::class.jvmName}"
- abstract fun shouldShow(activity: Activity?, video: ResultEpisode): Boolean
+ abstract fun shouldShow(context: Context?, video: ResultEpisode?): Boolean
/**
* This function is called when the action is clicked.
- * @param activity The current activity
+ * @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(activity: Activity?, video: ResultEpisode, result: LinkLoadingResult, index: Int?)
+ 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/MpvKtPackage.kt b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/MpvKtPackage.kt
index 57f564d24..f5ded49b8 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/actions/temp/MpvKtPackage.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/MpvKtPackage.kt
@@ -1,6 +1,7 @@
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
@@ -34,27 +35,28 @@ open class MpvKtPackage(
)
override fun putExtra(
- activity: Activity,
+ context: Context,
intent: Intent,
video: ResultEpisode,
result: LinkLoadingResult,
index: Int?
) {
- val link = result.links[index ?: 0]
+ val link = result.links.getOrNull(index ?: 0) ?: return
intent.apply {
putExtra("subs", result.subs.map { it.url.toUri() }.toTypedArray())
- putExtra("subs.name", result.subs.map { it.name }.toTypedArray())
- putExtra("subs.filename", result.subs.map { it.name }.toTypedArray())
setDataAndType(Uri.parse(link.url), "video/*")
+
// m3u8 plays, but changing sources feature is not available
// makeTempM3U8Intent(activity, this, result)
- putExtra("secure_uri", true)
- putExtra("return_result", true)
+
//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)
}
}
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
index 7ff05a3f1..4c66d0450 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/actions/temp/MpvPackage.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/MpvPackage.kt
@@ -1,6 +1,7 @@
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
@@ -13,6 +14,9 @@ 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,
@@ -26,14 +30,9 @@ open class MpvPackage(appName: String = "MPV", packageName: String = "is.xyz.mpv
packageName,
"is.xyz.mpv.MPVActivity"
) {
- override val sourceTypes = setOf(
- ExtractorLinkType.VIDEO,
- ExtractorLinkType.DASH,
- ExtractorLinkType.M3U8
- )
override fun putExtra(
- activity: Activity,
+ context: Context,
intent: Intent,
video: ResultEpisode,
result: LinkLoadingResult,
@@ -41,14 +40,15 @@ open class MpvPackage(appName: String = "MPV", packageName: String = "is.xyz.mpv
) {
intent.apply {
putExtra("subs", result.subs.map { it.url.toUri() }.toTypedArray())
- putExtra("subs.name", result.subs.map { it.name }.toTypedArray())
- putExtra("subs.filename", result.subs.map { it.name }.toTypedArray())
- makeTempM3U8Intent(activity, this, result)
- putExtra("secure_uri", true)
- putExtra("return_result", true)
+ 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)
}
}
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
index 6d6f78f51..39b689398 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/actions/temp/PlayInBrowserAction.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/PlayInBrowserAction.kt
@@ -1,6 +1,6 @@
package com.lagradost.cloudstream3.actions.temp
-import android.app.Activity
+import android.content.Context
import android.content.Intent
import android.net.Uri
import com.lagradost.cloudstream3.actions.VideoClickAction
@@ -15,25 +15,27 @@ class PlayInBrowserAction: VideoClickAction() {
override val oneSource = true
+ override val isPlayer = true
+
override val sourceTypes: Set = setOf(
ExtractorLinkType.VIDEO,
ExtractorLinkType.DASH,
ExtractorLinkType.M3U8
)
- override fun shouldShow(activity: Activity?, video: ResultEpisode) = true
+ override fun shouldShow(context: Context?, video: ResultEpisode?) = true
override fun runAction(
- activity: Activity?,
+ context: Context?,
video: ResultEpisode,
result: LinkLoadingResult,
index: Int?
) {
- if (index == null) return
+ val link = result.links.getOrNull(index ?: 0) ?: return
try {
val i = Intent(Intent.ACTION_VIEW)
- i.data = Uri.parse(result.links[index].url)
- activity?.startActivity(i)
+ i.data = Uri.parse(link.url)
+ context?.startActivity(i)
} catch (e: Exception) {
logError(e)
}
diff --git a/app/src/main/java/com/lagradost/cloudstream3/actions/temp/TestAction.kt b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/TestAction.kt
index 3c7464a05..c825202a1 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/actions/temp/TestAction.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/TestAction.kt
@@ -1,47 +1,27 @@
package com.lagradost.cloudstream3.actions.temp
-import android.app.Activity
+import android.content.Context
+import android.content.Intent
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
-import com.lagradost.cloudstream3.utils.AppUtils.toJson
class TestAction: VideoClickAction() {
override val name = txt("Test action")
- override fun shouldShow(activity: Activity?, video: ResultEpisode): Boolean {
- return true
- }
+ override fun shouldShow(context: Context?, video: ResultEpisode?) = true
override fun runAction(
- activity: Activity?,
+ context: Context?,
video: ResultEpisode,
result: LinkLoadingResult,
index: Int?
) {
- // Show dialog box
- val text = """
-Result links:
-${result.links.joinToString("\n") { if (it.url.length > 50) it.url.take(25) + "..." + it.url.takeLast(25) else it.url }}
-Result subs:
-${result.subs.joinToString("\n") { if (it.url.length > 50) it.url.take(25) + "..." + it.url.takeLast(25) else it.url }}
-Video:
-${video.toJson()}
- """.trim()
-
-
- activity?.runOnUiThread {
- val dialog = android.app.AlertDialog.Builder(activity)
- dialog.apply {
- setTitle("Action: ${video.name}")
- setMessage(text)
- setPositiveButton("OK") { dialog, _ ->
- dialog.dismiss()
- }
- }
- dialog.show()
- }
-
+ 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
index 7f3b34d01..ec824d4eb 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/actions/temp/VlcPackage.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/VlcPackage.kt
@@ -1,6 +1,7 @@
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
@@ -12,6 +13,9 @@ import com.lagradost.cloudstream3.ui.result.ResultEpisode
import com.lagradost.cloudstream3.ui.result.txt
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",
@@ -28,21 +32,21 @@ class VlcPackage: OpenInAppAction(
) {
override val oneSource = false
- // https://wiki.videolan.org/Android_Player_Intents/
override fun putExtra(
- activity: Activity,
+ context: Context,
intent: Intent,
video: ResultEpisode,
result: LinkLoadingResult,
index: Int?
) {
- makeTempM3U8Intent(activity, intent, result)
+ 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)
}
override fun onResult(activity: Activity, intent: Intent?) {
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
index 468b2e4e4..f8419f63c 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/actions/temp/WebVideoCastPackage.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/WebVideoCastPackage.kt
@@ -1,6 +1,7 @@
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
@@ -12,6 +13,8 @@ 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"
@@ -26,7 +29,7 @@ class WebVideoCastPackage: OpenInAppAction(
)
override fun putExtra(
- activity: Activity,
+ context: Context,
intent: Intent,
video: ResultEpisode,
result: LinkLoadingResult,
@@ -55,7 +58,5 @@ class WebVideoCastPackage: OpenInAppAction(
}
}
- override fun onResult(activity: Activity, intent: Intent?) {
-
- }
+ 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..f2f7621e8
--- /dev/null
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/fcast/FcastAction.kt
@@ -0,0 +1,66 @@
+package com.lagradost.cloudstream3.actions.temp.fcast
+
+import android.content.Context
+import com.lagradost.cloudstream3.AcraApplication.Companion.getActivity
+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")
+
+ 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,
+ "Select device",
+ 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(
+ "application/vnd.apple.mpegurl",
+ 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/ui/ControllerActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt
index b6556cbfe..4b5d680c3 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt
@@ -311,7 +311,8 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi
}
}, subtitleCallback = {
currentSubs.add(it)
- })
+ },
+ isCasting = true)
}
val sortedLinks = sortUrls(currentLinks)
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 89ce7974f..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
@@ -20,12 +20,6 @@ val LOADTYPE_CHROMECAST = setOf(
ExtractorLinkType.M3U8
)
-val LOADTYPE_FCAST = setOf(
- ExtractorLinkType.VIDEO,
- ExtractorLinkType.DASH,
- ExtractorLinkType.M3U8
-)
-
val LOADTYPE_ALL = ExtractorLinkType.entries.toSet()
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 a19adc4e8..0c754f513 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
@@ -34,10 +35,7 @@ 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
@@ -57,12 +55,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
@@ -74,22 +67,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 bbb835e1c..a330d5638 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
@@ -39,7 +39,6 @@ import com.lagradost.cloudstream3.ui.player.GeneratorPlayer
import com.lagradost.cloudstream3.ui.player.IGenerator
import com.lagradost.cloudstream3.ui.player.LOADTYPE_ALL
import com.lagradost.cloudstream3.ui.player.LOADTYPE_CHROMECAST
-import com.lagradost.cloudstream3.ui.player.LOADTYPE_FCAST
import com.lagradost.cloudstream3.ui.player.LOADTYPE_INAPP
import com.lagradost.cloudstream3.ui.player.LOADTYPE_INAPP_DOWNLOAD
import com.lagradost.cloudstream3.ui.player.RepoLinkGenerator
@@ -84,10 +83,6 @@ 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.util.concurrent.TimeUnit
@@ -790,7 +785,7 @@ class ResultViewModel2 : ViewModel() {
val generator = RepoLinkGenerator(listOf(episode))
val currentLinks = mutableSetOf()
val currentSubs = mutableSetOf()
- generator.generateLinks(clearCache = false, allowedTypes = LOADTYPE_CHROMECAST, callback = {
+ generator.generateLinks(clearCache = false, allowedTypes = LOADTYPE_INAPP_DOWNLOAD, callback = {
it.first?.let { link ->
currentLinks.add(link)
}
@@ -941,7 +936,7 @@ class ResultViewModel2 : ViewModel() {
isVisible: Boolean = true
) {
if (activity == null) return
- loadLinks(result, isVisible = isVisible, sourceTypes = LOADTYPE_CHROMECAST) { data ->
+ loadLinks(result, isVisible = isVisible, sourceTypes = LOADTYPE_CHROMECAST, isCasting = true) { data ->
startChromecast(activity, result, data.links, data.subs, 0)
}
}
@@ -1251,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,
@@ -1289,6 +1284,7 @@ class ResultViewModel2 : ViewModel() {
isVisible: Boolean,
sourceTypes: Set = LOADTYPE_ALL,
clearCache: Boolean = false,
+ isCasting: Boolean = false,
work: suspend (CoroutineScope.(LinkLoadingResult) -> Unit)
) {
currentLoadLinkJob?.cancel()
@@ -1297,7 +1293,8 @@ class ResultViewModel2 : ViewModel() {
result,
isVisible = isVisible,
sourceTypes = sourceTypes,
- clearCache = clearCache
+ clearCache = clearCache,
+ isCasting = isCasting
)
if (!this.isActive) return@ioSafe
work(links)
@@ -1309,9 +1306,10 @@ class ResultViewModel2 : ViewModel() {
result: ResultEpisode,
sourceTypes: Set,
text: UiText,
- callback: (Pair) -> Unit,
+ isCasting: Boolean = false,
+ callback: (Pair) -> Unit
) {
- loadLinks(result, isVisible = true, sourceTypes) { links ->
+ loadLinks(result, isVisible = true, sourceTypes, isCasting = isCasting) { links ->
// Could not find a better way to do this
val context = AcraApplication.context
postPopup(
@@ -1346,6 +1344,7 @@ class ResultViewModel2 : ViewModel() {
isVisible: Boolean,
sourceTypes: Set = LOADTYPE_ALL,
clearCache: Boolean = false,
+ isCasting: Boolean = false
): LinkLoadingResult {
val tempGenerator = RepoLinkGenerator(listOf(result))
@@ -1358,15 +1357,19 @@ class ResultViewModel2 : ViewModel() {
}
try {
updatePage()
- tempGenerator.generateLinks(clearCache, sourceTypes, { (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 {
@@ -1399,12 +1402,6 @@ 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)
options.addAll(
@@ -1566,45 +1563,13 @@ class ResultViewModel2 : ViewModel() {
acquireSingleLink(
click.data,
LOADTYPE_CHROMECAST,
- txt(R.string.episode_action_chromecast_mirror)
+ 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_COPY_LINK -> {
acquireSingleLink(
click.data,
@@ -1666,7 +1631,6 @@ class ResultViewModel2 : ViewModel() {
val action = VideoClickActionHolder.getActionById(click.action) ?: return
activity?.setKey("last_click_action", action.uniqueId())
- // TODO: use action.sourceTypes
if (action.oneSource) {
acquireSingleLink(
click.data,
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/strings.xml b/app/src/main/res/values/strings.xml
index b2ec8a760..7c7553208 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
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 @@
From e288c83c3d748bfc1b09c5337fffeebd90d28f54 Mon Sep 17 00:00:00 2001
From: Cloudburst <18114966+C10udburst@users.noreply.github.com>
Date: Tue, 17 Sep 2024 23:37:59 +0200
Subject: [PATCH 4/4] remove unused strings, address comment
---
.../cloudstream3/actions/OpenInAppAction.kt | 11 ++---
.../cloudstream3/actions/VideoClickAction.kt | 6 ++-
.../actions/temp/CopyClipboardAction.kt | 27 ++++++++++++
.../actions/temp/PlayInBrowserAction.kt | 3 +-
.../temp/{TestAction.kt => ViewM3U8Action.kt} | 7 ++-
.../cloudstream3/actions/temp/VlcPackage.kt | 11 ++++-
.../actions/temp/fcast/FcastAction.kt | 7 +--
.../cloudstream3/ui/result/EpisodeAdapter.kt | 1 -
.../ui/result/ResultViewModel2.kt | 12 -----
app/src/main/res/values-ajp/strings.xml | 8 ----
app/src/main/res/values-ar/strings.xml | 8 ----
app/src/main/res/values-ars/strings.xml | 2 -
app/src/main/res/values-as/strings.xml | 8 ----
app/src/main/res/values-bg/strings.xml | 6 ---
app/src/main/res/values-bn/strings.xml | 2 -
app/src/main/res/values-bp/strings.xml | 8 ----
app/src/main/res/values-cs/strings.xml | 8 ----
app/src/main/res/values-de/strings.xml | 7 ---
app/src/main/res/values-el/strings.xml | 7 ---
app/src/main/res/values-es/array.xml | 26 -----------
app/src/main/res/values-es/strings.xml | 8 ----
app/src/main/res/values-fr/strings.xml | 8 +---
app/src/main/res/values-hi/strings.xml | 2 -
app/src/main/res/values-hr/strings.xml | 8 ----
app/src/main/res/values-hu/strings.xml | 6 ---
app/src/main/res/values-in/strings.xml | 7 ---
app/src/main/res/values-it/strings.xml | 8 ----
app/src/main/res/values-iw/strings.xml | 6 ---
app/src/main/res/values-ja/strings.xml | 3 --
app/src/main/res/values-ko/strings.xml | 7 ---
app/src/main/res/values-lt/strings.xml | 5 ---
app/src/main/res/values-lv/strings.xml | 6 ---
app/src/main/res/values-mk/strings.xml | 7 ---
app/src/main/res/values-ml/strings.xml | 2 -
app/src/main/res/values-ms/strings.xml | 7 ---
app/src/main/res/values-my/strings.xml | 6 ---
app/src/main/res/values-nl/strings.xml | 6 ---
app/src/main/res/values-nn/strings.xml | 2 -
app/src/main/res/values-no/strings.xml | 6 ---
app/src/main/res/values-or/strings.xml | 4 --
app/src/main/res/values-pl/array.xml | 26 -----------
app/src/main/res/values-pl/strings.xml | 8 ----
app/src/main/res/values-pt/strings.xml | 7 ---
app/src/main/res/values-qt/strings.xml | 7 ---
app/src/main/res/values-ro/strings.xml | 7 ---
app/src/main/res/values-ru/strings.xml | 7 ---
app/src/main/res/values-sk/strings.xml | 2 -
app/src/main/res/values-so/strings.xml | 6 ---
app/src/main/res/values-sv/strings.xml | 7 ---
app/src/main/res/values-ta/strings.xml | 7 ---
app/src/main/res/values-tl/strings.xml | 2 -
app/src/main/res/values-tr/array.xml | 42 ------------------
app/src/main/res/values-tr/strings.xml | 7 ---
app/src/main/res/values-uk/strings.xml | 8 ----
app/src/main/res/values-ur/strings.xml | 6 ---
app/src/main/res/values-vi/array.xml | 26 -----------
app/src/main/res/values-vi/strings.xml | 8 ----
app/src/main/res/values-zh-rTW/strings.xml | 7 ---
app/src/main/res/values-zh/strings.xml | 8 ----
app/src/main/res/values/array.xml | 44 -------------------
app/src/main/res/values/strings.xml | 8 ----
61 files changed, 56 insertions(+), 483 deletions(-)
create mode 100644 app/src/main/java/com/lagradost/cloudstream3/actions/temp/CopyClipboardAction.kt
rename app/src/main/java/com/lagradost/cloudstream3/actions/temp/{TestAction.kt => ViewM3U8Action.kt} (80%)
diff --git a/app/src/main/java/com/lagradost/cloudstream3/actions/OpenInAppAction.kt b/app/src/main/java/com/lagradost/cloudstream3/actions/OpenInAppAction.kt
index 45e61f2a8..99c1ac38b 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/actions/OpenInAppAction.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/OpenInAppAction.kt
@@ -20,7 +20,6 @@ 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.Coroutines.main
import com.lagradost.cloudstream3.utils.DataStoreHelper
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -112,15 +111,11 @@ abstract class OpenInAppAction(
CoroutineScope(Dispatchers.IO).launch {
activityResultLauncher?.launch(intent)
}
+ } catch (_: ActivityNotFoundException) {
+ showToast(R.string.app_not_found_error, Toast.LENGTH_LONG)
} 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)
- }
- }
+ showToast(t.toString(), Toast.LENGTH_LONG)
}
}
diff --git a/app/src/main/java/com/lagradost/cloudstream3/actions/VideoClickAction.kt b/app/src/main/java/com/lagradost/cloudstream3/actions/VideoClickAction.kt
index a19553901..f66ed74d9 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/actions/VideoClickAction.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/VideoClickAction.kt
@@ -3,12 +3,13 @@ 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.TestAction
+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
@@ -21,7 +22,8 @@ import kotlin.reflect.jvm.jvmName
object VideoClickActionHolder {
val allVideoClickActions = threadSafeListOf(
- PlayInBrowserAction(), VlcPackage(), TestAction(),
+ PlayInBrowserAction(), CopyClipboardAction(),
+ VlcPackage(), ViewM3U8Action(),
MpvPackage(), MpvYTDLPackage(),
WebVideoCastPackage(), MpvKtPackage(), MpvKtPreviewPackage(),
FcastAction()
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/PlayInBrowserAction.kt b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/PlayInBrowserAction.kt
index 39b689398..de32bb4b3 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/actions/temp/PlayInBrowserAction.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/PlayInBrowserAction.kt
@@ -3,6 +3,7 @@ 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
@@ -11,7 +12,7 @@ import com.lagradost.cloudstream3.ui.result.txt
import com.lagradost.cloudstream3.utils.ExtractorLinkType
class PlayInBrowserAction: VideoClickAction() {
- override val name = txt("Play in browser")
+ override val name = txt(R.string.episode_action_play_in_format, "Browser")
override val oneSource = true
diff --git a/app/src/main/java/com/lagradost/cloudstream3/actions/temp/TestAction.kt b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/ViewM3U8Action.kt
similarity index 80%
rename from app/src/main/java/com/lagradost/cloudstream3/actions/temp/TestAction.kt
rename to app/src/main/java/com/lagradost/cloudstream3/actions/temp/ViewM3U8Action.kt
index c825202a1..c14168e96 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/actions/temp/TestAction.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/ViewM3U8Action.kt
@@ -2,14 +2,17 @@ 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 TestAction: VideoClickAction() {
- override val name = txt("Test action")
+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
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
index ec824d4eb..ecb37fdc6 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/actions/temp/VlcPackage.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/VlcPackage.kt
@@ -5,12 +5,14 @@ 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
@@ -47,6 +49,14 @@ class VlcPackage: OpenInAppAction(
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?) {
@@ -55,5 +65,4 @@ class VlcPackage: OpenInAppAction(
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/fcast/FcastAction.kt b/app/src/main/java/com/lagradost/cloudstream3/actions/temp/fcast/FcastAction.kt
index f2f7621e8..c0f92e4df 100644
--- 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
@@ -2,6 +2,7 @@ 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
@@ -13,7 +14,7 @@ import com.lagradost.cloudstream3.utils.ExtractorLinkType
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog
class FcastAction: VideoClickAction() {
- override val name = txt("Fcast")
+ override val name = txt("Fcast to device")
override val oneSource = true
@@ -36,7 +37,7 @@ class FcastAction: VideoClickAction() {
context?.getActivity()?.showBottomDialog(
devices.map { it.name },
-1,
- "Select device",
+ txt(R.string.player_settings_select_cast_device).asString(context),
false,
{}) {
val position = getViewPos(video.id)?.position
@@ -52,7 +53,7 @@ class FcastAction: VideoClickAction() {
session.sendMessage(
Opcode.Play,
PlayMessage(
- "application/vnd.apple.mpegurl",
+ "video/*",
link.url,
time = position?.let { it / 1000.0 },
headers = mapOf(
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 0c754f513..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
@@ -44,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
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 a330d5638..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
@@ -1406,7 +1406,6 @@ class ResultViewModel2 : ViewModel() {
options.addAll(
listOf(
- 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,
@@ -1570,17 +1569,6 @@ class ResultViewModel2 : ViewModel() {
}
}
- ACTION_COPY_LINK -> {
- acquireSingleLink(
- click.data,
- LOADTYPE_ALL,
- 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)
}
diff --git a/app/src/main/res/values-ajp/strings.xml b/app/src/main/res/values-ajp/strings.xml
index 7a70ccc6e..aa861bd47 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 33a1172ca..d4958b6d3 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 0ed41795c..b001ab768 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 0ad12bdf4..a39c4e208 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 414f26440..6e6d3b2a1 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 ccca67b36..2ec81cf28 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 09746f1f8..0d40ce6ae 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 22203b398..9255c459e 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 3e7636ce5..5902cd69e 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 0974257b0..f905c5f7b 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 421746742..fd3fa52d9 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
@@ -617,7 +611,6 @@
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 %1$d Episódio %2$d vai ser lançado em
- Fcast
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 809f12ce4..2b0402566 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 cb695c0f9..601500ff7 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 3e3c0e208..46123d7ab 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 479bdc38b..7cf754f97 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 7c7553208..c35c2b9d0 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -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