More player bug fixes (#543)

* Fix gesture controls in different modes

* Add border to double tap play/pause

* Fix a few PiP related bugs

* create a separate function for lock

* override default volume bar from volume control

* Fix a display settings bug in different orientations

* Fix minor brghtness bar text size bug
This commit is contained in:
Quickdesh 2022-04-23 14:05:19 +09:00 committed by GitHub
parent c097e565d9
commit a9ff9e792d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 97 additions and 37 deletions

View file

@ -13,6 +13,8 @@ import android.content.pm.ActivityInfo
import android.content.pm.PackageManager
import android.content.res.ColorStateList
import android.content.res.Configuration
import android.content.res.Configuration.ORIENTATION_LANDSCAPE
import android.content.res.Configuration.ORIENTATION_PORTRAIT
import android.graphics.Color
import android.graphics.drawable.Icon
import android.media.AudioFocusRequest
@ -25,6 +27,7 @@ import android.os.Looper
import android.os.ParcelFileDescriptor
import android.util.DisplayMetrics
import android.util.Rational
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View
import android.view.ViewAnimationUtils
@ -220,17 +223,17 @@ class PlayerActivity :
"seek" -> {
callback = seekTextRunnable
itemView = binding.seekView
delay = 500L
delay = 750L
}
"volume" -> {
callback = volumeViewRunnable
itemView = binding.volumeView
delay = 500L
delay = 750L
}
"brightness" -> {
callback = brightnessViewRunnable
itemView = binding.brightnessView
delay = 500L
delay = 750L
}
else -> return
}
@ -299,18 +302,6 @@ class PlayerActivity :
volumeControlStream = AudioManager.STREAM_MUSIC
val dm = DisplayMetrics()
windowManager.defaultDisplay.getRealMetrics(dm)
width = dm.widthPixels
height = dm.heightPixels
val gestures = Gestures(this, width.toFloat(), height.toFloat())
mDetector = GestureDetectorCompat(this, gestures)
player.setOnTouchListener { v, event ->
gestures.onTouch(v, event)
mDetector.onTouchEvent(event)
}
if (presenter?.needsInit() == true) {
val anime = intent.extras!!.getLong("anime", -1)
val episode = intent.extras!!.getLong("episode", -1)
@ -324,6 +315,31 @@ class PlayerActivity :
playerIsDestroyed = false
}
/**
* Sets up the gestures to be used
*/
@Suppress("DEPRECATION")
@SuppressLint("ClickableViewAccessibility")
private fun setupGestures() {
val dm = DisplayMetrics()
windowManager.defaultDisplay.getRealMetrics(dm)
width = dm.widthPixels
height = dm.heightPixels
val gestures = Gestures(this, width.toFloat(), height.toFloat())
mDetector = GestureDetectorCompat(this, gestures)
player.setOnTouchListener { v, event ->
gestures.onTouch(v, event)
mDetector.onTouchEvent(event)
}
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
if (newConfig.orientation == ORIENTATION_PORTRAIT || newConfig.orientation == ORIENTATION_LANDSCAPE) launchUI { setupGestures(); setViewMode() }
}
/**
* Switches to the previous episode if [previous] is true,
* to the next episode if [previous] is false
@ -402,7 +418,7 @@ class PlayerActivity :
MPVLib.setOptionString("panscan", "0.0")
}
0 -> {
val newAspect = "${binding.root.width}/${binding.root.height}"
val newAspect = "$width/$height"
MPVLib.setOptionString("video-aspect-override", newAspect)
MPVLib.setOptionString("panscan", "0.0")
}
@ -522,6 +538,46 @@ class PlayerActivity :
showGestureView("volume")
}
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
when (keyCode) {
KeyEvent.KEYCODE_VOLUME_UP -> {
verticalScrollRight(1 / maxVolume.toFloat())
return true
}
KeyEvent.KEYCODE_VOLUME_DOWN -> {
verticalScrollRight(-1 / maxVolume.toFloat())
return true
}
KeyEvent.KEYCODE_MEDIA_NEXT -> {
switchEpisode(false)
return true
}
// Not entirely sure how to handle these KeyCodes yet, need to learn some more
/**
KeyEvent.KEYCODE_MEDIA_PREVIOUS -> {
switchEpisode(true)
return true
}
KeyEvent.KEYCODE_MEDIA_PLAY -> {
player.paused = true
doubleTapPlayPause()
return true
}
KeyEvent.KEYCODE_MEDIA_PAUSE -> {
player.paused = false
doubleTapPlayPause()
return true
}
KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE -> {
doubleTapPlayPause()
return true
}
*/
else -> {}
}
return super.onKeyDown(keyCode, event)
}
fun initSeek() {
initialSeek = player.timePos ?: -1
}
@ -717,14 +773,13 @@ class PlayerActivity :
@RequiresApi(Build.VERSION_CODES.O)
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean, newConfig: Configuration?) {
isInPipMode = isInPictureInPictureMode
binding.playerControls.hideControls(!isInPictureInPictureMode)
if (isInPictureInPictureMode) binding.loadingIndicator.indicatorSize = binding.loadingIndicator.indicatorSize / 2
else binding.loadingIndicator.indicatorSize = binding.loadingIndicator.indicatorSize * 2
super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
if (isInPictureInPictureMode) {
// On Android TV it is required to hide controller in this PIP change callback
binding.playerControls.hideControls(true)
binding.loadingIndicator.indicatorSize = binding.loadingIndicator.indicatorSize / 2
mReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (intent == null || ACTION_MEDIA_CONTROL != intent.action) {
@ -752,18 +807,18 @@ class PlayerActivity :
}
registerReceiver(mReceiver, IntentFilter(ACTION_MEDIA_CONTROL))
} else {
if (player.paused!!) binding.playerControls.hideControls(false)
binding.loadingIndicator.indicatorSize = binding.loadingIndicator.indicatorSize * 2
if (mReceiver != null) {
unregisterReceiver(mReceiver)
mReceiver = null
}
binding.playerControls.hideControls(false)
}
}
@Suppress("DEPRECATION")
internal fun startPiP() {
if (packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
binding.playerControls.hideControls(true)
player.paused?.let { updatePictureInPictureActions(!it) }
?.let { this.enterPictureInPictureMode(it) }
}
@ -856,7 +911,6 @@ class PlayerActivity :
val intPos = pos / 1000F
MPVLib.command(arrayOf("set", "start", "$intPos"))
}
setViewMode()
subTracks = arrayOf(Track("nothing", "Off")) + it.subtitleTracks.toTypedArray()
audioTracks = arrayOf(Track("nothing", "Off")) + it.audioTracks.toTypedArray()
MPVLib.command(arrayOf("loadfile", parseVideoUrl(it.videoUrl)))
@ -1007,6 +1061,7 @@ class PlayerActivity :
binding.playerControls.binding.controlsTopLandscape.visibility = View.GONE
}
}
launchUI { setupGestures(); setViewMode() }
}
// mpv events

View file

@ -74,8 +74,8 @@ class PlayerControlsView @JvmOverloads constructor(context: Context, attrs: Attr
binding.pipBtn.setOnClickListener { activity.startPiP() }
// Lock and Unlock controls
binding.lockBtn.setOnClickListener { activity.isLocked = true; toggleControls() }
binding.unlockBtn.setOnClickListener { activity.isLocked = false; toggleControls() }
binding.lockBtn.setOnClickListener { lockControls(true) }
binding.unlockBtn.setOnClickListener { lockControls(false) }
// Cycle, Long click controls
binding.cycleAudioBtnLandscape.setOnLongClickListener { pickAudio(); true }
@ -105,9 +105,13 @@ class PlayerControlsView @JvmOverloads constructor(context: Context, attrs: Attr
}
}
private fun lockControls(locked: Boolean) {
activity.isLocked = locked
toggleControls()
}
internal fun toggleControls() {
if (activity.isLocked) {
// Hide controls
binding.controlsView.isVisible = false
if (!binding.lockedView.isVisible && !activity.player.paused!!) {
@ -131,7 +135,9 @@ class PlayerControlsView @JvmOverloads constructor(context: Context, attrs: Attr
}
internal fun hideControls(hide: Boolean) {
binding.controlsView.isVisible = !hide
animationHandler.removeCallbacks(controlsViewRunnable)
if (hide) binding.controlsView.isVisible = false
else showAndFadeControls()
}
internal fun updatePlaybackPos(position: Int) {
@ -166,6 +172,7 @@ class PlayerControlsView @JvmOverloads constructor(context: Context, attrs: Attr
internal fun showAndFadeControls() {
val itemView = if (!activity.isLocked) binding.controlsView else binding.lockedView
if (!itemView.isVisible) fadeInView(itemView)
itemView.visibility = View.VISIBLE
resetControlsFade()
}

View file

@ -74,7 +74,8 @@
android:layout_centerInParent="true"
android:layout_alignParentLeft="true"
android:layout_marginLeft="45dp"
android:visibility="gone">
android:visibility="gone"
tools:visibility="visible">
<TextView
android:id="@+id/volumeText"
@ -83,13 +84,13 @@
android:text="10"
android:gravity="left"
android:textColor="#FFFFFF"
android:textSize="15sp"
android:textSize="14sp"
android:layout_marginBottom="5dp"/>
<ProgressBar
style="@android:style/Widget.ProgressBar.Horizontal"
android:id="@+id/volumeBar"
android:layout_width="25dp"
android:layout_width="26dp"
android:layout_height="125dp"
android:max="15"
android:progress="10"
@ -116,7 +117,8 @@
android:layout_centerInParent="true"
android:layout_marginRight="45dp"
android:layout_marginTop="105dp"
android:visibility="gone">
android:visibility="gone"
tools:visibility="visible">
<TextView
android:id="@+id/brightnessText"
@ -125,12 +127,12 @@
android:layout_marginBottom="5dp"
android:text="100"
android:textColor="#FFFFFF"
android:textSize="15sp" />
android:textSize="14sp" />
<ProgressBar
android:id="@+id/brightnessBar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="25dp"
android:layout_width="26dp"
android:layout_height="125dp"
android:max="100"
android:progress="10"
@ -174,13 +176,9 @@
android:id="@+id/playPauseView"
android:layout_width="80dp"
android:layout_height="80dp"
android:state_enabled="true"
android:state_pressed="true"
android:state_focused="true"
android:layout_centerInParent="true"
android:contentDescription="Play/Pause"
android:textColor="@android:color/white"
android:background="#00000000"
android:background="#70000000"
android:visibility="gone"
app:tint="?attr/colorOnPrimarySurface"
tools:src="@drawable/ic_play_arrow_80dp" />