This commit is contained in:
LagradOst 2021-07-17 23:36:50 +02:00
parent bd34c66592
commit 8a519176ca
7 changed files with 73 additions and 61 deletions

View file

@ -75,7 +75,4 @@ dependencies {
implementation 'com.google.android.exoplayer:extension-cast:2.14.1' 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-mediasession:2.14.1"
//implementation "com.google.android.exoplayer:extension-leanback:2.14.0" //implementation "com.google.android.exoplayer:extension-leanback:2.14.0"
//download manager
implementation "com.anggrayudi:storage:0.9.0"
} }

View file

@ -1,6 +1,8 @@
package com.lagradost.cloudstream3 package com.lagradost.cloudstream3
import android.R.attr
import android.app.PictureInPictureParams import android.app.PictureInPictureParams
import android.content.ComponentName
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.Build import android.os.Build
@ -10,24 +12,33 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupWithNavController 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.gms.cast.framework.CastButtonFactory
import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.bottomnavigation.BottomNavigationView
import com.lagradost.cloudstream3.UIHelper.checkWrite import com.lagradost.cloudstream3.UIHelper.checkWrite
import com.lagradost.cloudstream3.UIHelper.hasPIPPermission import com.lagradost.cloudstream3.UIHelper.hasPIPPermission
import com.lagradost.cloudstream3.UIHelper.isUsingMobileData
import com.lagradost.cloudstream3.UIHelper.requestRW import com.lagradost.cloudstream3.UIHelper.requestRW
import com.lagradost.cloudstream3.UIHelper.shouldShowPIPMode import com.lagradost.cloudstream3.UIHelper.shouldShowPIPMode
import com.lagradost.cloudstream3.receivers.VideoDownloadRestartReceiver 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.getKey
import com.lagradost.cloudstream3.utils.DataStore.getKeys 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.DataStore.removeKeys
import com.lagradost.cloudstream3.utils.DataStoreHelper.setViewPos
import com.lagradost.cloudstream3.utils.VideoDownloadManager import com.lagradost.cloudstream3.utils.VideoDownloadManager
import kotlinx.android.synthetic.main.fragment_result.* 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() { class MainActivity : AppCompatActivity() {
/*, ViewModelStoreOwner { /*, ViewModelStoreOwner {
@ -51,8 +62,6 @@ class MainActivity : AppCompatActivity() {
const val REQUEST_CODE_ASK_PERMISSIONS = 4 const val REQUEST_CODE_ASK_PERMISSIONS = 4
} }
private lateinit var storage: SimpleStorage
private fun enterPIPMode() { private fun enterPIPMode() {
if (!shouldShowPIPMode(isInPlayer) || !canShowPipMode) return if (!shouldShowPIPMode(isInPlayer) || !canShowPipMode) return
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
@ -96,25 +105,21 @@ class MainActivity : AppCompatActivity() {
super.onBackPressed() super.onBackPressed()
} }
private fun setupSimpleStorage() {
storage = SimpleStorage(this)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { 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) 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() { override fun onDestroy() {
@ -128,11 +133,6 @@ class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
mainContext = this mainContext = this
setupSimpleStorage()
if (!storage.isStorageAccessGranted(StorageId.PRIMARY)) {
storage.requestStorageAccess(REQUEST_CODE_STORAGE_ACCESS)
}
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
val navView: BottomNavigationView = findViewById(R.id.nav_view) val navView: BottomNavigationView = findViewById(R.id.nav_view)
@ -168,7 +168,7 @@ class MainActivity : AppCompatActivity() {
// this.startService(mServiceIntent) // this.startService(mServiceIntent)
//} //}
//settingsManager.getBoolean("disable_automatic_data_downloads", true) && //settingsManager.getBoolean("disable_automatic_data_downloads", true) &&
if ( isUsingMobileData()) { if (isUsingMobileData()) {
Toast.makeText(this, "Downloads not resumed on mobile data", Toast.LENGTH_LONG).show() Toast.makeText(this, "Downloads not resumed on mobile data", Toast.LENGTH_LONG).show()
} else { } else {
val keys = getKeys(VideoDownloadManager.KEY_RESUME_PACKAGES) val keys = getKeys(VideoDownloadManager.KEY_RESUME_PACKAGES)

View file

@ -11,6 +11,8 @@ import android.graphics.Color
import android.media.AudioAttributes import android.media.AudioAttributes
import android.media.AudioFocusRequest import android.media.AudioFocusRequest
import android.media.AudioManager import android.media.AudioManager
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.os.Build import android.os.Build
import android.view.Gravity import android.view.Gravity
import android.view.MenuItem 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.cast.framework.CastState
import com.google.android.gms.common.ConnectionResult import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability 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.ui.result.ResultFragment
import com.lagradost.cloudstream3.utils.Event import com.lagradost.cloudstream3.utils.Event
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -162,6 +165,25 @@ object UIHelper {
return false 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 { fun adjustAlpha(@ColorInt color: Int, factor: Float): Int {
val alpha = (Color.alpha(color) * factor).roundToInt() val alpha = (Color.alpha(color) * factor).roundToInt()

View file

@ -101,8 +101,8 @@ const val PLAYBACK_SPEED = "playback_speed"
const val RESIZE_MODE_KEY = "resize_mode" // Last used resize mode const val RESIZE_MODE_KEY = "resize_mode" // Last used resize mode
const val PLAYBACK_SPEED_KEY = "playback_speed" // Last used playback speed const val PLAYBACK_SPEED_KEY = "playback_speed" // Last used playback speed
const val OPENING_PROCENTAGE = 50 const val OPENING_PRECENTAGE = 50
const val AUTOLOAD_NEXT_EPISODE_PROCENTAGE = 80 const val AUTOLOAD_NEXT_EPISODE_PRECENTAGE = 80
enum class PlayerEventType(val value: Int) { enum class PlayerEventType(val value: Int) {
Stop(-1), Stop(-1),
@ -502,7 +502,7 @@ class PlayerFragment : Fragment() {
val percentage = ((position ?: exoPlayer.currentPosition) * 100 / exoPlayer.contentDuration).toInt() val percentage = ((position ?: exoPlayer.currentPosition) * 100 / exoPlayer.contentDuration).toInt()
val hasNext = hasNextEpisode() val hasNext = hasNextEpisode()
if (percentage >= AUTOLOAD_NEXT_EPISODE_PROCENTAGE && hasNext) { if (percentage >= AUTOLOAD_NEXT_EPISODE_PRECENTAGE && hasNext) {
val ep = val ep =
episodes[playerData.episodeIndex + 1] episodes[playerData.episodeIndex + 1]
@ -512,7 +512,7 @@ class PlayerFragment : Fragment() {
} }
} }
} }
val nextEp = percentage >= OPENING_PROCENTAGE val nextEp = percentage >= OPENING_PRECENTAGE
val isAnime = val isAnime =
data.isAnimeBased()//(data is AnimeLoadResponse && (data.type == TvType.Anime || data.type == TvType.ONA)) data.isAnimeBased()//(data is AnimeLoadResponse && (data.type == TvType.Anime || data.type == TvType.ONA))
@ -1267,7 +1267,6 @@ class PlayerFragment : Fragment() {
super.onDestroy() super.onDestroy()
isInPlayer = false isInPlayer = false
savePos()
savePositionInPlayer() savePositionInPlayer()
safeReleasePlayer() safeReleasePlayer()
@ -1377,17 +1376,17 @@ class PlayerFragment : Fragment() {
} }
val mimeType = if (currentUrl.isM3u8) MimeTypes.APPLICATION_M3U8 else MimeTypes.APPLICATION_MP4 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 //Replace needed for android 6.0.0 https://github.com/google/ExoPlayer/issues/5983
.setMimeType(mimeType) .setMimeType(mimeType)
if (isOnline) { if (isOnline) {
_mediaItem.setUri(currentUrl.url) mediaItemBuilder.setUri(currentUrl.url)
} else { } 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()) val trackSelector = DefaultTrackSelector(requireContext())
// Disable subtitles // Disable subtitles
trackSelector.parameters = DefaultTrackSelector.ParametersBuilder(requireContext()) 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 (height == null || width == null) currentUrl.name else "${currentUrl.name} - ${width}x${height}"
if (!hasUsedFirstRender) { // DON'T WANT TO SET MULTIPLE MESSAGES if (!hasUsedFirstRender) { // DON'T WANT TO SET MULTIPLE MESSAGES
println("FIRST RENDER")
changeSkip() changeSkip()
exoPlayer exoPlayer
.createMessage { _, _ -> .createMessage { _, _ ->
changeSkip() changeSkip()
} }
.setLooper(Looper.getMainLooper()) .setLooper(Looper.getMainLooper())
.setPosition( /* positionMs= */exoPlayer.contentDuration * OPENING_PROCENTAGE / 100) .setPosition( /* positionMs= */exoPlayer.contentDuration * OPENING_PRECENTAGE / 100)
// .setPayload(customPayloadData) // .setPayload(customPayloadData)
.setDeleteAfterDelivery(false) .setDeleteAfterDelivery(false)
.send() .send()
@ -1486,7 +1484,7 @@ class PlayerFragment : Fragment() {
changeSkip() changeSkip()
} }
.setLooper(Looper.getMainLooper()) .setLooper(Looper.getMainLooper())
.setPosition( /* positionMs= */exoPlayer.contentDuration * AUTOLOAD_NEXT_EPISODE_PROCENTAGE / 100) .setPosition( /* positionMs= */exoPlayer.contentDuration * AUTOLOAD_NEXT_EPISODE_PRECENTAGE / 100)
// .setPayload(customPayloadData) // .setPayload(customPayloadData)
.setDeleteAfterDelivery(false) .setDeleteAfterDelivery(false)

View file

@ -28,7 +28,7 @@ import kotlinx.android.synthetic.main.result_episode.view.episode_text
import kotlinx.android.synthetic.main.result_episode_large.view.* import kotlinx.android.synthetic.main.result_episode_large.view.*
const val ACTION_PLAY_EPISODE_IN_PLAYER = 1 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_PLAY_EPISODE_IN_BROWSER = 3
const val ACTION_CHROME_CAST_EPISODE = 4 const val ACTION_CHROME_CAST_EPISODE = 4

View file

@ -17,7 +17,6 @@ import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.content.ContextCompat.getSystemService
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.core.text.color import androidx.core.text.color
import androidx.core.widget.NestedScrollView 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.colorFromAttribute
import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar
import com.lagradost.cloudstream3.UIHelper.getStatusBarHeight import com.lagradost.cloudstream3.UIHelper.getStatusBarHeight
import com.lagradost.cloudstream3.UIHelper.isAppInstalled
import com.lagradost.cloudstream3.UIHelper.isCastApiAvailable import com.lagradost.cloudstream3.UIHelper.isCastApiAvailable
import com.lagradost.cloudstream3.UIHelper.isConnectedToChromecast import com.lagradost.cloudstream3.UIHelper.isConnectedToChromecast
import com.lagradost.cloudstream3.UIHelper.popCurrentPage import com.lagradost.cloudstream3.UIHelper.popCurrentPage
@ -449,6 +449,7 @@ class ResultFragment : Fragment() {
val add = when (opv) { val add = when (opv) {
ACTION_CHROME_CAST_EPISODE -> isConnected ACTION_CHROME_CAST_EPISODE -> isConnected
ACTION_CHROME_CAST_MIRROR -> isConnected ACTION_CHROME_CAST_MIRROR -> isConnected
ACTION_PLAY_EPISODE_IN_VLC_PLAYER -> context?.isAppInstalled(VLC_PACKAGE) ?: false
else -> true else -> true
} }
if (add) { if (add) {
@ -497,7 +498,7 @@ class ResultFragment : Fragment() {
startChromecast(0) startChromecast(0)
} }
ACTION_PLAY_EPISODE_IN_EXTERNAL_PLAYER -> { ACTION_PLAY_EPISODE_IN_VLC_PLAYER -> {
if (activity?.checkWrite() != true) { if (activity?.checkWrite() != true) {
activity?.requestRW() activity?.requestRW()
if (activity?.checkWrite() == true) return@main if (activity?.checkWrite() == true) return@main
@ -517,14 +518,7 @@ class ResultFragment : Fragment() {
text += "\n#EXTINF:, ${link.name}\n${link.url}" text += "\n#EXTINF:, ${link.name}\n${link.url}"
} }
outputFile.writeText(text) 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) val vlcIntent = Intent(VLC_INTENT_ACTION_RESULT)
@ -542,21 +536,20 @@ class ResultFragment : Fragment() {
), "video/*" ), "video/*"
) )
val startId = FROM_PROGRESS val startId = VLC_FROM_PROGRESS
var position = startId var position = startId
if (startId == FROM_START) { if (startId == VLC_FROM_START) {
position = 1 position = 1
} else if (startId == FROM_PROGRESS) { } else if (startId == VLC_FROM_PROGRESS) {
position = 0 position = 0
} }
vlcIntent.putExtra("position", position) vlcIntent.putExtra("position", position)
vlcIntent.component = VLC_COMPONENT vlcIntent.component = VLC_COMPONENT
requireContext().setKey(VLC_LAST_ID_KEY, currentId)
activity?.startActivityForResult(vlcIntent, REQUEST_CODE) activity?.startActivityForResult(vlcIntent, VLC_REQUEST_CODE)
} }
ACTION_PLAY_EPISODE_IN_PLAYER -> { ACTION_PLAY_EPISODE_IN_PLAYER -> {

View file

@ -558,6 +558,8 @@ object VideoDownloadManager {
} }
DownloadActionType.Stop -> { DownloadActionType.Stop -> {
isStopped = true; updateNotification() isStopped = true; updateNotification()
context.removeKey(KEY_RESUME_PACKAGES, event.first.toString())
saveQueue(context)
} }
DownloadActionType.Resume -> { DownloadActionType.Resume -> {
isPaused = false; updateNotification() isPaused = false; updateNotification()