mirror of
				https://github.com/recloudstream/cloudstream.git
				synced 2024-08-15 01:53:11 +00:00 
			
		
		
		
	Add option for default media player (Internal, VLC and browser) & fixed VLC detection
This commit is contained in:
		
							parent
							
								
									03eb17149f
								
							
						
					
					
						commit
						fbbcdb4889
					
				
					 8 changed files with 102 additions and 22 deletions
				
			
		|  | @ -21,6 +21,10 @@ | |||
|         android:name="android.software.leanback" | ||||
|         android:required="false" /> | ||||
| 
 | ||||
|     <queries> | ||||
|         <package android:name="org.videolan.vlc" /> | ||||
|     </queries> | ||||
| 
 | ||||
|     <!--TODO https://stackoverflow.com/questions/41799732/chromecast-button-not-visible-in-android--> | ||||
|     <application | ||||
|         android:name=".AcraApplication" | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| package com.lagradost.cloudstream3.ui.result | ||||
| 
 | ||||
| import android.annotation.SuppressLint | ||||
| import android.content.Context | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
|  | @ -9,6 +10,7 @@ import android.widget.TextView | |||
| import androidx.core.view.isGone | ||||
| import androidx.core.view.isVisible | ||||
| import androidx.core.widget.ContentLoadingProgressBar | ||||
| import androidx.preference.PreferenceManager | ||||
| import androidx.recyclerview.widget.DiffUtil | ||||
| import androidx.recyclerview.widget.RecyclerView | ||||
| import com.google.android.material.button.MaterialButton | ||||
|  | @ -60,6 +62,22 @@ class EpisodeAdapter( | |||
|     private val clickCallback: (EpisodeClickEvent) -> Unit, | ||||
|     private val downloadClickCallback: (DownloadClickEvent) -> Unit, | ||||
| ) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { | ||||
|     companion object { | ||||
|         /** | ||||
|          * @return ACTION_PLAY_EPISODE_IN_PLAYER, ACTION_PLAY_EPISODE_IN_BROWSER or ACTION_PLAY_EPISODE_IN_VLC_PLAYER depending on player settings. | ||||
|          * See array.xml/player_pref_values | ||||
|          **/ | ||||
|         fun getPlayerAction(context: Context): Int { | ||||
|             val settingsManager = PreferenceManager.getDefaultSharedPreferences(context) | ||||
|             return when (settingsManager.getInt(context.getString(R.string.player_pref_key), 1)) { | ||||
|                 1 -> ACTION_PLAY_EPISODE_IN_PLAYER | ||||
|                 2 -> ACTION_PLAY_EPISODE_IN_VLC_PLAYER | ||||
|                 3 -> ACTION_PLAY_EPISODE_IN_BROWSER | ||||
|                 else -> ACTION_PLAY_EPISODE_IN_PLAYER | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     var cardList: MutableList<ResultEpisode> = mutableListOf() | ||||
| 
 | ||||
|     private val mBoundViewHolders: HashSet<DownloadButtonViewHolder> = HashSet() | ||||
|  |  | |||
|  | @ -38,6 +38,7 @@ import com.lagradost.cloudstream3.ui.download.DOWNLOAD_ACTION_DOWNLOAD | |||
| import com.lagradost.cloudstream3.ui.download.DownloadButtonSetup.handleDownloadClick | ||||
| import com.lagradost.cloudstream3.ui.download.EasyDownloadButton | ||||
| import com.lagradost.cloudstream3.ui.quicksearch.QuickSearchFragment | ||||
| import com.lagradost.cloudstream3.ui.result.EpisodeAdapter.Companion.getPlayerAction | ||||
| import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings | ||||
| import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings | ||||
| import com.lagradost.cloudstream3.utils.* | ||||
|  | @ -455,7 +456,8 @@ open class ResultFragment : ResultTrailerPlayer() { | |||
|         val apiName: String, | ||||
|         val showFillers: Boolean, | ||||
|         val dubStatus: DubStatus, | ||||
|         val start: AutoResume? | ||||
|         val start: AutoResume?, | ||||
|         val playerAction: Int | ||||
|     ) | ||||
| 
 | ||||
|     private fun getStoredData(context: Context): StoredData? { | ||||
|  | @ -469,6 +471,8 @@ open class ResultFragment : ResultTrailerPlayer() { | |||
|         ) DubStatus.Dubbed else DubStatus.Subbed | ||||
|         val startAction = arguments?.getInt(START_ACTION_BUNDLE) | ||||
| 
 | ||||
|         val playerAction = getPlayerAction(context) | ||||
| 
 | ||||
|         val start = startAction?.let { action -> | ||||
|             val startValue = arguments?.getInt(START_VALUE_BUNDLE) | ||||
|             val resumeEpisode = arguments?.getInt(EPISODE_BUNDLE) | ||||
|  | @ -483,7 +487,7 @@ open class ResultFragment : ResultTrailerPlayer() { | |||
|                 season = resumeSeason | ||||
|             ) | ||||
|         } | ||||
|         return StoredData(url, apiName, showFillers, dubStatus, start) | ||||
|         return StoredData(url, apiName, showFillers, dubStatus, start, playerAction) | ||||
|     } | ||||
| 
 | ||||
|     private fun reloadViewModel(success: Boolean = false) { | ||||
|  | @ -774,7 +778,8 @@ open class ResultFragment : ResultTrailerPlayer() { | |||
|                         viewModel.handleAction( | ||||
|                             activity, | ||||
|                             EpisodeClickEvent( | ||||
|                                 ACTION_PLAY_EPISODE_IN_PLAYER, value.result | ||||
|                                 storedData?.playerAction ?: ACTION_PLAY_EPISODE_IN_PLAYER, | ||||
|                                 value.result | ||||
|                             ) | ||||
|                         ) | ||||
|                     } | ||||
|  |  | |||
|  | @ -1,10 +1,7 @@ | |||
| package com.lagradost.cloudstream3.ui.result | ||||
| 
 | ||||
| import android.app.Activity | ||||
| import android.content.ClipData | ||||
| import android.content.ClipboardManager | ||||
| import android.content.Context | ||||
| import android.content.Intent | ||||
| import android.content.* | ||||
| import android.net.Uri | ||||
| import android.util.Log | ||||
| import android.widget.Toast | ||||
|  | @ -33,6 +30,7 @@ import com.lagradost.cloudstream3.ui.player.GeneratorPlayer | |||
| import com.lagradost.cloudstream3.ui.player.IGenerator | ||||
| 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.AppUtils.getNameFull | ||||
|  | @ -973,9 +971,11 @@ class ResultViewModel2 : ViewModel() { | |||
|                 File.createTempFile("mirrorlist", ".m3u8", outputDir) | ||||
|             } | ||||
|             var text = "#EXTM3U" | ||||
|             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}\"" | ||||
|             } | ||||
| 
 | ||||
|             // 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}" | ||||
|             } | ||||
|  | @ -999,11 +999,10 @@ class ResultViewModel2 : ViewModel() { | |||
| 
 | ||||
|             val startId = VLC_FROM_PROGRESS | ||||
| 
 | ||||
|             var position = startId | ||||
|             if (startId == VLC_FROM_START) { | ||||
|                 position = 1 | ||||
|             } else if (startId == VLC_FROM_PROGRESS) { | ||||
|                 position = 0 | ||||
|             val position = when (startId) { | ||||
|                 VLC_FROM_START -> 1 | ||||
|                 VLC_FROM_PROGRESS -> 0 | ||||
|                 else -> 0 | ||||
|             } | ||||
| 
 | ||||
|             vlcIntent.putExtra("position", position) | ||||
|  | @ -1013,7 +1012,13 @@ class ResultViewModel2 : ViewModel() { | |||
|             act.startActivityForResult(vlcIntent, VLC_REQUEST_CODE) | ||||
|         } catch (e: Exception) { | ||||
|             logError(e) | ||||
|             showToast(act, e.toString(), Toast.LENGTH_LONG) | ||||
|             main { | ||||
|                 if (e is ActivityNotFoundException) { | ||||
|                     showToast(act, txt(R.string.vlc_not_found_error), Toast.LENGTH_LONG) | ||||
|                 } else { | ||||
|                     showToast(act, e.toString(), Toast.LENGTH_LONG) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -1073,9 +1078,10 @@ class ResultViewModel2 : ViewModel() { | |||
|                             click.copy(action = ACTION_CHROME_CAST_EPISODE) | ||||
|                         ) | ||||
|                     } else { | ||||
|                         val action = getPlayerAction(ctx) | ||||
|                         handleEpisodeClickEvent( | ||||
|                             activity, | ||||
|                             click.copy(action = ACTION_PLAY_EPISODE_IN_PLAYER) | ||||
|                             click.copy(action = action) | ||||
|                         ) | ||||
|                     } | ||||
|                 } | ||||
|  | @ -1592,7 +1598,8 @@ class ResultViewModel2 : ViewModel() { | |||
|                     val idIndex = ep.key.id | ||||
|                     for ((index, i) in ep.value.withIndex()) { | ||||
|                         val episode = i.episode ?: (index + 1) | ||||
|                         val id = mainId + episode + idIndex * 1_000_000 + (i.season?.times(10_000) ?: 0) | ||||
|                         val id = | ||||
|                             mainId + episode + idIndex * 1_000_000 + (i.season?.times(10_000) ?: 0) | ||||
|                         if (!existingEpisodes.contains(id)) { | ||||
|                             existingEpisodes.add(id) | ||||
|                             val seasonData = loadResponse.seasonNames.getSeason(i.season) | ||||
|  | @ -1888,7 +1895,10 @@ class ResultViewModel2 : ViewModel() { | |||
|                             if (ep.getWatchProgress() > 0.9) continue | ||||
|                             handleAction( | ||||
|                                 activity, | ||||
|                                 EpisodeClickEvent(ACTION_PLAY_EPISODE_IN_PLAYER, ep) | ||||
|                                 EpisodeClickEvent( | ||||
|                                     getPlayerAction(activity), | ||||
|                                     ep | ||||
|                                 ) | ||||
|                             ) | ||||
|                             break | ||||
|                         } | ||||
|  | @ -1905,7 +1915,10 @@ class ResultViewModel2 : ViewModel() { | |||
|                             ?: return@launchSafe | ||||
|                     handleAction( | ||||
|                         activity, | ||||
|                         EpisodeClickEvent(ACTION_PLAY_EPISODE_IN_PLAYER, episode) | ||||
|                         EpisodeClickEvent( | ||||
|                             getPlayerAction(activity), | ||||
|                             episode | ||||
|                         ) | ||||
|                     ) | ||||
|                 } | ||||
|             } | ||||
|  |  | |||
|  | @ -113,6 +113,22 @@ 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) | ||||
| 
 | ||||
|             activity?.showBottomDialog( | ||||
|                 prefNames.toList(), | ||||
|                 prefValues.indexOf(current), | ||||
|                 getString(R.string.player_pref), | ||||
|                 true, | ||||
|                 {}) { | ||||
|                 settingsManager.edit().putInt(getString(R.string.player_pref_key), prefValues[it]).apply() | ||||
|             } | ||||
|             return@setOnPreferenceClickListener true | ||||
|         } | ||||
| 
 | ||||
|         getPref(R.string.subtitle_settings_key)?.setOnPreferenceClickListener { | ||||
|             SubtitlesFragment.push(activity, false) | ||||
|             return@setOnPreferenceClickListener true | ||||
|  |  | |||
|  | @ -33,6 +33,18 @@ | |||
|         <item>6</item> | ||||
|     </array> | ||||
| 
 | ||||
|     <array name="player_pref_names"> | ||||
|         <item>@string/player_settings_play_in_app</item> | ||||
|         <item>@string/player_settings_play_in_vlc</item> | ||||
|         <item>@string/player_settings_play_in_browser</item> | ||||
|     </array> | ||||
| 
 | ||||
|     <array name="player_pref_values"> | ||||
|         <item>1</item> | ||||
|         <item>2</item> | ||||
|         <item>3</item> | ||||
|     </array> | ||||
| 
 | ||||
|     <array name="limit_title_rez_pref_names"> | ||||
|         <item>@string/resolution_and_title</item> | ||||
|         <item>@string/title</item> | ||||
|  |  | |||
|  | @ -14,6 +14,7 @@ | |||
|     <string name="subtitle_settings_key" translatable="false">subtitle_settings_key</string> | ||||
|     <string name="subtitle_settings_chromecast_key" translatable="false">subtitle_settings_chromecast_key</string> | ||||
|     <string name="quality_pref_key" translatable="false">quality_pref_key</string> | ||||
|     <string name="player_pref_key" translatable="false">player_pref_key</string> | ||||
|     <string name="prefer_limit_title_key" translatable="false">prefer_limit_title_key</string> | ||||
|     <string name="prefer_limit_title_rez_key" translatable="false">prefer_limit_title_rez_key</string> | ||||
|     <string name="video_buffer_size_key" translatable="false">video_buffer_size_key</string> | ||||
|  | @ -255,7 +256,7 @@ | |||
|     <string name="search">Search</string> | ||||
|     <string name="category_account">Accounts</string> | ||||
|     <string name="category_updates">Updates and backup</string> | ||||
|      | ||||
| 
 | ||||
|     <string name="settings_info">Info</string> | ||||
|     <string name="advanced_search">Advanced Search</string> | ||||
|     <string name="advanced_search_des">Gives you the search results separated by provider</string> | ||||
|  | @ -626,6 +627,12 @@ | |||
|     <string name="extension_types">Supported</string> | ||||
|     <string name="extension_language">Language</string> | ||||
|     <string name="extension_install_first">Install the extension first</string> | ||||
|      | ||||
| 
 | ||||
|     <string name="hls_playlist">HLS Playlist</string> | ||||
| 
 | ||||
|     <string name="player_pref">Preferred video player</string> | ||||
|     <string name="player_settings_play_in_app">Internal player</string> | ||||
|     <string name="player_settings_play_in_vlc">VLC</string> | ||||
|     <string name="player_settings_play_in_browser">Browser</string> | ||||
|     <string name="vlc_not_found_error">VLC not found</string> | ||||
| </resources> | ||||
|  |  | |||
|  | @ -18,6 +18,11 @@ | |||
|             android:title="@string/watch_quality_pref" | ||||
|             android:icon="@drawable/ic_baseline_hd_24" /> | ||||
| 
 | ||||
|     <Preference | ||||
|             android:key="@string/player_pref_key" | ||||
|             android:title="@string/player_pref" | ||||
|             android:icon="@drawable/netflix_play" /> | ||||
| 
 | ||||
|     <Preference | ||||
|             android:key="@string/prefer_limit_title_key" | ||||
|             android:title="@string/limit_title" | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue