Skip to content

Commit d2d30ad

Browse files
authored
feat: option to change default video player (#929)
* feat: option to change default video player * docs: update changelog * docs: update changelog * refactor: improve code readability * refactor: address detekt issues * fix: prevent double choosers when gesture video player is enabled Before, the app was creating a system picker dialog instead of launching the gesture based player as intended by the preference. The "On video tap" preference only controls the list/grid item. * refactor: use clearer symbol names * refactor: update gesture player preference label * refactor: use clearer symbol names Refs: #917
1 parent 426b6b9 commit d2d30ad

File tree

11 files changed

+148
-58
lines changed

11 files changed

+148
-58
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased]
8+
### Added
9+
- Added "On video tap" option to choose between in-app player or default player app ([#917])
10+
811
### Fixed
912
- Fixed unnecessary "Video has no audio" toast when looping videos ([#876])
1013

@@ -292,6 +295,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
292295
[#830]: https://github.com/FossifyOrg/Gallery/issues/830
293296
[#831]: https://github.com/FossifyOrg/Gallery/issues/831
294297
[#876]: https://github.com/FossifyOrg/Gallery/issues/876
298+
[#917]: https://github.com/FossifyOrg/Gallery/issues/917
295299

296300
[Unreleased]: https://github.com/FossifyOrg/Gallery/compare/1.12.0...HEAD
297301
[1.12.0]: https://github.com/FossifyOrg/Gallery/compare/1.11.0...1.12.0

app/src/main/kotlin/org/fossify/gallery/activities/MediaActivity.kt

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,10 @@ import org.fossify.gallery.extensions.isDownloadsFolder
7676
import org.fossify.gallery.extensions.launchAbout
7777
import org.fossify.gallery.extensions.launchCamera
7878
import org.fossify.gallery.extensions.launchSettings
79-
import org.fossify.gallery.extensions.launchVideoPlayer
79+
import org.fossify.gallery.extensions.launchGesturePlayer
8080
import org.fossify.gallery.extensions.mediaDB
8181
import org.fossify.gallery.extensions.movePathsInRecycleBin
82+
import org.fossify.gallery.extensions.openPath
8283
import org.fossify.gallery.extensions.openRecycleBin
8384
import org.fossify.gallery.extensions.restoreRecycleBinPaths
8485
import org.fossify.gallery.extensions.showRecycleBinEmptyingDialog
@@ -90,6 +91,7 @@ import org.fossify.gallery.helpers.GET_ANY_INTENT
9091
import org.fossify.gallery.helpers.GET_IMAGE_INTENT
9192
import org.fossify.gallery.helpers.GET_VIDEO_INTENT
9293
import org.fossify.gallery.helpers.GridSpacingItemDecoration
94+
import org.fossify.gallery.helpers.IS_IN_RECYCLE_BIN
9395
import org.fossify.gallery.helpers.MAX_COLUMN_COUNT
9496
import org.fossify.gallery.helpers.MediaFetcher
9597
import org.fossify.gallery.helpers.PATH
@@ -102,6 +104,8 @@ import org.fossify.gallery.helpers.SHOW_RECYCLE_BIN
102104
import org.fossify.gallery.helpers.SHOW_TEMP_HIDDEN_DURATION
103105
import org.fossify.gallery.helpers.SKIP_AUTHENTICATION
104106
import org.fossify.gallery.helpers.SLIDESHOW_START_ON_ENTER
107+
import org.fossify.gallery.helpers.VIDEO_PLAYER_APP
108+
import org.fossify.gallery.helpers.VIDEO_PLAYER_SYSTEM
105109
import org.fossify.gallery.interfaces.MediaOperationsListener
106110
import org.fossify.gallery.models.Medium
107111
import org.fossify.gallery.models.ThumbnailItem
@@ -962,23 +966,42 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
962966
finish()
963967
} else {
964968
mWasFullscreenViewOpen = true
965-
val isVideo = path.isVideoFast()
966-
if (isVideo && config.openVideosOnSeparateScreen) {
967-
launchVideoPlayer(path)
968-
} else {
969-
Intent(this, ViewPagerActivity::class.java).apply {
970-
putExtra(SKIP_AUTHENTICATION, shouldSkipAuthentication())
971-
putExtra(PATH, path)
972-
putExtra(SHOW_ALL, mShowAll)
973-
putExtra(SHOW_FAVORITES, mPath == FAVORITES)
974-
putExtra(SHOW_RECYCLE_BIN, mPath == RECYCLE_BIN)
975-
putExtra(IS_FROM_GALLERY, true)
976-
startActivity(this)
977-
}
969+
if (!path.isVideoFast()) {
970+
openInViewPager(path)
971+
return
972+
}
973+
974+
when (config.videoPlayerType) {
975+
VIDEO_PLAYER_SYSTEM -> openSystemDefaultPlayer(path)
976+
VIDEO_PLAYER_APP -> if (config.gestureVideoPlayer) launchGesturePlayer(path) else openInViewPager(path)
977+
else -> openInViewPager(path) // unreachable by design
978978
}
979979
}
980980
}
981981

982+
private fun openInViewPager(path: String) {
983+
Intent(this, ViewPagerActivity::class.java).apply {
984+
putExtra(SKIP_AUTHENTICATION, shouldSkipAuthentication())
985+
putExtra(PATH, path)
986+
putExtra(SHOW_ALL, mShowAll)
987+
putExtra(SHOW_FAVORITES, mPath == FAVORITES)
988+
putExtra(SHOW_RECYCLE_BIN, mPath == RECYCLE_BIN)
989+
putExtra(IS_FROM_GALLERY, true)
990+
startActivity(this)
991+
}
992+
}
993+
994+
private fun openSystemDefaultPlayer(path: String) {
995+
openPath(
996+
path = path,
997+
forceChooser = false,
998+
extras = hashMapOf(SHOW_FAVORITES to (mPath == FAVORITES)).apply {
999+
if (path.startsWith(recycleBinPath)) put(IS_IN_RECYCLE_BIN, true)
1000+
if (shouldSkipAuthentication()) put(SKIP_AUTHENTICATION, true)
1001+
}
1002+
)
1003+
}
1004+
9821005
private fun gotMedia(media: ArrayList<ThumbnailItem>, isFromCache: Boolean) {
9831006
mIsGettingMedia = false
9841007
checkLastMediaChanged()

app/src/main/kotlin/org/fossify/gallery/activities/PhotoVideoActivity.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,8 @@ open class PhotoVideoActivity : BaseViewerActivity(), ViewPagerFragment.Fragment
189189

190190
var filename = getFilenameFromUri(mUri!!)
191191
mIsFromGallery = intent.getBooleanExtra(IS_FROM_GALLERY, false)
192-
if (mIsFromGallery && filename.isVideoFast() && config.openVideosOnSeparateScreen) {
193-
launchVideoPlayer()
192+
if (mIsFromGallery && filename.isVideoFast() && config.gestureVideoPlayer) {
193+
launchGesturePlayer()
194194
return
195195
}
196196

@@ -272,7 +272,7 @@ open class PhotoVideoActivity : BaseViewerActivity(), ViewPagerFragment.Fragment
272272
initBottomActions()
273273
}
274274

275-
private fun launchVideoPlayer() {
275+
private fun launchGesturePlayer() {
276276
val newUri = getFinalUriFromPath(mUri.toString(), BuildConfig.APPLICATION_ID)
277277
if (newUri == null) {
278278
toast(org.fossify.commons.R.string.unknown_error_occurred)

app/src/main/kotlin/org/fossify/gallery/activities/SearchActivity.kt

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import org.fossify.gallery.helpers.GridSpacingItemDecoration
2020
import org.fossify.gallery.helpers.MediaFetcher
2121
import org.fossify.gallery.helpers.PATH
2222
import org.fossify.gallery.helpers.SHOW_ALL
23+
import org.fossify.gallery.helpers.VIDEO_PLAYER_APP
24+
import org.fossify.gallery.helpers.VIDEO_PLAYER_SYSTEM
2325
import org.fossify.gallery.interfaces.MediaOperationsListener
2426
import org.fossify.gallery.models.Medium
2527
import org.fossify.gallery.models.ThumbnailItem
@@ -158,15 +160,23 @@ class SearchActivity : SimpleActivity(), MediaOperationsListener {
158160
}
159161

160162
private fun itemClicked(path: String) {
161-
val isVideo = path.isVideoFast()
162-
if (isVideo && config.openVideosOnSeparateScreen) {
163-
launchVideoPlayer(path)
164-
} else {
165-
Intent(this, ViewPagerActivity::class.java).apply {
166-
putExtra(PATH, path)
167-
putExtra(SHOW_ALL, false)
168-
startActivity(this)
169-
}
163+
if (!path.isVideoFast()) {
164+
openInViewPager(path)
165+
return
166+
}
167+
168+
when (config.videoPlayerType) {
169+
VIDEO_PLAYER_SYSTEM -> openPath(path = path, forceChooser = false)
170+
VIDEO_PLAYER_APP -> if (config.gestureVideoPlayer) launchGesturePlayer(path) else openInViewPager(path)
171+
else -> openInViewPager(path) // unreachable by design
172+
}
173+
}
174+
175+
private fun openInViewPager(path: String) {
176+
Intent(this, ViewPagerActivity::class.java).apply {
177+
putExtra(PATH, path)
178+
putExtra(SHOW_ALL, false)
179+
startActivity(this)
170180
}
171181
}
172182

app/src/main/kotlin/org/fossify/gallery/activities/SettingsActivity.kt

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class SettingsActivity : SimpleActivity() {
6666
setupRememberLastVideo()
6767
setupLoopVideos()
6868
setupOpenVideosOnSeparateScreen()
69+
setupOnVideoTap()
6970
setupMaxBrightness()
7071
setupUltraHdrRendering()
7172
setupCropThumbnails()
@@ -292,13 +293,39 @@ class SettingsActivity : SimpleActivity() {
292293
}
293294

294295
private fun setupOpenVideosOnSeparateScreen() {
295-
binding.settingsOpenVideosOnSeparateScreen.isChecked = config.openVideosOnSeparateScreen
296+
binding.settingsOpenVideosOnSeparateScreen.isChecked = config.gestureVideoPlayer
296297
binding.settingsOpenVideosOnSeparateScreenHolder.setOnClickListener {
297298
binding.settingsOpenVideosOnSeparateScreen.toggle()
298-
config.openVideosOnSeparateScreen = binding.settingsOpenVideosOnSeparateScreen.isChecked
299+
config.gestureVideoPlayer = binding.settingsOpenVideosOnSeparateScreen.isChecked
299300
}
300301
}
301302

303+
private fun setupOnVideoTap() {
304+
binding.settingsOnVideoTap.text = getVideoPlayerTypeText()
305+
binding.settingsOnVideoTapHolder.setOnClickListener {
306+
val items = arrayListOf(
307+
RadioItem(VIDEO_PLAYER_APP, getString(R.string.open_in_app_player)),
308+
RadioItem(VIDEO_PLAYER_SYSTEM, getString(R.string.open_system_default_player))
309+
)
310+
311+
RadioGroupDialog(
312+
activity = this@SettingsActivity,
313+
items = items,
314+
checkedItemId = config.videoPlayerType
315+
) {
316+
config.videoPlayerType = it as Int
317+
binding.settingsOnVideoTap.text = getVideoPlayerTypeText()
318+
}
319+
}
320+
}
321+
322+
private fun getVideoPlayerTypeText() = getString(
323+
when (config.videoPlayerType) {
324+
VIDEO_PLAYER_APP -> R.string.open_in_app_player
325+
else -> R.string.open_system_default_player
326+
}
327+
)
328+
302329
private fun setupMaxBrightness() {
303330
binding.settingsMaxBrightness.isChecked = config.maxBrightness
304331
binding.settingsMaxBrightnessHolder.setOnClickListener {
@@ -892,7 +919,8 @@ class SettingsActivity : SimpleActivity() {
892919
put(AUTOPLAY_VIDEOS, config.autoplayVideos)
893920
put(REMEMBER_LAST_VIDEO_POSITION, config.rememberLastVideoPosition)
894921
put(LOOP_VIDEOS, config.loopVideos)
895-
put(OPEN_VIDEOS_ON_SEPARATE_SCREEN, config.openVideosOnSeparateScreen)
922+
put(GESTURE_VIDEO_PLAYER, config.gestureVideoPlayer)
923+
put(VIDEO_PLAYER_TYPE, config.videoPlayerType)
896924
put(ALLOW_VIDEO_GESTURES, config.allowVideoGestures)
897925
put(ANIMATE_GIFS, config.animateGifs)
898926
put(CROP_THUMBNAILS, config.cropThumbnails)
@@ -1037,7 +1065,8 @@ class SettingsActivity : SimpleActivity() {
10371065
AUTOPLAY_VIDEOS -> config.autoplayVideos = value.toBoolean()
10381066
REMEMBER_LAST_VIDEO_POSITION -> config.rememberLastVideoPosition = value.toBoolean()
10391067
LOOP_VIDEOS -> config.loopVideos = value.toBoolean()
1040-
OPEN_VIDEOS_ON_SEPARATE_SCREEN -> config.openVideosOnSeparateScreen = value.toBoolean()
1068+
GESTURE_VIDEO_PLAYER -> config.gestureVideoPlayer = value.toBoolean()
1069+
VIDEO_PLAYER_TYPE -> config.videoPlayerType = value.toInt()
10411070
ALLOW_VIDEO_GESTURES -> config.allowVideoGestures = value.toBoolean()
10421071
ANIMATE_GIFS -> config.animateGifs = value.toBoolean()
10431072
CROP_THUMBNAILS -> config.cropThumbnails = value.toBoolean()

app/src/main/kotlin/org/fossify/gallery/extensions/Activity.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import android.provider.MediaStore.Files
1818
import android.provider.MediaStore.Images
1919
import android.provider.Settings
2020
import android.util.DisplayMetrics
21-
import android.view.View
2221
import androidx.appcompat.app.AppCompatActivity
2322
import androidx.exifinterface.media.ExifInterface
2423
import com.bumptech.glide.Glide
@@ -78,7 +77,7 @@ fun Activity.openPath(path: String, forceChooser: Boolean, extras: HashMap<Strin
7877
openPathIntent(path, forceChooser, BuildConfig.APPLICATION_ID, extras = extras)
7978
}
8079

81-
fun Activity.launchVideoPlayer(path: String, extras: HashMap<String, Boolean> = HashMap()) {
80+
fun Activity.launchGesturePlayer(path: String, extras: HashMap<String, Boolean> = HashMap()) {
8281
ensureBackgroundThread {
8382
val newUri = getFinalUriFromPath(path, BuildConfig.APPLICATION_ID)
8483
if (newUri == null) {

app/src/main/kotlin/org/fossify/gallery/fragments/VideoFragment.kt

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ import org.fossify.gallery.extensions.getActionBarHeight
7676
import org.fossify.gallery.extensions.getBottomActionsHeight
7777
import org.fossify.gallery.extensions.getFormattedDuration
7878
import org.fossify.gallery.extensions.getFriendlyMessage
79+
import org.fossify.gallery.extensions.launchGesturePlayer
7980
import org.fossify.gallery.extensions.parseFileChannel
8081
import org.fossify.gallery.helpers.Config
8182
import org.fossify.gallery.helpers.EXOPLAYER_MAX_BUFFER_MS
@@ -184,11 +185,7 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener,
184185
videoSurfaceFrame.controller.settings.swallowDoubleTaps = true
185186

186187
videoPlayOutline.setOnClickListener {
187-
if (mConfig.openVideosOnSeparateScreen) {
188-
launchVideoPlayer()
189-
} else {
190-
togglePlayPause()
191-
}
188+
if (mConfig.gestureVideoPlayer) activity.launchGesturePlayer(mMedium.path) else togglePlayPause()
192189
}
193190

194191
mPlayPauseButton = bottomVideoTimeHolder.videoTogglePlayPause
@@ -352,7 +349,7 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener,
352349
})
353350

354351
videoSurface.onGlobalLayout {
355-
if (mIsFragmentVisible && mConfig.autoplayVideos && !mConfig.openVideosOnSeparateScreen) {
352+
if (mIsFragmentVisible && mConfig.autoplayVideos && !mConfig.gestureVideoPlayer) {
356353
playVideo()
357354
}
358355
}
@@ -373,7 +370,7 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener,
373370
requireContext().config // make sure we get a new config, in case the user changed something in the app settings
374371
requireActivity().updateTextColors(binding.videoHolder)
375372
val allowVideoGestures = mConfig.allowVideoGestures
376-
mTextureView.beGoneIf(mConfig.openVideosOnSeparateScreen || mIsPanorama)
373+
mTextureView.beGoneIf(mConfig.gestureVideoPlayer || mIsPanorama)
377374
binding.videoSurfaceFrame.beGoneIf(mTextureView.isGone())
378375

379376
mVolumeSideScroll.beVisibleIf(allowVideoGestures && !mIsPanorama)
@@ -407,9 +404,8 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener,
407404
}
408405

409406
mIsFragmentVisible = menuVisible
410-
if (mWasFragmentInit && menuVisible && mConfig.autoplayVideos && !mConfig.openVideosOnSeparateScreen) {
411-
playVideo()
412-
}
407+
val shouldPlayVideo = mWasFragmentInit && menuVisible && mConfig.autoplayVideos && !mConfig.gestureVideoPlayer
408+
if (shouldPlayVideo) playVideo()
413409
}
414410

415411
override fun onConfigurationChanged(newConfig: Configuration) {
@@ -477,9 +473,8 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener,
477473
}
478474

479475
private fun initExoPlayer() {
480-
if (activity == null || mConfig.openVideosOnSeparateScreen || mIsPanorama || mExoPlayer != null) {
481-
return
482-
}
476+
val shouldSkipInit = activity == null || mConfig.gestureVideoPlayer || mIsPanorama || mExoPlayer != null
477+
if (shouldSkipInit) return
483478

484479
val isContentUri = mMedium.path.startsWith("content://")
485480
val uri = if (isContentUri) Uri.parse(mMedium.path) else Uri.fromFile(File(mMedium.path))
@@ -595,10 +590,6 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener,
595590
})
596591
}
597592

598-
private fun launchVideoPlayer() {
599-
listener?.launchViewVideoIntent(mMedium.path)
600-
}
601-
602593
private fun toggleFullscreen() {
603594
listener?.fragmentClicked()
604595
}
@@ -963,9 +954,7 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener,
963954
}
964955

965956
private fun setVideoSize() {
966-
if (activity == null || mConfig.openVideosOnSeparateScreen) {
967-
return
968-
}
957+
if (activity == null || mConfig.gestureVideoPlayer) return
969958

970959
val videoProportion = mVideoSize.x.toFloat() / mVideoSize.y.toFloat()
971960
val display = requireActivity().windowManager.defaultDisplay

app/src/main/kotlin/org/fossify/gallery/helpers/Config.kt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,14 @@ class Config(context: Context) : BaseConfig(context) {
217217
get() = prefs.getBoolean(MUTE_VIDEOS, false)
218218
set(muteVideos) = prefs.edit().putBoolean(MUTE_VIDEOS, muteVideos).apply()
219219

220-
var openVideosOnSeparateScreen: Boolean
221-
get() = prefs.getBoolean(OPEN_VIDEOS_ON_SEPARATE_SCREEN, false)
222-
set(openVideosOnSeparateScreen) = prefs.edit().putBoolean(OPEN_VIDEOS_ON_SEPARATE_SCREEN, openVideosOnSeparateScreen).apply()
220+
var gestureVideoPlayer: Boolean
221+
get() = prefs.getBoolean(GESTURE_VIDEO_PLAYER, false)
222+
set(gestureVideoPlayer) = prefs.edit().putBoolean(GESTURE_VIDEO_PLAYER, gestureVideoPlayer)
223+
.apply()
224+
225+
var videoPlayerType: Int
226+
get() = prefs.getInt(VIDEO_PLAYER_TYPE, VIDEO_PLAYER_APP)
227+
set(videoPlayerType) = prefs.edit().putInt(VIDEO_PLAYER_TYPE, videoPlayerType).apply()
223228

224229
var displayFileNames: Boolean
225230
get() = prefs.getBoolean(DISPLAY_FILE_NAMES, false)

app/src/main/kotlin/org/fossify/gallery/helpers/Constants.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ const val AUTOPLAY_VIDEOS = "autoplay_videos"
1717
const val REMEMBER_LAST_VIDEO_POSITION = "remember_last_video_position"
1818
const val LOOP_VIDEOS = "loop_videos"
1919
const val MUTE_VIDEOS = "mute_videos"
20-
const val OPEN_VIDEOS_ON_SEPARATE_SCREEN = "open_videos_on_separate_screen"
20+
const val GESTURE_VIDEO_PLAYER = "open_videos_on_separate_screen"
21+
const val VIDEO_PLAYER_TYPE = "video_player_type"
2122
const val ANIMATE_GIFS = "animate_gifs"
2223
const val MAX_BRIGHTNESS = "max_brightness"
2324
const val ULTRA_HDR_RENDERING = "ultra_hdr_rendering"
@@ -168,6 +169,10 @@ const val ROTATE_BY_SYSTEM_SETTING = 0
168169
const val ROTATE_BY_DEVICE_ROTATION = 1
169170
const val ROTATE_BY_ASPECT_RATIO = 2
170171

172+
// video player type
173+
const val VIDEO_PLAYER_APP = 0
174+
const val VIDEO_PLAYER_SYSTEM = 1
175+
171176
// file loading priority
172177
const val PRIORITY_SPEED = 0
173178
const val PRIORITY_COMPROMISE = 1

0 commit comments

Comments
 (0)