crash fix and headphones pause

This commit is contained in:
LagradOst 2022-01-13 22:09:05 +01:00
parent ca4d05bd34
commit 0f1229354a
9 changed files with 246 additions and 149 deletions

View file

@ -8,7 +8,6 @@
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="jbr-11" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />

View file

@ -35,8 +35,8 @@ android {
minSdkVersion 21
targetSdkVersion 30
versionCode 40
versionName "2.4.8"
versionCode 41
versionName "2.5.8"
resValue "string", "app_version",
"${defaultConfig.versionName}${versionNameSuffix ?: ""}"

View file

@ -39,7 +39,6 @@ object APIHolder {
WcoProvider(),
// MeloMovieProvider(), // Captcha for links
DubbedAnimeProvider(),
HDMProvider(),
IHaveNoTvProvider(), // Documentaries provider
//LookMovieProvider(), // RECAPTCHA (Please allow up to 5 seconds...)
VMoveeProvider(),
@ -58,8 +57,6 @@ object APIHolder {
//TmdbProvider(),
FilmanProvider(),
ZoroProvider(),
@ -81,6 +78,7 @@ object APIHolder {
private val backwardsCompatibleProviders = arrayListOf(
KawaiifuProvider(), // removed due to cloudflare
HDMProvider(),// removed due to cloudflare
)
fun getApiFromName(apiName: String?): MainAPI {
@ -179,7 +177,8 @@ object APIHolder {
fun Context.filterProviderByPreferredMedia(): List<MainAPI> {
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
val currentPrefMedia = settingsManager.getInt(this.getString(R.string.prefer_media_type_key), 0)
val currentPrefMedia =
settingsManager.getInt(this.getString(R.string.prefer_media_type_key), 0)
val langs = this.getApiProviderLangSettings()
val allApis = apis.filter { langs.contains(it.lang) }.filter { api -> api.hasMainPage }
return if (currentPrefMedia < 1) {
@ -275,7 +274,7 @@ fun parseRating(ratingString: String?): Int? {
return (floatRating * 10).toInt()
}
fun MainAPI.fixUrlNull(url : String?) : String? {
fun MainAPI.fixUrlNull(url: String?): String? {
if (url.isNullOrEmpty()) {
return null
}
@ -305,7 +304,7 @@ fun sortUrls(urls: Set<ExtractorLink>): List<ExtractorLink> {
return urls.sortedBy { t -> -t.quality }
}
fun sortSubs(subs : Set<SubtitleData>) : List<SubtitleData> {
fun sortSubs(subs: Set<SubtitleData>): List<SubtitleData> {
return subs.sortedBy { it.name }
}
@ -473,7 +472,7 @@ fun LoadResponse?.isAnimeBased(): Boolean {
return (this.type == TvType.Anime || this.type == TvType.ONA) // && (this is AnimeLoadResponse)
}
fun TvType?.isEpisodeBased() : Boolean {
fun TvType?.isEpisodeBased(): Boolean {
if (this == null) return false
return (this == TvType.TvSeries || this == TvType.Anime)
}
@ -573,7 +572,13 @@ fun MainAPI.newMovieLoadResponse(
dataUrl: String,
initializer: MovieLoadResponse.() -> Unit = { }
): MovieLoadResponse {
val builder = MovieLoadResponse(name = name, url = url, apiName = this.name, type = type, dataUrl = dataUrl)
val builder = MovieLoadResponse(
name = name,
url = url,
apiName = this.name,
type = type,
dataUrl = dataUrl
)
builder.initializer()
return builder
}
@ -634,7 +639,13 @@ fun MainAPI.newTvSeriesLoadResponse(
episodes: List<TvSeriesEpisode>,
initializer: TvSeriesLoadResponse.() -> Unit = { }
): TvSeriesLoadResponse {
val builder = TvSeriesLoadResponse(name = name, url = url, apiName = this.name, type = type, episodes = episodes)
val builder = TvSeriesLoadResponse(
name = name,
url = url,
apiName = this.name,
type = type,
episodes = episodes
)
builder.initializer()
return builder
}

View file

@ -1,26 +1,27 @@
package com.lagradost.cloudstream3.ui.player
import android.annotation.SuppressLint
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.*
import android.graphics.drawable.AnimatedImageDrawable
import android.graphics.drawable.AnimatedVectorDrawable
import android.media.metrics.PlaybackErrorEvent
import android.os.Build
import android.os.Bundle
import android.support.v4.media.session.MediaSessionCompat
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.Toast
import androidx.annotation.LayoutRes
import androidx.annotation.StringRes
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.media.session.MediaButtonReceiver
import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat
import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.PlaybackException
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout
import com.google.android.exoplayer2.ui.SubtitleView
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
@ -81,9 +82,20 @@ abstract class AbstractPlayerFragment(
throw NotImplementedError()
}
private fun keepScreenOn(on : Boolean) {
if(on) {
activity?.window?.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
} else {
activity?.window?.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
}
private fun updateIsPlaying(playing: Pair<CSPlayerLoading, CSPlayerLoading>) {
val (wasPlaying, isPlaying) = playing
val isPlayingRightNow = CSPlayerLoading.IsPlaying == isPlaying
val isPausedRightNow = CSPlayerLoading.IsPaused == isPlaying
keepScreenOn(!isPausedRightNow)
isBuffering = CSPlayerLoading.IsBuffering == isPlaying
if (isBuffering) {
@ -241,11 +253,48 @@ abstract class AbstractPlayerFragment(
private fun playerUpdated(player: Any?) {
if (player is ExoPlayer) {
context?.let { ctx ->
val mediaButtonReceiver = ComponentName(ctx, MediaButtonReceiver::class.java)
MediaSessionCompat(ctx, "Player", mediaButtonReceiver, null).let { media ->
//media.setCallback(mMediaSessionCallback)
//media.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS or MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS)
val mediaSessionConnector = MediaSessionConnector(media)
mediaSessionConnector.setPlayer(player)
media.isActive = true
mMediaSessionCompat = media
}
}
player_view?.player = player
player_view?.performClick()
}
}
private var mediaSessionConnector: MediaSessionConnector? = null
private var mMediaSessionCompat: MediaSessionCompat? = null
// this can be used in the future for players other than exoplayer
//private val mMediaSessionCallback: MediaSessionCompat.Callback = object : MediaSessionCompat.Callback() {
// override fun onMediaButtonEvent(mediaButtonEvent: Intent): Boolean {
// val keyEvent = mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT) as KeyEvent?
// if (keyEvent != null) {
// if (keyEvent.action == KeyEvent.ACTION_DOWN) { // NO DOUBLE SKIP
// val consumed = when (keyEvent.keyCode) {
// KeyEvent.KEYCODE_MEDIA_PAUSE -> callOnPause()
// KeyEvent.KEYCODE_MEDIA_PLAY -> callOnPlay()
// KeyEvent.KEYCODE_MEDIA_STOP -> callOnStop()
// KeyEvent.KEYCODE_MEDIA_NEXT -> callOnNext()
// else -> false
// }
// if (consumed) return true
// }
// }
//
// return super.onMediaButtonEvent(mediaButtonEvent)
// }
//}
@SuppressLint("SetTextI18n")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
resizeMode = getKey(RESIZE_MODE_KEY) ?: 0
@ -295,6 +344,7 @@ abstract class AbstractPlayerFragment(
keyEventListener = null
SubtitlesFragment.applyStyleEvent -= ::onSubStyleChanged
keepScreenOn(false)
super.onDestroy()
}

View file

@ -130,7 +130,7 @@ open class FullScreenPlayer : AbstractPlayerFragment(R.layout.fragment_player) {
if (isShowing) {
updateUIVisibility()
} else {
player_holder.postDelayed({ updateUIVisibility() }, 200)
player_holder?.postDelayed({ updateUIVisibility() }, 200)
}
val titleMove = if (isShowing) 0f else -50.toPx.toFloat()

View file

@ -17,6 +17,7 @@ import com.hippo.unifile.UniFile
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.CommonActivity.showToast
import com.lagradost.cloudstream3.mvvm.Resource
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
import com.lagradost.cloudstream3.mvvm.observe
import com.lagradost.cloudstream3.ui.player.PlayerSubtitleHelper.Companion.toSubtitleMimeType
@ -171,6 +172,7 @@ class GeneratorPlayer : FullScreenPlayer() {
var selectSourceDialog: AlertDialog? = null
override fun showMirrorsDialogue() {
try {
currentSelectedSubtitles = player.getCurrentPreferredSubtitle()
context?.let { ctx ->
val isPlaying = player.getIsPlaying()
@ -277,6 +279,9 @@ class GeneratorPlayer : FullScreenPlayer() {
sourceDialog.dismissSafe(activity)
}
}
} catch (e : Exception) {
logError(e)
}
}
private fun noLinksFound() {

View file

@ -755,9 +755,13 @@ class ResultFragment : Fragment() {
ACTION_PLAY_EPISODE_IN_BROWSER -> {
acquireSingeExtractorLink(getString(R.string.episode_action_play_in_browser)) { link ->
try {
val i = Intent(ACTION_VIEW)
i.data = Uri.parse(link.url)
startActivity(i)
} catch (e : Exception) {
logError(e)
}
}
}
@ -1125,11 +1129,15 @@ class ResultFragment : Fragment() {
}
result_share?.setOnClickListener {
try {
val i = Intent(ACTION_SEND)
i.type = "text/plain"
i.putExtra(EXTRA_SUBJECT, d.name)
i.putExtra(EXTRA_TEXT, d.url)
startActivity(createChooser(i, d.name))
} catch (e: Exception) {
logError(e)
}
}
updateSync(d.getId())

View file

@ -32,6 +32,7 @@ import com.lagradost.cloudstream3.DubStatus
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
import com.lagradost.cloudstream3.syncproviders.AccountManager
import com.lagradost.cloudstream3.syncproviders.OAuth2API
import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.aniListApi
@ -301,6 +302,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
}
fun getDownloadDirs(): List<String> {
return normalSafeApiCall {
val defaultDir = getDownloadDir()?.filePath
// app_name_download_path = Cloudstream and does not change depending on release.
@ -308,7 +310,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
val secondaryDir = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) null else Environment.getExternalStorageDirectory().absolutePath +
File.separator + resources.getString(R.string.app_name_download_path)
val first = listOf(defaultDir, secondaryDir)
return (try {
(try {
val currentDir = context?.getBasePath()?.let { it.first?.filePath ?: it.second }
(first +
@ -317,6 +319,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
} catch (e: Exception) {
first
}).filterNotNull().distinct()
} ?: emptyList()
}
downloadPathPreference.setOnPreferenceClickListener {

View file

@ -126,7 +126,12 @@ class InAppUpdater {
}
)!! < 0 else false
return if (foundVersion != null) {
Update(shouldUpdate, foundAsset.browser_download_url, foundVersion.groupValues[2], found.body)
Update(
shouldUpdate,
foundAsset.browser_download_url,
foundVersion.groupValues[2],
found.body
)
} else {
Update(false, null, null, null)
}
@ -135,7 +140,8 @@ class InAppUpdater {
}
private fun Activity.getPreReleaseUpdate(): Update {
val tagUrl = "https://api.github.com/repos/LagradOst/CloudStream-3/git/ref/tags/pre-release"
val tagUrl =
"https://api.github.com/repos/LagradOst/CloudStream-3/git/ref/tags/pre-release"
val releaseUrl = "https://api.github.com/repos/LagradOst/CloudStream-3/releases"
val headers = mapOf("Accept" to "application/vnd.github.v3+json")
val response =
@ -150,10 +156,16 @@ class InAppUpdater {
val tagResponse =
mapper.readValue<GithubTag>(app.get(tagUrl, headers = headers).text)
val shouldUpdate = (getString(R.string.prerelease_commit_hash) != tagResponse.github_object.sha)
val shouldUpdate =
(getString(R.string.prerelease_commit_hash) != tagResponse.github_object.sha)
return if (foundAsset != null) {
Update(shouldUpdate, foundAsset.browser_download_url, tagResponse.github_object.sha, found.body)
Update(
shouldUpdate,
foundAsset.browser_download_url,
tagResponse.github_object.sha,
found.body
)
} else {
Update(false, null, null, null)
}
@ -217,6 +229,7 @@ class InAppUpdater {
}
fun openApk(context: Context, uri: Uri) {
try {
uri.path?.let {
val contentUri = FileProvider.getUriForFile(
context,
@ -231,12 +244,18 @@ class InAppUpdater {
}
context.startActivity(installIntent)
}
} catch (e: Exception) {
logError(e)
}
}
fun Activity.runAutoUpdate(checkAutoUpdate: Boolean = true): Boolean {
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
if (!checkAutoUpdate || settingsManager.getBoolean(getString(R.string.auto_update_key), true)
if (!checkAutoUpdate || settingsManager.getBoolean(
getString(R.string.auto_update_key),
true
)
) {
val update = getAppUpdate()
if (update.shouldUpdate && update.updateURL != null) {
@ -264,7 +283,8 @@ class InAppUpdater {
showToast(context, R.string.download_started, Toast.LENGTH_LONG)
thread {
val downloadStatus =
normalSafeApiCall { context.downloadUpdate(update.updateURL) } ?: false
normalSafeApiCall { context.downloadUpdate(update.updateURL) }
?: false
if (!downloadStatus) {
runOnUiThread {
showToast(
@ -281,7 +301,8 @@ class InAppUpdater {
if (checkAutoUpdate) {
setNeutralButton(R.string.dont_show_again) { _, _ ->
settingsManager.edit().putBoolean("auto_update", false).apply()
settingsManager.edit().putBoolean("auto_update", false)
.apply()
}
}
}