mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
player stuff
This commit is contained in:
parent
47e3876e4a
commit
a102d5f66d
15 changed files with 338 additions and 38 deletions
|
@ -1,26 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.lagradost.cloudstream3">
|
||||
xmlns:tools="http://schemas.android.com/tools" package="com.lagradost.cloudstream3">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:usesCleartextTraffic="true"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
android:theme="@style/AppTheme" android:fullBackupContent="@xml/backup_descriptor">
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
|
||||
android:value="com.lagradost.cloudstream3.utils.CastOptionsProvider"/>
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|keyboard|keyboardHidden|navigation"
|
||||
android:label="@string/app_name">
|
||||
android:label="@string/app_name"
|
||||
android:resizeableActivity="true"
|
||||
android:supportsPictureInPicture="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
|
||||
|
@ -41,5 +44,4 @@
|
|||
android:resource="@xml/provider_paths"/>
|
||||
</provider>
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -1,24 +1,58 @@
|
|||
package com.lagradost.cloudstream3
|
||||
|
||||
import android.app.PictureInPictureParams
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContentProviderCompat.requireContext
|
||||
import androidx.lifecycle.ViewModelStore
|
||||
import androidx.lifecycle.ViewModelStoreOwner
|
||||
import androidx.navigation.findNavController
|
||||
import androidx.navigation.ui.AppBarConfiguration
|
||||
import androidx.navigation.ui.setupWithNavController
|
||||
import com.lagradost.cloudstream3.UIHelper.checkWrite
|
||||
import com.lagradost.cloudstream3.UIHelper.hasPIPPermission
|
||||
import com.lagradost.cloudstream3.UIHelper.requestRW
|
||||
import com.lagradost.cloudstream3.UIHelper.shouldShowPIPMode
|
||||
|
||||
class MainActivity : AppCompatActivity() {/*, ViewModelStoreOwner {
|
||||
private val appViewModelStore: ViewModelStore by lazy {
|
||||
ViewModelStore()
|
||||
class MainActivity : AppCompatActivity() {
|
||||
/*, ViewModelStoreOwner {
|
||||
private val appViewModelStore: ViewModelStore by lazy {
|
||||
ViewModelStore()
|
||||
}
|
||||
|
||||
override fun getViewModelStore(): ViewModelStore {
|
||||
return appViewModelStore
|
||||
}*/
|
||||
companion object {
|
||||
var isInPlayer: Boolean = false
|
||||
var canShowPipMode: Boolean = false
|
||||
var isInPIPMode: Boolean = false
|
||||
}
|
||||
|
||||
override fun getViewModelStore(): ViewModelStore {
|
||||
return appViewModelStore
|
||||
}*/
|
||||
private fun enterPIPMode() {
|
||||
if (!shouldShowPIPMode(isInPlayer) || !canShowPipMode) return
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
try {
|
||||
enterPictureInPictureMode(PictureInPictureParams.Builder().build())
|
||||
} catch (e: Exception) {
|
||||
enterPictureInPictureMode()
|
||||
}
|
||||
} else {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
enterPictureInPictureMode()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onUserLeaveHint() {
|
||||
super.onUserLeaveHint()
|
||||
if (isInPlayer && canShowPipMode) {
|
||||
enterPIPMode()
|
||||
}
|
||||
}
|
||||
|
||||
private fun AppCompatActivity.backPressed(): Boolean {
|
||||
val currentFragment = supportFragmentManager.fragments.last {
|
||||
|
@ -46,6 +80,13 @@ class MainActivity : AppCompatActivity() {/*, ViewModelStoreOwner {
|
|||
setContentView(R.layout.activity_main)
|
||||
val navView: BottomNavigationView = findViewById(R.id.nav_view)
|
||||
|
||||
//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
|
||||
canShowPipMode =
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && // OS SUPPORT
|
||||
packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE) && // HAS FEATURE, MIGHT BE BLOCKED DUE TO POWER DRAIN
|
||||
hasPIPPermission() // CHECK IF FEATURE IS ENABLED IN SETTINGS
|
||||
|
||||
val navController = findNavController(R.id.nav_host_fragment)
|
||||
// Passing each menu ID as a set of Ids because each
|
||||
// menu should be considered as top level destinations.
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.lagradost.cloudstream3
|
|||
|
||||
import android.Manifest
|
||||
import android.app.Activity
|
||||
import android.app.AppOpsManager
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Resources
|
||||
|
@ -11,6 +12,7 @@ import android.media.AudioManager
|
|||
import android.os.Build
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
|
@ -19,6 +21,7 @@ import androidx.preference.PreferenceManager
|
|||
import com.google.android.gms.cast.framework.CastContext
|
||||
import com.google.android.gms.common.ConnectionResult
|
||||
import com.google.android.gms.common.GoogleApiAvailability
|
||||
import com.lagradost.cloudstream3.UIHelper.getGridFormat
|
||||
import com.lagradost.cloudstream3.ui.result.ResultFragment
|
||||
import com.lagradost.cloudstream3.utils.Event
|
||||
|
||||
|
@ -261,4 +264,24 @@ object UIHelper {
|
|||
) // or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
// window.clearFlags(View.KEEP_SCREEN_ON)
|
||||
}
|
||||
|
||||
fun Context.shouldShowPIPMode(isInPlayer: Boolean): Boolean {
|
||||
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
return settingsManager?.getBoolean("pip_enabled", true) ?: true && isInPlayer
|
||||
}
|
||||
|
||||
fun Context.hasPIPPermission(): Boolean {
|
||||
val appOps =
|
||||
getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
|
||||
return appOps.checkOpNoThrow(
|
||||
AppOpsManager.OPSTR_PICTURE_IN_PICTURE,
|
||||
android.os.Process.myUid(),
|
||||
packageName
|
||||
) == AppOpsManager.MODE_ALLOWED
|
||||
}
|
||||
|
||||
fun Context.hideKeyboard(view: View) {
|
||||
val inputMethodManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
|
||||
}
|
||||
}
|
|
@ -3,22 +3,28 @@ package com.lagradost.cloudstream3.ui.player
|
|||
import android.animation.ObjectAnimator
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.app.PendingIntent
|
||||
import android.app.PictureInPictureParams
|
||||
import android.app.RemoteAction
|
||||
import android.content.*
|
||||
import android.content.Context.AUDIO_SERVICE
|
||||
import android.content.SharedPreferences
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.content.res.Resources
|
||||
import android.database.ContentObserver
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.Icon
|
||||
import android.media.AudioManager
|
||||
import android.net.Uri
|
||||
import android.os.*
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.View.*
|
||||
import android.view.ViewGroup
|
||||
import android.view.animation.*
|
||||
import android.view.animation.AccelerateInterpolator
|
||||
import android.view.animation.AlphaAnimation
|
||||
import android.view.animation.Animation
|
||||
import android.view.animation.AnimationUtils
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.Toast
|
||||
import android.widget.Toast.LENGTH_SHORT
|
||||
|
@ -26,7 +32,6 @@ import androidx.appcompat.app.AlertDialog
|
|||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.mediarouter.app.MediaRouteButton
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.transition.Fade
|
||||
import androidx.transition.Transition
|
||||
|
@ -44,6 +49,7 @@ import com.google.android.exoplayer2.upstream.DataSource
|
|||
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory
|
||||
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory
|
||||
import com.google.android.exoplayer2.util.MimeTypes
|
||||
import com.google.android.exoplayer2.util.Util
|
||||
import com.google.android.gms.cast.MediaInfo
|
||||
import com.google.android.gms.cast.MediaMetadata
|
||||
import com.google.android.gms.cast.MediaQueueItem
|
||||
|
@ -53,10 +59,13 @@ import com.google.android.gms.cast.framework.CastContext
|
|||
import com.google.android.gms.cast.framework.CastState
|
||||
import com.google.android.gms.common.images.WebImage
|
||||
import com.lagradost.cloudstream3.*
|
||||
import com.lagradost.cloudstream3.MainActivity.Companion.isInPIPMode
|
||||
import com.lagradost.cloudstream3.MainActivity.Companion.isInPlayer
|
||||
import com.lagradost.cloudstream3.R
|
||||
import com.lagradost.cloudstream3.UIHelper.getFocusRequest
|
||||
import com.lagradost.cloudstream3.UIHelper.getNavigationBarHeight
|
||||
import com.lagradost.cloudstream3.UIHelper.getStatusBarHeight
|
||||
import com.lagradost.cloudstream3.UIHelper.hideKeyboard
|
||||
import com.lagradost.cloudstream3.UIHelper.hideSystemUI
|
||||
import com.lagradost.cloudstream3.UIHelper.isCastApiAvailable
|
||||
import com.lagradost.cloudstream3.UIHelper.popCurrentPage
|
||||
|
@ -72,12 +81,10 @@ import com.lagradost.cloudstream3.utils.DataStore.setKey
|
|||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
import com.lagradost.cloudstream3.utils.getId
|
||||
import kotlinx.android.synthetic.main.fragment_player.*
|
||||
import kotlinx.android.synthetic.main.fragment_result.*
|
||||
import kotlinx.android.synthetic.main.player_custom_layout.*
|
||||
import kotlinx.coroutines.*
|
||||
import org.json.JSONObject
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import javax.net.ssl.HttpsURLConnection
|
||||
import javax.net.ssl.SSLContext
|
||||
import javax.net.ssl.SSLSession
|
||||
|
@ -129,12 +136,12 @@ data class PlayerData(
|
|||
)
|
||||
|
||||
class PlayerFragment : Fragment() {
|
||||
private var isCurrentlyPlaying: Boolean = false
|
||||
private val mapper = JsonMapper.builder().addModule(KotlinModule())
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).build()
|
||||
|
||||
private var isFullscreen = false
|
||||
private var isPlayerPlaying = true
|
||||
private var doubleTapEnabled = false
|
||||
private lateinit var viewModel: ResultViewModel
|
||||
private lateinit var playerData: PlayerData
|
||||
private var isLoading = true
|
||||
|
@ -281,20 +288,21 @@ class PlayerFragment : Fragment() {
|
|||
)
|
||||
}
|
||||
|
||||
fun skipOP() {
|
||||
private fun skipOP() {
|
||||
seekTime(85000L)
|
||||
}
|
||||
|
||||
private var swipeEnabled = true //<settingsManager!!.getBoolean("swipe_enabled", true)
|
||||
private var swipeVerticalEnabled = true//settingsManager.getBoolean("swipe_vertical_enabled", true)
|
||||
private var playBackSpeedEnabled = true//settingsManager!!.getBoolean("playback_speed_enabled", false)
|
||||
private var playerResizeEnabled = true//settingsManager!!.getBoolean("player_resize_enabled", false)
|
||||
private var doubleTapEnabled = false
|
||||
|
||||
private var skipTime = 0L
|
||||
private var prevDiffX = 0.0
|
||||
private var preventHorizontalSwipe = false
|
||||
private var hasPassedVerticalSwipeThreshold = false
|
||||
private var hasPassedSkipLimit = false
|
||||
private val swipeEnabled = true //<settingsManager!!.getBoolean("swipe_enabled", true)
|
||||
private val swipeVerticalEnabled = true//settingsManager.getBoolean("swipe_vertical_enabled", true)
|
||||
private val playBackSpeedEnabled = true//settingsManager!!.getBoolean("playback_speed_enabled", false)
|
||||
private val playerResizeEnabled = true//settingsManager!!.getBoolean("player_resize_enabled", false)
|
||||
private val swipeEdgeSize = 10.toPx
|
||||
|
||||
private var isMovingStartTime = 0L
|
||||
private var currentX = 0F
|
||||
|
@ -499,6 +507,7 @@ class PlayerFragment : Fragment() {
|
|||
private var hasUsedFirstRender = false
|
||||
|
||||
private fun releasePlayer() {
|
||||
isCurrentlyPlaying = false
|
||||
val alphaAnimation = AlphaAnimation(0f, 1f)
|
||||
alphaAnimation.duration = 100
|
||||
alphaAnimation.fillAfter = true
|
||||
|
@ -563,7 +572,7 @@ class PlayerFragment : Fragment() {
|
|||
video_locked_img.setColorFilter(color)
|
||||
|
||||
val isClick = !isLocked
|
||||
println("UPDATED LOCK $isClick")
|
||||
|
||||
exo_play.isClickable = isClick
|
||||
exo_pause.isClickable = isClick
|
||||
exo_ffwd.isClickable = isClick
|
||||
|
@ -597,10 +606,109 @@ class PlayerFragment : Fragment() {
|
|||
private var episodes: ArrayList<ResultEpisode> = ArrayList()
|
||||
var currentPoster: String? = null
|
||||
|
||||
//region PIP MODE
|
||||
private fun getPen(code: PlayerEventType): PendingIntent {
|
||||
return getPen(code.value)
|
||||
}
|
||||
|
||||
private fun getPen(code: Int): PendingIntent {
|
||||
return PendingIntent.getBroadcast(
|
||||
activity,
|
||||
code,
|
||||
Intent("media_control").putExtra("control_type", code),
|
||||
0
|
||||
)
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private fun getRemoteAction(id: Int, title: String, event: PlayerEventType): RemoteAction {
|
||||
return RemoteAction(
|
||||
Icon.createWithResource(activity, id),
|
||||
title,
|
||||
title,
|
||||
getPen(event)
|
||||
)
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private fun updatePIPModeActions() {
|
||||
if (!isInPIPMode || !this::exoPlayer.isInitialized) return
|
||||
|
||||
val actions: ArrayList<RemoteAction> = ArrayList()
|
||||
|
||||
actions.add(getRemoteAction(R.drawable.go_back_30, "Go Back", PlayerEventType.SeekBack))
|
||||
|
||||
if (exoPlayer.isPlaying) {
|
||||
actions.add(getRemoteAction(R.drawable.netflix_pause, "Pause", PlayerEventType.Pause))
|
||||
} else {
|
||||
actions.add(getRemoteAction(R.drawable.ic_baseline_play_arrow_24, "Play", PlayerEventType.Play))
|
||||
}
|
||||
|
||||
actions.add(getRemoteAction(R.drawable.go_forward_30, "Go Forward", PlayerEventType.SeekForward))
|
||||
activity?.setPictureInPictureParams(PictureInPictureParams.Builder().setActions(actions).build())
|
||||
}
|
||||
|
||||
private var receiver: BroadcastReceiver? = null
|
||||
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean) {
|
||||
isInPIPMode = isInPictureInPictureMode
|
||||
if (isInPictureInPictureMode) {
|
||||
// Hide the full-screen UI (controls, etc.) while in picture-in-picture mode.
|
||||
player_holder.alpha = 0f
|
||||
receiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(
|
||||
context: Context,
|
||||
intent: Intent,
|
||||
) {
|
||||
if (ACTION_MEDIA_CONTROL != intent.action) {
|
||||
return
|
||||
}
|
||||
handlePlayerEvent(intent.getIntExtra(EXTRA_CONTROL_TYPE, 0))
|
||||
}
|
||||
}
|
||||
val filter = IntentFilter()
|
||||
filter.addAction(
|
||||
ACTION_MEDIA_CONTROL
|
||||
)
|
||||
activity?.registerReceiver(receiver, filter)
|
||||
updatePIPModeActions()
|
||||
} else {
|
||||
// Restore the full-screen UI.
|
||||
player_holder.alpha = 1f
|
||||
receiver?.let {
|
||||
activity?.unregisterReceiver(it)
|
||||
}
|
||||
activity?.hideSystemUI()
|
||||
this.view?.let { activity?.hideKeyboard(it) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun handlePlayerEvent(event: PlayerEventType) {
|
||||
handlePlayerEvent(event.value)
|
||||
}
|
||||
|
||||
private fun handlePlayerEvent(event: Int) {
|
||||
when (event) {
|
||||
PlayerEventType.Play.value -> exoPlayer.play()
|
||||
PlayerEventType.Pause.value -> exoPlayer.pause()
|
||||
PlayerEventType.SeekBack.value -> seekTime(-30000L)
|
||||
PlayerEventType.SeekForward.value -> seekTime(30000L)
|
||||
}
|
||||
}
|
||||
//endregion
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
settingsManager = PreferenceManager.getDefaultSharedPreferences(activity)
|
||||
swipeEnabled = settingsManager.getBoolean("swipe_enabled", true)
|
||||
swipeVerticalEnabled = settingsManager.getBoolean("swipe_vertical_enabled", true)
|
||||
playBackSpeedEnabled = settingsManager.getBoolean("playback_speed_enabled", false)
|
||||
playerResizeEnabled = settingsManager.getBoolean("player_resize_enabled", true)
|
||||
doubleTapEnabled = settingsManager.getBoolean("double_tap_enabled", false)
|
||||
|
||||
isInPlayer = true // NEED REFERENCE TO MAIN ACTIVITY FOR PIP
|
||||
|
||||
navigationBarHeight = requireContext().getNavigationBarHeight()
|
||||
statusBarHeight = requireContext().getStatusBarHeight()
|
||||
|
||||
|
@ -723,9 +831,6 @@ class PlayerFragment : Fragment() {
|
|||
}
|
||||
}
|
||||
|
||||
println(episodes)
|
||||
settingsManager = PreferenceManager.getDefaultSharedPreferences(activity)
|
||||
|
||||
val fastForwardTime = settingsManager.getInt("fast_forward_button_time", 10)
|
||||
exo_rew_text.text = fastForwardTime.toString()
|
||||
exo_ffwd_text.text = fastForwardTime.toString()
|
||||
|
@ -928,6 +1033,8 @@ class PlayerFragment : Fragment() {
|
|||
}
|
||||
|
||||
changeSkip()
|
||||
|
||||
initPlayer()
|
||||
}
|
||||
|
||||
private fun getCurrentUrl(): ExtractorLink? {
|
||||
|
@ -1003,24 +1110,28 @@ class PlayerFragment : Fragment() {
|
|||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
thread {
|
||||
// initPlayer()
|
||||
if (player_view != null) player_view.onResume()
|
||||
if (!isCurrentlyPlaying) {
|
||||
initPlayer()
|
||||
}
|
||||
if (player_view != null) player_view.onResume()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
activity?.hideSystemUI()
|
||||
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
|
||||
thread {
|
||||
initPlayer()
|
||||
if (Util.SDK_INT <= 23) {
|
||||
if (!isCurrentlyPlaying) {
|
||||
initPlayer()
|
||||
}
|
||||
if (player_view != null) player_view.onResume()
|
||||
}
|
||||
}
|
||||
|
||||
//TODO FIX NON PIP MODE BUG
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
isInPlayer = false
|
||||
// releasePlayer()
|
||||
|
||||
activity?.showSystemUI()
|
||||
|
@ -1029,14 +1140,18 @@ class PlayerFragment : Fragment() {
|
|||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
if (player_view != null) player_view.onPause()
|
||||
releasePlayer()
|
||||
if (Util.SDK_INT <= 23) {
|
||||
if (player_view != null) player_view.onPause()
|
||||
releasePlayer()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
if (player_view != null) player_view.onPause()
|
||||
releasePlayer()
|
||||
if (Util.SDK_INT > 23) {
|
||||
if (player_view != null) player_view.onPause()
|
||||
releasePlayer()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
|
@ -1229,7 +1344,7 @@ class PlayerFragment : Fragment() {
|
|||
}
|
||||
|
||||
override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
|
||||
// updatePIPModeActions()
|
||||
updatePIPModeActions()
|
||||
if (activity == null) return
|
||||
if (playWhenReady) {
|
||||
when (playbackState) {
|
||||
|
@ -1296,6 +1411,7 @@ class PlayerFragment : Fragment() {
|
|||
//http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun initPlayer() {
|
||||
isCurrentlyPlaying = true
|
||||
println("INIT PLAYER")
|
||||
view?.setOnTouchListener { _, _ -> return@setOnTouchListener true } // VERY IMPORTANT https://stackoverflow.com/questions/28818926/prevent-clicking-on-a-button-in-an-activity-while-showing-a-fragment
|
||||
val tempUrl = getCurrentUrl()
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package com.lagradost.cloudstream3.ui.settings
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import com.lagradost.cloudstream3.R
|
||||
|
||||
class SettingsFragment : PreferenceFragmentCompat() {
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
setPreferencesFromResource(R.xml.settings, rootKey)
|
||||
}
|
||||
}
|
6
app/src/main/res/drawable/ic_baseline_discord_24.xml
Normal file
6
app/src/main/res/drawable/ic_baseline_discord_24.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<vector android:height="27.5dp" android:tint="?attr/white"
|
||||
android:viewportHeight="293" android:viewportWidth="256"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white"
|
||||
android:pathData="M226.011429,0 L29.9885714,0 C13.4582857,0 0,13.4582857 0,30.1348571 L0,227.913143 C0,244.589714 13.4582857,258.048 29.9885714,258.048 L195.876571,258.048 L188.123429,230.985143 L206.848,248.393143 L224.548571,264.777143 L256,292.571429 L256,30.1348571 C256,13.4582857 242.541714,0 226.011429,0 Z M169.545143,191.049143 C169.545143,191.049143 164.278857,184.758857 159.890286,179.2 C179.053714,173.787429 186.368,161.792 186.368,161.792 C180.370286,165.741714 174.665143,168.521143 169.545143,170.422857 C162.230857,173.494857 155.209143,175.542857 148.333714,176.713143 C134.290286,179.346286 121.417143,178.614857 110.445714,176.566857 C102.107429,174.957714 94.9394286,172.617143 88.9417143,170.276571 C85.5771429,168.96 81.92,167.350857 78.2628571,165.302857 C77.824,165.010286 77.3851429,164.864 76.9462857,164.571429 C76.6537143,164.425143 76.5074286,164.278857 76.3611429,164.132571 C73.728,162.669714 72.2651429,161.645714 72.2651429,161.645714 C72.2651429,161.645714 79.2868571,173.348571 97.8651429,178.907429 C93.4765714,184.466286 88.064,191.049143 88.064,191.049143 C55.7348571,190.025143 43.4468571,168.813714 43.4468571,168.813714 C43.4468571,121.709714 64.512,83.5291429 64.512,83.5291429 C85.5771429,67.7302857 105.618286,68.1691429 105.618286,68.1691429 L107.081143,69.9245714 C80.7497143,77.5314286 68.608,89.088 68.608,89.088 C68.608,89.088 71.8262857,87.3325714 77.2388571,84.8457143 C92.8914286,77.9702857 105.325714,76.0685714 110.445714,75.6297143 C111.323429,75.4834286 112.054857,75.3371429 112.932571,75.3371429 C121.856,74.1668571 131.949714,73.8742857 142.482286,75.0445714 C156.379429,76.6537143 171.300571,80.7497143 186.514286,89.088 C186.514286,89.088 174.957714,78.1165714 150.089143,70.5097143 L152.137143,68.1691429 C152.137143,68.1691429 172.178286,67.7302857 193.243429,83.5291429 C193.243429,83.5291429 214.308571,121.709714 214.308571,168.813714 C214.308571,168.813714 201.874286,190.025143 169.545143,191.049143 Z M101.522286,122.733714 C93.184,122.733714 86.6011429,130.048 86.6011429,138.971429 C86.6011429,147.894857 93.3302857,155.209143 101.522286,155.209143 C109.860571,155.209143 116.443429,147.894857 116.443429,138.971429 C116.589714,130.048 109.860571,122.733714 101.522286,122.733714 M154.916571,122.733714 C146.578286,122.733714 139.995429,130.048 139.995429,138.971429 C139.995429,147.894857 146.724571,155.209143 154.916571,155.209143 C163.254857,155.209143 169.837714,147.894857 169.837714,138.971429 C169.837714,130.048 163.254857,122.733714 154.916571,122.733714"/>
|
||||
</vector>
|
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M21,3L3,3c-1.11,0 -2,0.89 -2,2v12c0,1.1 0.89,2 2,2h5v2h8v-2h5c1.1,0 1.99,-0.9 1.99,-2L23,5c0,-1.11 -0.9,-2 -2,-2zM21,17L3,17L3,5h18v12zM16,11l-7,4L9,7z"/>
|
||||
</vector>
|
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M19,11h-8v6h8v-6zM23,19L23,4.98C23,3.88 22.1,3 21,3L3,3c-1.1,0 -2,0.88 -2,1.98L1,19c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2zM21,19.02L3,19.02L3,4.97h18v14.05z"/>
|
||||
</vector>
|
5
app/src/main/res/drawable/ic_baseline_touch_app_24.xml
Normal file
5
app/src/main/res/drawable/ic_baseline_touch_app_24.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M9,11.24V7.5C9,6.12 10.12,5 11.5,5S14,6.12 14,7.5v3.74c1.21,-0.81 2,-2.18 2,-3.74C16,5.01 13.99,3 11.5,3S7,5.01 7,7.5C7,9.06 7.79,10.43 9,11.24zM18.84,15.87l-4.54,-2.26c-0.17,-0.07 -0.35,-0.11 -0.54,-0.11H13v-6C13,6.67 12.33,6 11.5,6S10,6.67 10,7.5v10.74c-3.6,-0.76 -3.54,-0.75 -3.67,-0.75c-0.31,0 -0.59,0.13 -0.79,0.33l-0.79,0.8l4.94,4.94C9.96,23.83 10.34,24 10.75,24h6.79c0.75,0 1.33,-0.55 1.44,-1.28l0.75,-5.27c0.01,-0.07 0.02,-0.14 0.02,-0.2C19.75,16.63 19.37,16.09 18.84,15.87z"/>
|
||||
</vector>
|
5
app/src/main/res/drawable/ic_github_logo.xml
Normal file
5
app/src/main/res/drawable/ic_github_logo.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<vector android:tint="?attr/white" xmlns:tools="http://schemas.android.com/tools" android:height="24dp" android:viewportHeight="1000"
|
||||
android:viewportWidth="1000" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="?attr/white" android:pathData="M455.34,24.62c-61.96,5.16 -121.85,22.37 -176.93,49.91c-80.55,40.62 -140.44,94.66 -190.36,170.73c-35.8,54.39 -60.24,116 -72.29,182.78C7.85,471.07 8.2,555.75 16.11,597.4c33.05,172.45 148.36,312.21 307.73,372.1c26.16,9.98 36.49,10.33 45.44,1.38c6.2,-6.2 6.88,-11.36 6.88,-52.67l0,-45.44l-43.72,-0c-37.86,-0 -46.47,-1.03 -60.24,-7.57c-27.19,-12.39 -45.44,-32.35 -62.65,-68.16c-15.15,-31.67 -34.42,-55.42 -58.17,-72.29c-23.75,-16.87 -5.16,-29.95 28.57,-20.31c14.8,4.48 23.06,9.64 37.86,25.13c10.33,10.67 24.44,26.85 30.98,36.14c7.57,10.67 18.93,20.65 30.98,27.54c16.52,9.29 22.03,10.67 44.75,10.33c14.11,-0.35 31.67,-2.76 38.9,-5.16c12.05,-4.48 13.77,-7.23 20.65,-27.54c4.13,-12.05 11.02,-26.85 15.49,-32.36l7.92,-9.98l-35.46,-7.57c-63.68,-13.43 -99.82,-32.01 -132.52,-68.16c-33.73,-36.83 -52.67,-94.31 -52.67,-160.4c0,-51.63 9.98,-84.68 36.83,-121.17l11.7,-16.18l-4.13,-21c-7.23,-37.52 2.75,-103.96 16.52,-109.12c14.46,-5.51 72.97,15.83 112.21,40.96l16.18,10.33l32.01,-6.2c44.06,-8.95 139.41,-9.29 183.47,-0.34l31.33,6.54l30.29,-17.56c33.73,-19.28 64.71,-30.64 87.43,-32.01l15.49,-1.03l6.54,17.21c8.61,22.03 11.71,70.91 5.85,93.97l-4.13,17.56l15.49,23.41c27.54,41.99 31.67,57.14 31.67,116.35c-0.34,43.37 -1.38,56.11 -7.92,79.17c-19.28,67.12 -60.24,110.84 -125.3,134.59c-8.26,3.1 -30.64,8.95 -50.25,13.08l-35.46,7.57l7.57,9.29c4.13,5.51 10.67,17.9 14.46,27.54c6.88,16.18 7.57,26.16 8.61,107.4c0.69,59.9 2.41,90.88 5.16,93.97c11.71,14.46 27.88,11.71 83.65,-14.8c67.12,-31.32 136.31,-88.12 182.09,-149.39c42.68,-56.45 77.11,-136.31 89.84,-206.88c7.92,-43.72 7.92,-121.51 0,-165.23c-19.96,-110.5 -81.58,-218.24 -165.57,-288.8C716.26,54.91 586.14,12.92 455.34,24.62z"
|
||||
tools:ignore="VectorPath"/>
|
||||
</vector>
|
|
@ -15,5 +15,9 @@
|
|||
android:id="@+id/navigation_notifications"
|
||||
android:icon="@drawable/netflix_download"
|
||||
android:title="@string/title_downloads"/>
|
||||
<item
|
||||
android:id="@+id/navigation_settings"
|
||||
android:icon="@drawable/netflix_download"
|
||||
android:title="@string/title_settings"/>
|
||||
|
||||
</menu>
|
|
@ -22,4 +22,10 @@
|
|||
android:name="com.lagradost.cloudstream3.ui.notifications.NotificationsFragment"
|
||||
android:label="@string/title_downloads"
|
||||
tools:layout="@layout/fragment_notifications"/>
|
||||
<fragment
|
||||
android:id="@+id/navigation_settings"
|
||||
android:layout_height="match_parent"
|
||||
android:name="com.lagradost.cloudstream3.ui.settings.SettingsFragment"
|
||||
android:label="@string/title_settings"
|
||||
/>
|
||||
</navigation>
|
|
@ -3,6 +3,7 @@
|
|||
<string name="title_home">Home</string>
|
||||
<string name="title_search">Search</string>
|
||||
<string name="title_downloads">Downloads</string>
|
||||
<string name="title_settings">Settings</string>
|
||||
<string name="search_hint">Search...</string>
|
||||
<string name="change_providers_descript">Change Providers</string>
|
||||
<string name="search_providers_list_key">search_providers_list</string>
|
||||
|
|
3
app/src/main/res/xml/backup_descriptor.xml
Normal file
3
app/src/main/res/xml/backup_descriptor.xml
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<full-backup-content>
|
||||
</full-backup-content>
|
67
app/src/main/res/xml/settings.xml
Normal file
67
app/src/main/res/xml/settings.xml
Normal file
|
@ -0,0 +1,67 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<PreferenceCategory/>
|
||||
<PreferenceCategory
|
||||
android:key="video"
|
||||
android:title="Player"
|
||||
app:isPreferenceVisible="true"
|
||||
>
|
||||
<SwitchPreference
|
||||
android:icon="@drawable/ic_baseline_picture_in_picture_alt_24"
|
||||
app:key="pip_enabled"
|
||||
android:title="Picture-in-picture"
|
||||
android:summary="Continues playback in a miniature player on top of other apps"
|
||||
app:defaultValue="true"
|
||||
/>
|
||||
<SwitchPreference
|
||||
android:icon="@drawable/ic_baseline_aspect_ratio_24"
|
||||
app:key="player_resize_enabled"
|
||||
android:title="Player resize button"
|
||||
android:summary="Remove the black borders"
|
||||
app:defaultValue="true"
|
||||
/>
|
||||
<SwitchPreference
|
||||
android:icon="@drawable/ic_baseline_speed_24"
|
||||
app:key="playback_speed_enabled"
|
||||
android:title="Eigengrau Mode"
|
||||
android:summary="Adds the speed option in the player"
|
||||
app:defaultValue="true"
|
||||
/>
|
||||
<SwitchPreference
|
||||
android:icon="@drawable/ic_baseline_ondemand_video_24"
|
||||
app:key="swipe_enabled"
|
||||
android:title="Swipe to seek"
|
||||
android:summary="Swipe left or right to control time in the videoplayer"
|
||||
app:defaultValue="true"
|
||||
/>
|
||||
<SwitchPreference
|
||||
android:icon="@drawable/ic_baseline_ondemand_video_24"
|
||||
app:key="swipe_vertical_enabled"
|
||||
android:title="Swipe to change settings"
|
||||
android:summary="Swipe on the left or right side to change brightness or volume"
|
||||
app:defaultValue="true"
|
||||
/>
|
||||
<SwitchPreference
|
||||
android:icon="@drawable/ic_baseline_touch_app_24"
|
||||
app:key="double_tap_enabled"
|
||||
android:title="Double tap to seek"
|
||||
android:summary="Tap twice on the right or left side to seek forwards or backwards"
|
||||
app:defaultValue="false"
|
||||
/>
|
||||
<Preference
|
||||
android:title="Github"
|
||||
android:icon="@drawable/ic_github_logo"
|
||||
app:summary="https://github.com/LagradOst/CloudStream-3">
|
||||
<intent android:action="android.intent.action.VIEW"
|
||||
android:data="https://github.com/LagradOst/CloudStream-3"/>
|
||||
</Preference>
|
||||
<Preference
|
||||
android:title="Join Discord"
|
||||
android:icon="@drawable/ic_baseline_discord_24"
|
||||
app:summary="https://discord.gg/5Hus6fM">
|
||||
<intent android:action="android.intent.action.VIEW"
|
||||
android:data="https://discord.gg/5Hus6fM"/>
|
||||
</Preference>
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
Loading…
Reference in a new issue