diff --git a/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt index c7c3efdb6..0cc9d37b1 100644 --- a/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt @@ -46,7 +46,6 @@ import com.github.libretube.dialogs.AddtoPlaylistDialog import com.github.libretube.dialogs.DownloadDialog import com.github.libretube.dialogs.ShareDialog import com.github.libretube.obj.ChapterSegment -import com.github.libretube.obj.PipedStream import com.github.libretube.obj.Playlist import com.github.libretube.obj.Segment import com.github.libretube.obj.Segments @@ -60,6 +59,7 @@ import com.github.libretube.util.BackgroundMode import com.github.libretube.util.ConnectionHelper import com.github.libretube.util.CronetHelper import com.github.libretube.util.DescriptionAdapter +import com.github.libretube.util.PlayerHelper import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.formatShort import com.github.libretube.views.DoubleClickListener @@ -78,6 +78,7 @@ import com.google.android.exoplayer2.source.MediaSource import com.google.android.exoplayer2.source.MergingMediaSource import com.google.android.exoplayer2.source.ProgressiveMediaSource import com.google.android.exoplayer2.ui.AspectRatioFrameLayout +import com.google.android.exoplayer2.ui.CaptionStyleCompat import com.google.android.exoplayer2.ui.PlayerNotificationManager import com.google.android.exoplayer2.ui.StyledPlayerView import com.google.android.exoplayer2.ui.TimeBar @@ -349,6 +350,60 @@ class PlayerFragment : Fragment() { isPlayerLocked = !isPlayerLocked } + // set default playback speed + val playbackSpeed = + PreferenceHelper.getString(requireContext(), "playback_speed", "1F")!! + val playbackSpeeds = context?.resources?.getStringArray(R.array.playbackSpeed)!! + val playbackSpeedValues = + context?.resources?.getStringArray(R.array.playbackSpeedValues)!! + exoPlayer.setPlaybackSpeed(playbackSpeed.toFloat()) + val speedIndex = playbackSpeedValues.indexOf(playbackSpeed) + playerBinding.speedText.text = playbackSpeeds[speedIndex] + + // change playback speed button + playerBinding.speedText.setOnClickListener { + MaterialAlertDialogBuilder(requireContext()) + .setTitle(R.string.change_playback_speed) + .setItems(playbackSpeeds) { _, index -> + // set the new playback speed + val newPlaybackSpeed = playbackSpeedValues[index].toFloat() + exoPlayer.setPlaybackSpeed(newPlaybackSpeed) + playerBinding.speedText.text = playbackSpeeds[index] + } + .show() + } + + // repeat toggle button + playerBinding.repeatToggle.setOnClickListener { + if (exoPlayer.repeatMode == RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL) { + // turn off repeat mode + exoPlayer.repeatMode = RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE + playerBinding.repeatToggle.setColorFilter(Color.GRAY) + } else { + exoPlayer.repeatMode = RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL + playerBinding.repeatToggle.setColorFilter(Color.WHITE) + } + } + + // share button + binding.relPlayerShare.setOnClickListener { + val shareDialog = ShareDialog(videoId!!, false) + shareDialog.show(childFragmentManager, "ShareDialog") + } + + binding.relPlayerBackground.setOnClickListener { + // pause the current player + exoPlayer.pause() + + // start the background mode + BackgroundMode + .getInstance() + .playOnBackgroundMode( + requireContext(), + videoId!! + ) + } + binding.playerScrollView.viewTreeObserver .addOnScrollChangedListener { if (binding.playerScrollView.getChildAt(0).bottom @@ -738,6 +793,14 @@ class PlayerFragment : Fragment() { useController = false player = exoPlayer } + + val useSystemCaptionStyle = PreferenceHelper.getBoolean(requireContext(), "system_caption_style", true) + if (useSystemCaptionStyle) { + // set the subtitle style + val captionStyle = PlayerHelper.getCaptionStyle(requireContext()) + exoPlayerView.subtitleView?.setApplyEmbeddedStyles(captionStyle == CaptionStyleCompat.DEFAULT) + exoPlayerView.subtitleView?.setStyle(captionStyle) + } } private fun initializePlayerView(view: View, response: Streams) { @@ -766,29 +829,6 @@ class PlayerFragment : Fragment() { initializeChapters() } - // set default playback speed - val playbackSpeed = - PreferenceHelper.getString(requireContext(), "playback_speed", "1F")!! - val playbackSpeeds = context?.resources?.getStringArray(R.array.playbackSpeed)!! - val playbackSpeedValues = - context?.resources?.getStringArray(R.array.playbackSpeedValues)!! - exoPlayer.setPlaybackSpeed(playbackSpeed.toFloat()) - val speedIndex = playbackSpeedValues.indexOf(playbackSpeed) - playerBinding.speedText.text = playbackSpeeds[speedIndex] - - // change playback speed button - playerBinding.speedText.setOnClickListener { - MaterialAlertDialogBuilder(requireContext()) - .setTitle(R.string.change_playback_speed) - .setItems(playbackSpeeds) { _, index -> - // set the new playback speed - val newPlaybackSpeed = playbackSpeedValues[index].toFloat() - exoPlayer.setPlaybackSpeed(newPlaybackSpeed) - playerBinding.speedText.text = playbackSpeeds[index] - } - .show() - } - // Listener for play and pause icon change exoPlayer.addListener(object : Player.Listener { override fun onIsPlayingChanged(isPlaying: Boolean) { @@ -855,37 +895,6 @@ class PlayerFragment : Fragment() { } }) - // repeat toggle button - playerBinding.repeatToggle.setOnClickListener { - if (exoPlayer.repeatMode == RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL) { - // turn off repeat mode - exoPlayer.repeatMode = RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE - playerBinding.repeatToggle.setColorFilter(Color.GRAY) - } else { - exoPlayer.repeatMode = RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL - playerBinding.repeatToggle.setColorFilter(Color.WHITE) - } - } - - // share button - binding.relPlayerShare.setOnClickListener { - val shareDialog = ShareDialog(videoId!!, false) - shareDialog.show(childFragmentManager, "ShareDialog") - } - - binding.relPlayerBackground.setOnClickListener { - // pause the current player - exoPlayer.pause() - - // start the background mode - BackgroundMode - .getInstance() - .playOnBackgroundMode( - requireContext(), - videoId!! - ) - } - // check if livestream if (response.duration!! > 0) { // download clicked @@ -1195,7 +1204,7 @@ class PlayerFragment : Fragment() { exoPlayer.setMediaItem(mediaItem) } else { val videoUri = videosUrlArray[which] - val audioUrl = getMostBitRate(response.audioStreams!!) + val audioUrl = PlayerHelper.getMostBitRate(response.audioStreams!!) setMediaSource(videoUri, audioUrl) } exoPlayer.seekTo(lastPosition) @@ -1222,7 +1231,7 @@ class PlayerFragment : Fragment() { // search for quality preference in the available stream sources if (pipedStream.contains(defRes)) { val videoUri = videosUrlArray[index] - val audioUrl = getMostBitRate(streams.audioStreams!!) + val audioUrl = PlayerHelper.getMostBitRate(streams.audioStreams!!) setMediaSource(videoUri, audioUrl) playerBinding.qualityText.text = videosNameArray[index] return @@ -1244,7 +1253,7 @@ class PlayerFragment : Fragment() { // if nothing found, use the first list entry if (videosUrlArray.isNotEmpty()) { val videoUri = videosUrlArray[0] - val audioUrl = getMostBitRate(streams.audioStreams!!) + val audioUrl = PlayerHelper.getMostBitRate(streams.audioStreams!!) setMediaSource(videoUri, audioUrl) playerBinding.qualityText.text = videosNameArray[0] } @@ -1430,19 +1439,6 @@ class PlayerFragment : Fragment() { activity?.runOnUiThread(action) } - private fun getMostBitRate(audios: List): String { - var bitrate = 0 - var index = 0 - for ((i, audio) in audios.withIndex()) { - val q = audio.quality!!.replace(" kbps", "").toInt() - if (q > bitrate) { - bitrate = q - index = i - } - } - return audios[index].url!! - } - private fun fetchComments() { lifecycleScope.launchWhenCreated { val commentsResponse = try { diff --git a/app/src/main/java/com/github/libretube/util/PlayerHelper.kt b/app/src/main/java/com/github/libretube/util/PlayerHelper.kt new file mode 100644 index 000000000..b5c7c1c96 --- /dev/null +++ b/app/src/main/java/com/github/libretube/util/PlayerHelper.kt @@ -0,0 +1,34 @@ +package com.github.libretube.util + +import android.content.Context +import android.view.accessibility.CaptioningManager +import com.github.libretube.obj.PipedStream +import com.google.android.exoplayer2.ui.CaptionStyleCompat + +object PlayerHelper { + // get the best bit rate from audio streams + fun getMostBitRate(audios: List): String { + var bitrate = 0 + var index = 0 + for ((i, audio) in audios.withIndex()) { + val q = audio.quality!!.replace(" kbps", "").toInt() + if (q > bitrate) { + bitrate = q + index = i + } + } + return audios[index].url!! + } + + // get the system default caption style + fun getCaptionStyle(context: Context): CaptionStyleCompat { + val captioningManager = context.getSystemService(Context.CAPTIONING_SERVICE) as CaptioningManager + return if (!captioningManager.isEnabled) { + // system captions are disabled, using android default captions style + CaptionStyleCompat.DEFAULT + } else { + // system captions are enabled + CaptionStyleCompat.createFromCaptionStyle(captioningManager.userStyle) + } + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_caption.xml b/app/src/main/res/drawable/ic_caption.xml new file mode 100644 index 000000000..8720e7644 --- /dev/null +++ b/app/src/main/res/drawable/ic_caption.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e89d87c4c..8d53e5f21 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -249,4 +249,5 @@ Watch and search history Watch positions Reset watch positions + System caption style \ No newline at end of file diff --git a/app/src/main/res/xml/appearance_settings.xml b/app/src/main/res/xml/appearance_settings.xml index d3e5262df..4cae308d8 100644 --- a/app/src/main/res/xml/appearance_settings.xml +++ b/app/src/main/res/xml/appearance_settings.xml @@ -78,6 +78,16 @@ + + + + + +