mirror of
				https://github.com/recloudstream/cloudstream.git
				synced 2024-08-15 01:53:11 +00:00 
			
		
		
		
	mpv
This commit is contained in:
		
							parent
							
								
									071004f6c2
								
							
						
					
					
						commit
						c2d245e8b4
					
				
					 7 changed files with 158 additions and 89 deletions
				
			
		|  | @ -24,6 +24,7 @@ | |||
|     <queries> | ||||
|         <package android:name="org.videolan.vlc" /> | ||||
|         <package android:name="com.instantbits.cast.webvideo" /> | ||||
|         <package android:name="is.xyz.mpv" /> | ||||
|     </queries> | ||||
| 
 | ||||
|     <!--TODO https://stackoverflow.com/questions/41799732/chromecast-button-not-visible-in-android--> | ||||
|  |  | |||
|  | @ -10,16 +10,22 @@ import android.util.Log | |||
| import android.view.* | ||||
| import android.widget.TextView | ||||
| import android.widget.Toast | ||||
| import androidx.activity.ComponentActivity | ||||
| import androidx.activity.result.contract.ActivityResultContracts | ||||
| import androidx.annotation.MainThread | ||||
| import androidx.annotation.StringRes | ||||
| import androidx.appcompat.app.AppCompatActivity | ||||
| import androidx.appcompat.widget.SearchView | ||||
| import androidx.preference.PreferenceManager | ||||
| import com.google.android.gms.cast.framework.CastSession | ||||
| import com.lagradost.cloudstream3.AcraApplication.Companion.getKey | ||||
| import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey | ||||
| 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.SettingsFragment.Companion.updateTv | ||||
| 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 | ||||
|  | @ -34,6 +40,7 @@ object CommonActivity { | |||
|         return (this as MainActivity?)?.mSessionManager?.currentCastSession | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     var canEnterPipMode: Boolean = false | ||||
|     var canShowPipMode: Boolean = false | ||||
|     var isInPIPMode: Boolean = false | ||||
|  | @ -117,7 +124,7 @@ object CommonActivity { | |||
|         setLocale(this, localeCode) | ||||
|     } | ||||
| 
 | ||||
|     fun init(act: Activity?) { | ||||
|     fun init(act: ComponentActivity?) { | ||||
|         if (act == null) return | ||||
|         //https://stackoverflow.com/questions/52594181/how-to-know-if-user-has-disabled-picture-in-picture-feature-permission | ||||
|         //https://developer.android.com/guide/topics/ui/picture-in-picture | ||||
|  | @ -129,6 +136,22 @@ object CommonActivity { | |||
|         act.updateLocale() | ||||
|         act.updateTv() | ||||
|         NewPipe.init(DownloaderTestImpl.getInstance()) | ||||
| 
 | ||||
|         for (resumeApp in resumeApps) { | ||||
|             resumeApp.launcher = | ||||
|                 act.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 = data.getLongExtra(resumeApp.position, -1L) | ||||
|                         val dur = data.getLongExtra(resumeApp.duration, -1L) | ||||
|                         if (dur > 0L && pos > 0L) | ||||
|                             DataStoreHelper.setViewPos(getKey(resumeApp.lastId), pos, dur) | ||||
|                         removeKey(resumeApp.lastId) | ||||
|                         ResultFragment.updateUI() | ||||
|                     } | ||||
|                 } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private fun Activity.enterPIPMode() { | ||||
|  | @ -167,7 +190,7 @@ object CommonActivity { | |||
|                 "Amoled" -> R.style.AmoledMode | ||||
|                 "AmoledLight" -> R.style.AmoledModeLight | ||||
|                 "Monet" -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) | ||||
|                         R.style.MonetMode else R.style.AppTheme | ||||
|                     R.style.MonetMode else R.style.AppTheme | ||||
|                 else -> R.style.AppTheme | ||||
|             } | ||||
| 
 | ||||
|  |  | |||
|  | @ -10,7 +10,7 @@ import android.view.KeyEvent | |||
| import android.view.Menu | ||||
| import android.view.MenuItem | ||||
| import android.view.WindowManager | ||||
| import android.widget.Toast | ||||
| import androidx.activity.result.ActivityResultLauncher | ||||
| import androidx.annotation.IdRes | ||||
| import androidx.appcompat.app.AlertDialog | ||||
| import androidx.appcompat.app.AppCompatActivity | ||||
|  | @ -35,6 +35,8 @@ import com.lagradost.cloudstream3.APIHolder.apis | |||
| import com.lagradost.cloudstream3.APIHolder.getApiDubstatusSettings | ||||
| import com.lagradost.cloudstream3.APIHolder.initAll | ||||
| import com.lagradost.cloudstream3.APIHolder.updateHasTrailers | ||||
| import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey | ||||
| import com.lagradost.cloudstream3.AcraApplication.Companion.setKey | ||||
| import com.lagradost.cloudstream3.CommonActivity.loadThemes | ||||
| import com.lagradost.cloudstream3.CommonActivity.onColorSelectedEvent | ||||
| import com.lagradost.cloudstream3.CommonActivity.onDialogDismissedEvent | ||||
|  | @ -53,7 +55,6 @@ import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appStri | |||
| import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.inAppAuths | ||||
| import com.lagradost.cloudstream3.ui.APIRepository | ||||
| import com.lagradost.cloudstream3.ui.download.DOWNLOAD_NAVIGATE_TO | ||||
| import com.lagradost.cloudstream3.ui.result.ResultFragment | ||||
| import com.lagradost.cloudstream3.ui.search.SearchResultBuilder | ||||
| import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isEmulatorSettings | ||||
| import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings | ||||
|  | @ -67,10 +68,8 @@ import com.lagradost.cloudstream3.utils.AppUtils.loadResult | |||
| import com.lagradost.cloudstream3.utils.BackupUtils.setUpBackup | ||||
| import com.lagradost.cloudstream3.utils.Coroutines.ioSafe | ||||
| import com.lagradost.cloudstream3.utils.DataStore.getKey | ||||
| import com.lagradost.cloudstream3.utils.DataStore.removeKey | ||||
| import com.lagradost.cloudstream3.utils.DataStore.setKey | ||||
| import com.lagradost.cloudstream3.utils.DataStoreHelper.migrateResumeWatching | ||||
| import com.lagradost.cloudstream3.utils.DataStoreHelper.setViewPos | ||||
| import com.lagradost.cloudstream3.utils.Event | ||||
| import com.lagradost.cloudstream3.utils.IOnBackPressed | ||||
| import com.lagradost.cloudstream3.utils.InAppUpdater.Companion.runAutoUpdate | ||||
|  | @ -95,18 +94,65 @@ import java.nio.charset.Charset | |||
| import kotlin.reflect.KClass | ||||
| 
 | ||||
| 
 | ||||
| //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 | ||||
| 
 | ||||
| const val VLC_PACKAGE = "org.videolan.vlc" | ||||
| const val VLC_INTENT_ACTION_RESULT = "org.videolan.vlc.player.result" | ||||
| val VLC_COMPONENT: ComponentName = | ||||
|     ComponentName(VLC_PACKAGE, "org.videolan.vlc.gui.video.VideoPlayerActivity") | ||||
| const val VLC_REQUEST_CODE = 42 | ||||
| 
 | ||||
| const val VLC_EXTRA_POSITION_OUT = "extra_position" | ||||
| const val VLC_EXTRA_DURATION_OUT = "extra_duration" | ||||
| const val VLC_LAST_ID_KEY = "vlc_last_open_id" | ||||
| 
 | ||||
| const val MPV_PACKAGE = "is.xyz.mpv" | ||||
| 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") | ||||
| 
 | ||||
| //TODO REFACTOR AF | ||||
| data class ResultResume( | ||||
|     val packageString: String, | ||||
|     val action: String = Intent.ACTION_VIEW, | ||||
|     val position: String? = null, | ||||
|     val duration: String? = null, | ||||
|     var launcher: ActivityResultLauncher<Intent>? = null, | ||||
| ) { | ||||
|     val 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) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| val VLC = ResultResume( | ||||
|     VLC_PACKAGE, | ||||
|     "org.videolan.vlc.player.result", | ||||
|     "extra_position", | ||||
|     "extra_duration", | ||||
| ) | ||||
| 
 | ||||
| val MPV = ResultResume( | ||||
|     MPV_PACKAGE, | ||||
|     //"is.xyz.mpv.MPVActivity.result", // resume not working :pensive: | ||||
|      position = "position", | ||||
|     duration = "duration", | ||||
| ) | ||||
| 
 | ||||
| val WEB_VIDEO = ResultResume(WEB_VIDEO_CAST_PACKAGE) | ||||
| 
 | ||||
| val resumeApps = arrayOf( | ||||
|     VLC, MPV, WEB_VIDEO | ||||
| ) | ||||
| 
 | ||||
| // Short name for requests client to make it nicer to use | ||||
| 
 | ||||
|  | @ -373,31 +419,6 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { | ||||
|         if (requestCode == VLC_REQUEST_CODE) { | ||||
|             if (resultCode == RESULT_OK && data != null) { | ||||
|                 val pos: Long = | ||||
|                     data.getLongExtra( | ||||
|                         VLC_EXTRA_POSITION_OUT, | ||||
|                         -1 | ||||
|                     ) //Last position in media when player exited | ||||
|                 val dur: Long = | ||||
|                     data.getLongExtra( | ||||
|                         VLC_EXTRA_DURATION_OUT, | ||||
|                         -1 | ||||
|                     ) //Last position in media when player exited | ||||
|                 val id = getKey<Int>(VLC_LAST_ID_KEY) | ||||
|                 println("SET KEY $id at $pos / $dur") | ||||
|                 if (dur > 0 && pos > 0) { | ||||
|                     setViewPos(id, pos, dur) | ||||
|                 } | ||||
|                 removeKey(VLC_LAST_ID_KEY) | ||||
|                 ResultFragment.updateUI() | ||||
|             } | ||||
|         } | ||||
|         super.onActivityResult(requestCode, resultCode, data) | ||||
|     } | ||||
| 
 | ||||
|     override fun onDestroy() { | ||||
|         val broadcastIntent = Intent() | ||||
|         broadcastIntent.action = "restart_service" | ||||
|  |  | |||
|  | @ -56,6 +56,7 @@ 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 | ||||
| 
 | ||||
| 
 | ||||
| data class EpisodeClickEvent(val action: Int, val data: ResultEpisode) | ||||
|  | @ -71,12 +72,14 @@ class EpisodeAdapter( | |||
|          * 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 | ||||
|                 else -> ACTION_PLAY_EPISODE_IN_PLAYER | ||||
|             } | ||||
|         } | ||||
|  |  | |||
|  | @ -15,6 +15,7 @@ import androidx.lifecycle.viewModelScope | |||
| import com.lagradost.cloudstream3.* | ||||
| import com.lagradost.cloudstream3.APIHolder.getId | ||||
| import com.lagradost.cloudstream3.APIHolder.unixTime | ||||
| import com.lagradost.cloudstream3.AcraApplication.Companion.setKey | ||||
| import com.lagradost.cloudstream3.CommonActivity.getCastSession | ||||
| import com.lagradost.cloudstream3.CommonActivity.showToast | ||||
| import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer | ||||
|  | @ -43,7 +44,6 @@ 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.getDub | ||||
| import com.lagradost.cloudstream3.utils.DataStoreHelper.getResultEpisode | ||||
| import com.lagradost.cloudstream3.utils.DataStoreHelper.getResultSeason | ||||
|  | @ -613,7 +613,7 @@ class ResultViewModel2 : ViewModel() { | |||
|                 val src = "$DOWNLOAD_NAVIGATE_TO/$parentId" // url ?: return@let | ||||
| 
 | ||||
|                 // SET VISUAL KEYS | ||||
|                 AcraApplication.setKey( | ||||
|                 setKey( | ||||
|                     DOWNLOAD_HEADER_CACHE, | ||||
|                     parentId.toString(), | ||||
|                     VideoDownloadHelper.DownloadHeaderCached( | ||||
|  | @ -627,7 +627,7 @@ class ResultViewModel2 : ViewModel() { | |||
|                     ) | ||||
|                 ) | ||||
| 
 | ||||
|                 AcraApplication.setKey( | ||||
|                 setKey( | ||||
|                     DataStore.getFolderName( | ||||
|                         DOWNLOAD_EPISODE_CACHE, | ||||
|                         parentId.toString() | ||||
|  | @ -956,12 +956,16 @@ class ResultViewModel2 : ViewModel() { | |||
| 
 | ||||
|     private fun launchActivity( | ||||
|         activity: Activity?, | ||||
|         work: suspend (CoroutineScope.(Activity) -> Unit) | ||||
|         resumeApp: ResultResume, | ||||
|         id: Int? = null, | ||||
|         work: suspend (Intent.(Activity) -> Unit) | ||||
|     ): Job? { | ||||
|         val act = activity ?: return null | ||||
|         return CoroutineScope(Dispatchers.IO).launch { | ||||
|             try { | ||||
|                 work(act) | ||||
|                 resumeApp.launch(id) { | ||||
|                     work(act) | ||||
|                 } | ||||
|             } catch (t: Throwable) { | ||||
|                 logError(t) | ||||
|                 main { | ||||
|  | @ -981,14 +985,12 @@ class ResultViewModel2 : ViewModel() { | |||
|         title: String?, | ||||
|         posterUrl: String?, | ||||
|         subtitles: List<SubtitleData> | ||||
|     ) = launchActivity(activity) { act -> | ||||
|         val shareVideo = Intent(Intent.ACTION_VIEW) | ||||
|     ) = launchActivity(activity, WEB_VIDEO) { | ||||
|         setDataAndType(Uri.parse(link.url), "video/*") | ||||
| 
 | ||||
|         shareVideo.setDataAndType(Uri.parse(link.url), "video/*") | ||||
|         shareVideo.setPackage(WEB_VIDEO_CAST_PACKAGE) | ||||
|         shareVideo.putExtra("subs", subtitles.map { it.url.toUri() }.toTypedArray()) | ||||
|         title?.let { shareVideo.putExtra("title", title) } | ||||
|         posterUrl?.let { shareVideo.putExtra("poster", posterUrl) } | ||||
|         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) | ||||
|  | @ -997,10 +999,27 @@ class ResultViewModel2 : ViewModel() { | |||
|                 putString(key, value) | ||||
|             } | ||||
|         } | ||||
|         shareVideo.putExtra("android.media.intent.extra.HTTP_HEADERS", headers) | ||||
|         shareVideo.putExtra("secure_uri", true) | ||||
|         putExtra("android.media.intent.extra.HTTP_HEADERS", headers) | ||||
|         putExtra("secure_uri", true) | ||||
|     } | ||||
| 
 | ||||
|         act.startActivity(shareVideo) | ||||
|     private fun playWithMpv( | ||||
|         activity: Activity?, | ||||
|         id: Int, | ||||
|         link: ExtractorLink, | ||||
|         subtitles: List<SubtitleData>, | ||||
|         resume: Boolean = true, | ||||
|     ) = launchActivity(activity, MPV, id) { | ||||
|         putExtra("subs", subtitles.map { it.url.toUri() }.toTypedArray()) | ||||
|         putExtra("subs.name", subtitles.map { it.name }.toTypedArray()) | ||||
|         putExtra("subs.filename", subtitles.map { it.name }.toTypedArray()) | ||||
|         setDataAndType(Uri.parse(link.url), "video/*") | ||||
|         component = MPV_COMPONENT | ||||
|         putExtra("secure_uri", true) | ||||
|         putExtra("return_result", true) | ||||
|         val position = getViewPos(id)?.position | ||||
|         if (resume && position != null) | ||||
|             putExtra("position", position.toInt()) | ||||
|     } | ||||
| 
 | ||||
|     // https://wiki.videolan.org/Android_Player_Intents/ | ||||
|  | @ -1011,18 +1030,16 @@ class ResultViewModel2 : ViewModel() { | |||
|         resume: Boolean = true, | ||||
|         // if it is only a single link then resume works correctly | ||||
|         singleFile: Boolean? = null | ||||
|     ) = launchActivity(activity) { act -> | ||||
|         val vlcIntent = Intent(VLC_INTENT_ACTION_RESULT) | ||||
|     ) = 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) | ||||
| 
 | ||||
|         vlcIntent.setPackage(VLC_PACKAGE) | ||||
|         vlcIntent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) | ||||
|         vlcIntent.addFlags(Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) | ||||
|         vlcIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) | ||||
|         vlcIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION) | ||||
|         val outputDir = act.cacheDir | ||||
| 
 | ||||
|         if (singleFile ?: (data.links.size == 1)) { | ||||
|             vlcIntent.setDataAndType(data.links.first().url.toUri(), "video/*") | ||||
|             setDataAndType(data.links.first().url.toUri(), "video/*") | ||||
|         } else { | ||||
|             val outputFile = File.createTempFile("mirrorlist", ".m3u8", outputDir) | ||||
| 
 | ||||
|  | @ -1037,7 +1054,7 @@ class ResultViewModel2 : ViewModel() { | |||
|             } | ||||
|             outputFile.writeText(text) | ||||
| 
 | ||||
|             vlcIntent.setDataAndType( | ||||
|             setDataAndType( | ||||
|                 FileProvider.getUriForFile( | ||||
|                     act, | ||||
|                     act.applicationContext.packageName + ".provider", | ||||
|  | @ -1051,33 +1068,14 @@ class ResultViewModel2 : ViewModel() { | |||
|         } else { | ||||
|             1L | ||||
|         } | ||||
|         vlcIntent.putExtra("from_start", !resume) | ||||
|         vlcIntent.putExtra("position", position) | ||||
|         //vlcIntent.putExtra("subtitles_location", data.subs.first().url) | ||||
|         /*for (s in data.subs) { | ||||
|             if (s.origin == SubtitleOrigin.URL) { | ||||
|                 try { | ||||
|                     val txt = app.get(s.url, s.headers).text | ||||
|                     val subtitleFile = File.createTempFile("subtitle1", ".srt", outputDir) | ||||
|                     subtitleFile.writeText(txt) | ||||
|                     println("Subtitles::::::${subtitleFile.path}") | ||||
|                     vlcIntent.putExtra("subtitles_location", FileProvider.getUriForFile( | ||||
|                         act, | ||||
|                         act.applicationContext.packageName + ".provider", | ||||
|                         subtitleFile | ||||
|                     )) | ||||
|                     break | ||||
|                 } catch (t : Throwable) { | ||||
|                     logError(t) | ||||
|                 } | ||||
|             } | ||||
|         }*/ | ||||
| 
 | ||||
|         vlcIntent.component = VLC_COMPONENT | ||||
|         act.setKey(VLC_LAST_ID_KEY, id) | ||||
|         act.startActivityForResult(vlcIntent, VLC_REQUEST_CODE) | ||||
|         component = VLC_COMPONENT | ||||
| 
 | ||||
|         putExtra("from_start", !resume) | ||||
|         putExtra("position", position) | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     fun handleAction(activity: Activity?, click: EpisodeClickEvent) = | ||||
|         viewModelScope.launchSafe { | ||||
|             handleEpisodeClickEvent(activity, click) | ||||
|  | @ -1098,6 +1096,11 @@ class ResultViewModel2 : ViewModel() { | |||
|             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 | ||||
|         ) | ||||
|     ) | ||||
| 
 | ||||
|  | @ -1329,6 +1332,21 @@ class ResultViewModel2 : ViewModel() { | |||
|                     result.subs | ||||
|                 ) | ||||
|             } | ||||
|             ACTION_PLAY_EPISODE_IN_MPV -> acquireSingleLink( | ||||
|                 click.data, | ||||
|                 isCasting = true, | ||||
|                 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_PLAYER -> { | ||||
|                 val data = currentResponse?.syncData?.toList() ?: emptyList() | ||||
|                 val list = | ||||
|  | @ -2107,7 +2125,7 @@ class ResultViewModel2 : ViewModel() { | |||
|                     preferStartEpisode = getResultEpisode(mainId) | ||||
|                     preferStartSeason = getResultSeason(mainId) | ||||
| 
 | ||||
|                     AcraApplication.setKey( | ||||
|                     setKey( | ||||
|                         DOWNLOAD_HEADER_CACHE, | ||||
|                         mainId.toString(), | ||||
|                         VideoDownloadHelper.DownloadHeaderCached( | ||||
|  |  | |||
|  | @ -36,6 +36,7 @@ | |||
|     <array name="player_pref_names"> | ||||
|         <item>@string/player_settings_play_in_app</item> | ||||
|         <item>@string/player_settings_play_in_vlc</item> | ||||
|         <item>@string/player_settings_play_in_mpv</item> | ||||
|         <item>@string/player_settings_play_in_web</item> | ||||
|         <item>@string/player_settings_play_in_browser</item> | ||||
|     </array> | ||||
|  | @ -43,6 +44,7 @@ | |||
|     <array name="player_pref_values"> | ||||
|         <item>1</item> | ||||
|         <item>2</item> | ||||
|         <item>5</item> | ||||
|         <item>4</item> | ||||
|         <item>3</item> | ||||
|     </array> | ||||
|  |  | |||
|  | @ -633,6 +633,7 @@ | |||
|     <string name="player_pref">Preferred video player</string> | ||||
|     <string name="player_settings_play_in_app">Internal player</string> | ||||
|     <string name="player_settings_play_in_vlc">VLC</string> | ||||
|     <string name="player_settings_play_in_mpv">MPV</string> | ||||
|     <string name="player_settings_play_in_web">Web Video Cast</string> | ||||
|     <string name="player_settings_play_in_browser">Browser</string> | ||||
|     <string name="app_not_found_error">App not found</string> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue