mirror of
				https://github.com/recloudstream/cloudstream.git
				synced 2024-08-15 01:53:11 +00:00 
			
		
		
		
	sff
This commit is contained in:
		
							parent
							
								
									bd34c66592
								
							
						
					
					
						commit
						8a519176ca
					
				
					 7 changed files with 73 additions and 61 deletions
				
			
		|  | @ -75,7 +75,4 @@ dependencies { | |||
|     implementation 'com.google.android.exoplayer:extension-cast:2.14.1' | ||||
|     implementation "com.google.android.exoplayer:extension-mediasession:2.14.1" | ||||
|     //implementation "com.google.android.exoplayer:extension-leanback:2.14.0" | ||||
| 
 | ||||
|     //download manager | ||||
|     implementation "com.anggrayudi:storage:0.9.0" | ||||
| } | ||||
|  | @ -1,6 +1,8 @@ | |||
| package com.lagradost.cloudstream3 | ||||
| 
 | ||||
| import android.R.attr | ||||
| import android.app.PictureInPictureParams | ||||
| import android.content.ComponentName | ||||
| import android.content.Intent | ||||
| import android.content.pm.PackageManager | ||||
| import android.os.Build | ||||
|  | @ -10,24 +12,33 @@ import androidx.appcompat.app.AppCompatActivity | |||
| import androidx.navigation.findNavController | ||||
| import androidx.navigation.ui.AppBarConfiguration | ||||
| import androidx.navigation.ui.setupWithNavController | ||||
| import com.anggrayudi.storage.SimpleStorage | ||||
| import com.anggrayudi.storage.file.StorageId | ||||
| import com.google.android.gms.cast.framework.CastButtonFactory | ||||
| import com.google.android.material.bottomnavigation.BottomNavigationView | ||||
| import com.lagradost.cloudstream3.UIHelper.checkWrite | ||||
| import com.lagradost.cloudstream3.UIHelper.hasPIPPermission | ||||
| import com.lagradost.cloudstream3.UIHelper.isUsingMobileData | ||||
| import com.lagradost.cloudstream3.UIHelper.requestRW | ||||
| import com.lagradost.cloudstream3.UIHelper.shouldShowPIPMode | ||||
| import com.lagradost.cloudstream3.receivers.VideoDownloadRestartReceiver | ||||
| import com.lagradost.cloudstream3.services.RESTART_ALL_DOWNLOADS_AND_QUEUE | ||||
| import com.lagradost.cloudstream3.services.START_VALUE_KEY | ||||
| import com.lagradost.cloudstream3.services.VideoDownloadKeepAliveService | ||||
| import com.lagradost.cloudstream3.utils.DataStore.getKey | ||||
| import com.lagradost.cloudstream3.utils.DataStore.getKeys | ||||
| import com.lagradost.cloudstream3.utils.DataStore.removeKey | ||||
| import com.lagradost.cloudstream3.utils.DataStore.removeKeys | ||||
| import com.lagradost.cloudstream3.utils.DataStoreHelper.setViewPos | ||||
| import com.lagradost.cloudstream3.utils.VideoDownloadManager | ||||
| import kotlinx.android.synthetic.main.fragment_result.* | ||||
| 
 | ||||
| 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_FROM_START = -1 | ||||
| const val VLC_FROM_PROGRESS = -2 | ||||
| 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" | ||||
| 
 | ||||
| class MainActivity : AppCompatActivity() { | ||||
|     /*, ViewModelStoreOwner { | ||||
|  | @ -51,8 +62,6 @@ class MainActivity : AppCompatActivity() { | |||
|         const val REQUEST_CODE_ASK_PERMISSIONS = 4 | ||||
|     } | ||||
| 
 | ||||
|     private lateinit var storage: SimpleStorage | ||||
| 
 | ||||
|     private fun enterPIPMode() { | ||||
|         if (!shouldShowPIPMode(isInPlayer) || !canShowPipMode) return | ||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||||
|  | @ -96,25 +105,21 @@ class MainActivity : AppCompatActivity() { | |||
|         super.onBackPressed() | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     private fun setupSimpleStorage() { | ||||
|         storage = SimpleStorage(this) | ||||
|     } | ||||
| 
 | ||||
|     override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { | ||||
|         if (VLC_REQUEST_CODE == requestCode) { | ||||
|             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) | ||||
|                 if (dur > 0 && pos > 0) { | ||||
|                     setViewPos(id, pos, dur) | ||||
|                 } | ||||
|                 removeKey(VLC_LAST_ID_KEY) | ||||
|             } | ||||
|         } | ||||
|         super.onActivityResult(requestCode, resultCode, data) | ||||
|         // Mandatory for Activity, but not for Fragment | ||||
|         storage.onActivityResult(requestCode, resultCode, data) | ||||
|     } | ||||
| 
 | ||||
|     override fun onSaveInstanceState(outState: Bundle) { | ||||
|         storage.onSaveInstanceState(outState) | ||||
|         super.onSaveInstanceState(outState) | ||||
|     } | ||||
| 
 | ||||
|     override fun onRestoreInstanceState(savedInstanceState: Bundle) { | ||||
|         super.onRestoreInstanceState(savedInstanceState) | ||||
|         storage.onRestoreInstanceState(savedInstanceState) | ||||
|     } | ||||
| 
 | ||||
|     override fun onDestroy() { | ||||
|  | @ -128,11 +133,6 @@ class MainActivity : AppCompatActivity() { | |||
|     override fun onCreate(savedInstanceState: Bundle?) { | ||||
|         super.onCreate(savedInstanceState) | ||||
|         mainContext = this | ||||
|         setupSimpleStorage() | ||||
| 
 | ||||
|         if (!storage.isStorageAccessGranted(StorageId.PRIMARY)) { | ||||
|             storage.requestStorageAccess(REQUEST_CODE_STORAGE_ACCESS) | ||||
|         } | ||||
| 
 | ||||
|         setContentView(R.layout.activity_main) | ||||
|         val navView: BottomNavigationView = findViewById(R.id.nav_view) | ||||
|  | @ -168,7 +168,7 @@ class MainActivity : AppCompatActivity() { | |||
|         //    this.startService(mServiceIntent) | ||||
|         //} | ||||
| //settingsManager.getBoolean("disable_automatic_data_downloads", true) && | ||||
|         if ( isUsingMobileData()) { | ||||
|         if (isUsingMobileData()) { | ||||
|             Toast.makeText(this, "Downloads not resumed on mobile data", Toast.LENGTH_LONG).show() | ||||
|         } else { | ||||
|             val keys = getKeys(VideoDownloadManager.KEY_RESUME_PACKAGES) | ||||
|  |  | |||
|  | @ -11,6 +11,8 @@ import android.graphics.Color | |||
| import android.media.AudioAttributes | ||||
| import android.media.AudioFocusRequest | ||||
| import android.media.AudioManager | ||||
| import android.net.ConnectivityManager | ||||
| import android.net.NetworkCapabilities | ||||
| import android.os.Build | ||||
| import android.view.Gravity | ||||
| import android.view.MenuItem | ||||
|  | @ -30,6 +32,7 @@ import com.google.android.gms.cast.framework.CastContext | |||
| import com.google.android.gms.cast.framework.CastState | ||||
| import com.google.android.gms.common.ConnectionResult | ||||
| import com.google.android.gms.common.GoogleApiAvailability | ||||
| import com.google.android.gms.common.wrappers.Wrappers.packageManager | ||||
| import com.lagradost.cloudstream3.ui.result.ResultFragment | ||||
| import com.lagradost.cloudstream3.utils.Event | ||||
| import kotlin.math.roundToInt | ||||
|  | @ -162,6 +165,25 @@ object UIHelper { | |||
|         return false | ||||
|     } | ||||
| 
 | ||||
|     fun Context.isUsingMobileData(): Boolean { | ||||
|         val conManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager | ||||
|         val networkInfo = conManager.allNetworks | ||||
|         return networkInfo.any { | ||||
|             conManager.getNetworkCapabilities(it)?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == true | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fun Context.isAppInstalled(uri: String): Boolean { | ||||
|         val pm = packageManager(this) | ||||
|         var appInstalled = false | ||||
|         appInstalled = try { | ||||
|             pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES) | ||||
|             true | ||||
|         } catch (e: PackageManager.NameNotFoundException) { | ||||
|             false | ||||
|         } | ||||
|         return appInstalled | ||||
|     } | ||||
| 
 | ||||
|     fun adjustAlpha(@ColorInt color: Int, factor: Float): Int { | ||||
|         val alpha = (Color.alpha(color) * factor).roundToInt() | ||||
|  |  | |||
|  | @ -101,8 +101,8 @@ const val PLAYBACK_SPEED = "playback_speed" | |||
| const val RESIZE_MODE_KEY = "resize_mode" // Last used resize mode | ||||
| const val PLAYBACK_SPEED_KEY = "playback_speed" // Last used playback speed | ||||
| 
 | ||||
| const val OPENING_PROCENTAGE = 50 | ||||
| const val AUTOLOAD_NEXT_EPISODE_PROCENTAGE = 80 | ||||
| const val OPENING_PRECENTAGE = 50 | ||||
| const val AUTOLOAD_NEXT_EPISODE_PRECENTAGE = 80 | ||||
| 
 | ||||
| enum class PlayerEventType(val value: Int) { | ||||
|     Stop(-1), | ||||
|  | @ -502,7 +502,7 @@ class PlayerFragment : Fragment() { | |||
|             val percentage = ((position ?: exoPlayer.currentPosition) * 100 / exoPlayer.contentDuration).toInt() | ||||
|             val hasNext = hasNextEpisode() | ||||
| 
 | ||||
|             if (percentage >= AUTOLOAD_NEXT_EPISODE_PROCENTAGE && hasNext) { | ||||
|             if (percentage >= AUTOLOAD_NEXT_EPISODE_PRECENTAGE && hasNext) { | ||||
|                 val ep = | ||||
|                     episodes[playerData.episodeIndex + 1] | ||||
| 
 | ||||
|  | @ -512,7 +512,7 @@ class PlayerFragment : Fragment() { | |||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             val nextEp = percentage >= OPENING_PROCENTAGE | ||||
|             val nextEp = percentage >= OPENING_PRECENTAGE | ||||
|             val isAnime = | ||||
|                 data.isAnimeBased()//(data is AnimeLoadResponse && (data.type == TvType.Anime || data.type == TvType.ONA)) | ||||
| 
 | ||||
|  | @ -1267,7 +1267,6 @@ class PlayerFragment : Fragment() { | |||
|         super.onDestroy() | ||||
|         isInPlayer = false | ||||
| 
 | ||||
|         savePos() | ||||
|         savePositionInPlayer() | ||||
|         safeReleasePlayer() | ||||
| 
 | ||||
|  | @ -1377,17 +1376,17 @@ class PlayerFragment : Fragment() { | |||
|             } | ||||
| 
 | ||||
|             val mimeType = if (currentUrl.isM3u8) MimeTypes.APPLICATION_M3U8 else MimeTypes.APPLICATION_MP4 | ||||
|             val _mediaItem = MediaItem.Builder() | ||||
|             val mediaItemBuilder = MediaItem.Builder() | ||||
|                 //Replace needed for android 6.0.0  https://github.com/google/ExoPlayer/issues/5983 | ||||
|                 .setMimeType(mimeType) | ||||
| 
 | ||||
|             if (isOnline) { | ||||
|                 _mediaItem.setUri(currentUrl.url) | ||||
|                 mediaItemBuilder.setUri(currentUrl.url) | ||||
|             } else { | ||||
|                 _mediaItem.setUri(Uri.fromFile(File(currentUrl.url))) | ||||
|                 mediaItemBuilder.setUri(Uri.fromFile(File(currentUrl.url))) | ||||
|             } | ||||
| 
 | ||||
|             val mediaItem = _mediaItem.build() | ||||
|             val mediaItem = mediaItemBuilder.build() | ||||
|             val trackSelector = DefaultTrackSelector(requireContext()) | ||||
|             // Disable subtitles | ||||
|             trackSelector.parameters = DefaultTrackSelector.ParametersBuilder(requireContext()) | ||||
|  | @ -1470,14 +1469,13 @@ class PlayerFragment : Fragment() { | |||
|                         if (height == null || width == null) currentUrl.name else "${currentUrl.name} - ${width}x${height}" | ||||
| 
 | ||||
|                     if (!hasUsedFirstRender) { // DON'T WANT TO SET MULTIPLE MESSAGES | ||||
|                         println("FIRST RENDER") | ||||
|                         changeSkip() | ||||
|                         exoPlayer | ||||
|                             .createMessage { _, _ -> | ||||
|                                 changeSkip() | ||||
|                             } | ||||
|                             .setLooper(Looper.getMainLooper()) | ||||
|                             .setPosition( /* positionMs= */exoPlayer.contentDuration * OPENING_PROCENTAGE / 100) | ||||
|                             .setPosition( /* positionMs= */exoPlayer.contentDuration * OPENING_PRECENTAGE / 100) | ||||
|                             //   .setPayload(customPayloadData) | ||||
|                             .setDeleteAfterDelivery(false) | ||||
|                             .send() | ||||
|  | @ -1486,7 +1484,7 @@ class PlayerFragment : Fragment() { | |||
|                                 changeSkip() | ||||
|                             } | ||||
|                             .setLooper(Looper.getMainLooper()) | ||||
|                             .setPosition( /* positionMs= */exoPlayer.contentDuration * AUTOLOAD_NEXT_EPISODE_PROCENTAGE / 100) | ||||
|                             .setPosition( /* positionMs= */exoPlayer.contentDuration * AUTOLOAD_NEXT_EPISODE_PRECENTAGE / 100) | ||||
|                             //   .setPayload(customPayloadData) | ||||
|                             .setDeleteAfterDelivery(false) | ||||
| 
 | ||||
|  |  | |||
|  | @ -28,7 +28,7 @@ import kotlinx.android.synthetic.main.result_episode.view.episode_text | |||
| import kotlinx.android.synthetic.main.result_episode_large.view.* | ||||
| 
 | ||||
| const val ACTION_PLAY_EPISODE_IN_PLAYER = 1 | ||||
| const val ACTION_PLAY_EPISODE_IN_EXTERNAL_PLAYER = 2 | ||||
| const val ACTION_PLAY_EPISODE_IN_VLC_PLAYER = 2 | ||||
| const val ACTION_PLAY_EPISODE_IN_BROWSER = 3 | ||||
| 
 | ||||
| const val ACTION_CHROME_CAST_EPISODE = 4 | ||||
|  |  | |||
|  | @ -17,7 +17,6 @@ import androidx.appcompat.app.AlertDialog | |||
| import androidx.appcompat.app.AppCompatActivity | ||||
| import androidx.coordinatorlayout.widget.CoordinatorLayout | ||||
| import androidx.core.content.ContextCompat | ||||
| import androidx.core.content.ContextCompat.getSystemService | ||||
| import androidx.core.content.FileProvider | ||||
| import androidx.core.text.color | ||||
| import androidx.core.widget.NestedScrollView | ||||
|  | @ -38,6 +37,7 @@ import com.lagradost.cloudstream3.UIHelper.checkWrite | |||
| import com.lagradost.cloudstream3.UIHelper.colorFromAttribute | ||||
| import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar | ||||
| import com.lagradost.cloudstream3.UIHelper.getStatusBarHeight | ||||
| import com.lagradost.cloudstream3.UIHelper.isAppInstalled | ||||
| import com.lagradost.cloudstream3.UIHelper.isCastApiAvailable | ||||
| import com.lagradost.cloudstream3.UIHelper.isConnectedToChromecast | ||||
| import com.lagradost.cloudstream3.UIHelper.popCurrentPage | ||||
|  | @ -449,6 +449,7 @@ class ResultFragment : Fragment() { | |||
|                         val add = when (opv) { | ||||
|                             ACTION_CHROME_CAST_EPISODE -> isConnected | ||||
|                             ACTION_CHROME_CAST_MIRROR -> isConnected | ||||
|                             ACTION_PLAY_EPISODE_IN_VLC_PLAYER -> context?.isAppInstalled(VLC_PACKAGE) ?: false | ||||
|                             else -> true | ||||
|                         } | ||||
|                         if (add) { | ||||
|  | @ -497,7 +498,7 @@ class ResultFragment : Fragment() { | |||
|                     startChromecast(0) | ||||
|                 } | ||||
| 
 | ||||
|                 ACTION_PLAY_EPISODE_IN_EXTERNAL_PLAYER -> { | ||||
|                 ACTION_PLAY_EPISODE_IN_VLC_PLAYER -> { | ||||
|                     if (activity?.checkWrite() != true) { | ||||
|                         activity?.requestRW() | ||||
|                         if (activity?.checkWrite() == true) return@main | ||||
|  | @ -517,14 +518,7 @@ class ResultFragment : Fragment() { | |||
|                         text += "\n#EXTINF:, ${link.name}\n${link.url}" | ||||
|                     } | ||||
|                     outputFile.writeText(text) | ||||
|                     val VLC_PACKAGE = "org.videolan.vlc" | ||||
|                     val VLC_INTENT_ACTION_RESULT = "org.videolan.vlc.player.result" | ||||
|                     val VLC_COMPONENT: ComponentName = | ||||
|                         ComponentName(VLC_PACKAGE, "org.videolan.vlc.gui.video.VideoPlayerActivity") | ||||
|                     val REQUEST_CODE = 42 | ||||
| 
 | ||||
|                     val FROM_START = -1 | ||||
|                     val FROM_PROGRESS = -2 | ||||
| 
 | ||||
|                     val vlcIntent = Intent(VLC_INTENT_ACTION_RESULT) | ||||
| 
 | ||||
|  | @ -542,21 +536,20 @@ class ResultFragment : Fragment() { | |||
|                         ), "video/*" | ||||
|                     ) | ||||
| 
 | ||||
|                     val startId = FROM_PROGRESS | ||||
|                     val startId = VLC_FROM_PROGRESS | ||||
| 
 | ||||
|                     var position = startId | ||||
|                     if (startId == FROM_START) { | ||||
|                     if (startId == VLC_FROM_START) { | ||||
|                         position = 1 | ||||
|                     } else if (startId == FROM_PROGRESS) { | ||||
|                     } else if (startId == VLC_FROM_PROGRESS) { | ||||
|                         position = 0 | ||||
|                     } | ||||
| 
 | ||||
|                     vlcIntent.putExtra("position", position) | ||||
| 
 | ||||
|                     vlcIntent.component = VLC_COMPONENT | ||||
| 
 | ||||
|                     activity?.startActivityForResult(vlcIntent, REQUEST_CODE) | ||||
| 
 | ||||
|                     requireContext().setKey(VLC_LAST_ID_KEY, currentId) | ||||
|                     activity?.startActivityForResult(vlcIntent, VLC_REQUEST_CODE) | ||||
|                 } | ||||
| 
 | ||||
|                 ACTION_PLAY_EPISODE_IN_PLAYER -> { | ||||
|  |  | |||
|  | @ -558,6 +558,8 @@ object VideoDownloadManager { | |||
|                     } | ||||
|                     DownloadActionType.Stop -> { | ||||
|                         isStopped = true; updateNotification() | ||||
|                         context.removeKey(KEY_RESUME_PACKAGES, event.first.toString()) | ||||
|                         saveQueue(context) | ||||
|                     } | ||||
|                     DownloadActionType.Resume -> { | ||||
|                         isPaused = false; updateNotification() | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue