mirror of
https://github.com/FossifyOrg/Gallery.git
synced 2024-11-28 23:48:00 +01:00
Rework the mute button logic
See https://github.com/FossifyOrg/Gallery/issues/171#issuecomment-2378649690 - Mute button is now completely unlinked from the system volume. The only way to unmute the player is to use the unmute button. - Mute button state is now persisted.
This commit is contained in:
parent
6e98294147
commit
fafd6343d9
6 changed files with 62 additions and 81 deletions
|
@ -61,7 +61,6 @@ open class VideoPlayerActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListen
|
||||||
private var mVideoSize = Point(0, 0)
|
private var mVideoSize = Point(0, 0)
|
||||||
private var mTimerHandler = Handler()
|
private var mTimerHandler = Handler()
|
||||||
private var mPlayWhenReadyHandler = Handler()
|
private var mPlayWhenReadyHandler = Handler()
|
||||||
private var mVolumeController: VolumeController? = null
|
|
||||||
|
|
||||||
private var mIgnoreCloseDown = false
|
private var mIgnoreCloseDown = false
|
||||||
|
|
||||||
|
@ -119,7 +118,6 @@ open class VideoPlayerActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListen
|
||||||
binding.bottomVideoTimeHolder.videoSeekbar.progress = 0
|
binding.bottomVideoTimeHolder.videoSeekbar.progress = 0
|
||||||
mTimerHandler.removeCallbacksAndMessages(null)
|
mTimerHandler.removeCallbacksAndMessages(null)
|
||||||
mPlayWhenReadyHandler.removeCallbacksAndMessages(null)
|
mPlayWhenReadyHandler.removeCallbacksAndMessages(null)
|
||||||
mVolumeController?.destroy()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +187,11 @@ open class VideoPlayerActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListen
|
||||||
binding.bottomVideoTimeHolder.videoDuration.setOnClickListener { doSkip(true) }
|
binding.bottomVideoTimeHolder.videoDuration.setOnClickListener { doSkip(true) }
|
||||||
binding.bottomVideoTimeHolder.videoTogglePlayPause.setOnClickListener { togglePlayPause() }
|
binding.bottomVideoTimeHolder.videoTogglePlayPause.setOnClickListener { togglePlayPause() }
|
||||||
binding.bottomVideoTimeHolder.videoPlaybackSpeed.setOnClickListener { showPlaybackSpeedPicker() }
|
binding.bottomVideoTimeHolder.videoPlaybackSpeed.setOnClickListener { showPlaybackSpeedPicker() }
|
||||||
binding.bottomVideoTimeHolder.videoToggleMute.setOnClickListener { mVolumeController?.toggleMute() }
|
binding.bottomVideoTimeHolder.videoToggleMute.setOnClickListener {
|
||||||
|
config.muteVideos = !config.muteVideos
|
||||||
|
updatePlayerMuteState()
|
||||||
|
}
|
||||||
|
|
||||||
binding.videoSurfaceFrame.setOnClickListener { toggleFullscreen() }
|
binding.videoSurfaceFrame.setOnClickListener { toggleFullscreen() }
|
||||||
binding.videoSurfaceFrame.controller.settings.swallowDoubleTaps = true
|
binding.videoSurfaceFrame.controller.settings.swallowDoubleTaps = true
|
||||||
|
|
||||||
|
@ -239,12 +241,6 @@ open class VideoPlayerActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListen
|
||||||
}
|
}
|
||||||
|
|
||||||
mDragThreshold = DRAG_THRESHOLD * resources.displayMetrics.density
|
mDragThreshold = DRAG_THRESHOLD * resources.displayMetrics.density
|
||||||
mVolumeController = VolumeController(this) { isMuted ->
|
|
||||||
val icon = if (isMuted) R.drawable.ic_vector_speaker_off else R.drawable.ic_vector_speaker_on
|
|
||||||
binding.bottomVideoTimeHolder.videoToggleMute.setImageDrawable(
|
|
||||||
AppCompatResources.getDrawable(this, icon)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initExoPlayer() {
|
private fun initExoPlayer() {
|
||||||
|
@ -285,6 +281,8 @@ open class VideoPlayerActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListen
|
||||||
prepare()
|
prepare()
|
||||||
initListeners()
|
initListeners()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updatePlayerMuteState()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ExoPlayer.initListeners() {
|
private fun ExoPlayer.initListeners() {
|
||||||
|
@ -397,6 +395,21 @@ open class VideoPlayerActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updatePlayerMuteState() {
|
||||||
|
val isMuted = config.muteVideos
|
||||||
|
val drawableId = if (isMuted) {
|
||||||
|
mExoPlayer?.mute()
|
||||||
|
R.drawable.ic_vector_speaker_off
|
||||||
|
} else {
|
||||||
|
mExoPlayer?.unmute()
|
||||||
|
R.drawable.ic_vector_speaker_on
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.bottomVideoTimeHolder.videoToggleMute.setImageDrawable(
|
||||||
|
AppCompatResources.getDrawable(this, drawableId)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun setPosition(seconds: Int) {
|
private fun setPosition(seconds: Int) {
|
||||||
mExoPlayer?.seekTo(seconds * 1000L)
|
mExoPlayer?.seekTo(seconds * 1000L)
|
||||||
binding.bottomVideoTimeHolder.videoSeekbar.progress = seconds
|
binding.bottomVideoTimeHolder.videoSeekbar.progress = seconds
|
||||||
|
|
11
app/src/main/kotlin/org/fossify/gallery/extensions/Player.kt
Normal file
11
app/src/main/kotlin/org/fossify/gallery/extensions/Player.kt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
package org.fossify.gallery.extensions
|
||||||
|
|
||||||
|
import androidx.media3.common.Player
|
||||||
|
|
||||||
|
fun Player.mute() {
|
||||||
|
volume = 0f
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Player.unmute() {
|
||||||
|
volume = 1f
|
||||||
|
}
|
|
@ -34,9 +34,7 @@ import org.fossify.commons.helpers.ensureBackgroundThread
|
||||||
import org.fossify.gallery.R
|
import org.fossify.gallery.R
|
||||||
import org.fossify.gallery.activities.VideoActivity
|
import org.fossify.gallery.activities.VideoActivity
|
||||||
import org.fossify.gallery.databinding.PagerVideoItemBinding
|
import org.fossify.gallery.databinding.PagerVideoItemBinding
|
||||||
import org.fossify.gallery.extensions.config
|
import org.fossify.gallery.extensions.*
|
||||||
import org.fossify.gallery.extensions.hasNavBar
|
|
||||||
import org.fossify.gallery.extensions.parseFileChannel
|
|
||||||
import org.fossify.gallery.helpers.*
|
import org.fossify.gallery.helpers.*
|
||||||
import org.fossify.gallery.interfaces.PlaybackSpeedListener
|
import org.fossify.gallery.interfaces.PlaybackSpeedListener
|
||||||
import org.fossify.gallery.models.Medium
|
import org.fossify.gallery.models.Medium
|
||||||
|
@ -87,8 +85,6 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
|
||||||
private lateinit var mPlayPauseButton: ImageView
|
private lateinit var mPlayPauseButton: ImageView
|
||||||
private lateinit var mSeekBar: SeekBar
|
private lateinit var mSeekBar: SeekBar
|
||||||
|
|
||||||
private var mVolumeController: VolumeController? = null
|
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||||
val context = requireContext()
|
val context = requireContext()
|
||||||
val activity = requireActivity()
|
val activity = requireActivity()
|
||||||
|
@ -103,7 +99,11 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
|
||||||
videoHolder.setOnClickListener { toggleFullscreen() }
|
videoHolder.setOnClickListener { toggleFullscreen() }
|
||||||
videoPreview.setOnClickListener { toggleFullscreen() }
|
videoPreview.setOnClickListener { toggleFullscreen() }
|
||||||
bottomVideoTimeHolder.videoPlaybackSpeed.setOnClickListener { showPlaybackSpeedPicker() }
|
bottomVideoTimeHolder.videoPlaybackSpeed.setOnClickListener { showPlaybackSpeedPicker() }
|
||||||
bottomVideoTimeHolder.videoToggleMute.setOnClickListener { mVolumeController?.toggleMute() }
|
bottomVideoTimeHolder.videoToggleMute.setOnClickListener {
|
||||||
|
mConfig.muteVideos = !mConfig.muteVideos
|
||||||
|
updatePlayerMuteState()
|
||||||
|
}
|
||||||
|
|
||||||
videoSurfaceFrame.controller.settings.swallowDoubleTaps = true
|
videoSurfaceFrame.controller.settings.swallowDoubleTaps = true
|
||||||
|
|
||||||
videoPlayOutline.setOnClickListener {
|
videoPlayOutline.setOnClickListener {
|
||||||
|
@ -246,13 +246,6 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
|
||||||
restoreLastVideoSavedPosition()
|
restoreLastVideoSavedPosition()
|
||||||
}
|
}
|
||||||
|
|
||||||
mVolumeController = VolumeController(context) { isMuted ->
|
|
||||||
val icon = if (isMuted) R.drawable.ic_vector_speaker_off else R.drawable.ic_vector_speaker_on
|
|
||||||
binding.bottomVideoTimeHolder.videoToggleMute.setImageDrawable(
|
|
||||||
AppCompatResources.getDrawable(context, icon)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return mView
|
return mView
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,6 +416,8 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
|
||||||
|
|
||||||
initListeners()
|
initListeners()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updatePlayerMuteState()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ExoPlayer.initListeners() {
|
private fun ExoPlayer.initListeners() {
|
||||||
|
@ -692,6 +687,22 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updatePlayerMuteState() {
|
||||||
|
val context = context ?: return
|
||||||
|
val isMuted = mConfig.muteVideos
|
||||||
|
val drawableId = if (isMuted) {
|
||||||
|
mExoPlayer?.mute()
|
||||||
|
R.drawable.ic_vector_speaker_off
|
||||||
|
} else {
|
||||||
|
mExoPlayer?.unmute()
|
||||||
|
R.drawable.ic_vector_speaker_on
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.bottomVideoTimeHolder.videoToggleMute.setImageDrawable(
|
||||||
|
AppCompatResources.getDrawable(context, drawableId)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun playVideo() {
|
fun playVideo() {
|
||||||
if (mExoPlayer == null) {
|
if (mExoPlayer == null) {
|
||||||
initExoPlayer()
|
initExoPlayer()
|
||||||
|
@ -822,7 +833,6 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
|
||||||
private fun cleanup() {
|
private fun cleanup() {
|
||||||
pauseVideo()
|
pauseVideo()
|
||||||
releaseExoPlayer()
|
releaseExoPlayer()
|
||||||
mVolumeController?.destroy()
|
|
||||||
|
|
||||||
if (mWasFragmentInit) {
|
if (mWasFragmentInit) {
|
||||||
mCurrTimeView.text = 0.getFormattedDuration()
|
mCurrTimeView.text = 0.getFormattedDuration()
|
||||||
|
|
|
@ -205,6 +205,10 @@ class Config(context: Context) : BaseConfig(context) {
|
||||||
get() = prefs.getBoolean(LOOP_VIDEOS, false)
|
get() = prefs.getBoolean(LOOP_VIDEOS, false)
|
||||||
set(loop) = prefs.edit().putBoolean(LOOP_VIDEOS, loop).apply()
|
set(loop) = prefs.edit().putBoolean(LOOP_VIDEOS, loop).apply()
|
||||||
|
|
||||||
|
var muteVideos: Boolean
|
||||||
|
get() = prefs.getBoolean(MUTE_VIDEOS, false)
|
||||||
|
set(muteVideos) = prefs.edit().putBoolean(MUTE_VIDEOS, muteVideos).apply()
|
||||||
|
|
||||||
var openVideosOnSeparateScreen: Boolean
|
var openVideosOnSeparateScreen: Boolean
|
||||||
get() = prefs.getBoolean(OPEN_VIDEOS_ON_SEPARATE_SCREEN, false)
|
get() = prefs.getBoolean(OPEN_VIDEOS_ON_SEPARATE_SCREEN, false)
|
||||||
set(openVideosOnSeparateScreen) = prefs.edit().putBoolean(OPEN_VIDEOS_ON_SEPARATE_SCREEN, openVideosOnSeparateScreen).apply()
|
set(openVideosOnSeparateScreen) = prefs.edit().putBoolean(OPEN_VIDEOS_ON_SEPARATE_SCREEN, openVideosOnSeparateScreen).apply()
|
||||||
|
|
|
@ -16,6 +16,7 @@ const val IS_THIRD_PARTY_INTENT = "is_third_party_intent"
|
||||||
const val AUTOPLAY_VIDEOS = "autoplay_videos"
|
const val AUTOPLAY_VIDEOS = "autoplay_videos"
|
||||||
const val REMEMBER_LAST_VIDEO_POSITION = "remember_last_video_position"
|
const val REMEMBER_LAST_VIDEO_POSITION = "remember_last_video_position"
|
||||||
const val LOOP_VIDEOS = "loop_videos"
|
const val LOOP_VIDEOS = "loop_videos"
|
||||||
|
const val MUTE_VIDEOS = "mute_videos"
|
||||||
const val OPEN_VIDEOS_ON_SEPARATE_SCREEN = "open_videos_on_separate_screen"
|
const val OPEN_VIDEOS_ON_SEPARATE_SCREEN = "open_videos_on_separate_screen"
|
||||||
const val ANIMATE_GIFS = "animate_gifs"
|
const val ANIMATE_GIFS = "animate_gifs"
|
||||||
const val MAX_BRIGHTNESS = "max_brightness"
|
const val MAX_BRIGHTNESS = "max_brightness"
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
package org.fossify.gallery.helpers
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.database.ContentObserver
|
|
||||||
import android.media.AudioManager
|
|
||||||
import android.os.Handler
|
|
||||||
import android.os.Looper
|
|
||||||
import android.provider.Settings
|
|
||||||
import org.fossify.gallery.extensions.audioManager
|
|
||||||
|
|
||||||
class VolumeController(
|
|
||||||
private val context: Context,
|
|
||||||
private val streamType: Int = AudioManager.STREAM_MUSIC,
|
|
||||||
private val onVolumeChanged: (isMuted: Boolean) -> Unit
|
|
||||||
) {
|
|
||||||
private var audioManager = context.audioManager
|
|
||||||
private var savedVolume = audioManager.getStreamMaxVolume(streamType)
|
|
||||||
|
|
||||||
private val currentVolume: Int
|
|
||||||
get() = audioManager.getStreamVolume(streamType)
|
|
||||||
|
|
||||||
private val volumeObserver = object : ContentObserver(Handler(Looper.getMainLooper())) {
|
|
||||||
override fun onChange(selfChange: Boolean) {
|
|
||||||
super.onChange(selfChange)
|
|
||||||
onVolumeChanged(isMuted())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
context.contentResolver.registerContentObserver(Settings.System.CONTENT_URI, true, volumeObserver)
|
|
||||||
onVolumeChanged(isMuted())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isMuted() = currentVolume == 0
|
|
||||||
|
|
||||||
private fun mute() {
|
|
||||||
savedVolume = audioManager.getStreamVolume(streamType)
|
|
||||||
audioManager.setStreamVolume(streamType, 0, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun unmute() {
|
|
||||||
audioManager.setStreamVolume(streamType, savedVolume, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun toggleMute() {
|
|
||||||
if (isMuted()) {
|
|
||||||
unmute()
|
|
||||||
onVolumeChanged(false)
|
|
||||||
} else {
|
|
||||||
mute()
|
|
||||||
onVolumeChanged(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun destroy() {
|
|
||||||
context.contentResolver.unregisterContentObserver(volumeObserver)
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue