Merge pull request #805 from Bnyro/master

bug fixes and cleanup
This commit is contained in:
Bnyro 2022-07-17 13:00:09 +02:00 committed by GitHub
commit 0a8d11458a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 200 additions and 126 deletions

View File

@ -107,47 +107,83 @@ class PlayerFragment : Fragment() {
private lateinit var binding: FragmentPlayerBinding
private lateinit var playerBinding: ExoStyledPlayerControlViewBinding
/**
* video information
*/
private var videoId: String? = null
private var playlistId: String? = null
private var sId: Int = 0
private var eId: Int = 0
private var paused = false
private var whichQuality = 0
private var transitioning = false
private var autoplay = false
private var isZoomed: Boolean = false
private var isSubscribed: Boolean = false
/**
* for the transition
*/
private var sId: Int = 0
private var eId: Int = 0
private var transitioning = false
/**
* for the comments
*/
private var commentsAdapter: CommentsAdapter? = null
private var commentsLoaded: Boolean? = false
private var nextPage: String? = null
private var isLoading = true
private lateinit var exoPlayerView: StyledPlayerView
/**
* for the player
*/
private lateinit var exoPlayer: ExoPlayer
private lateinit var trackSelector: DefaultTrackSelector
private lateinit var segmentData: Segments
private var relatedStreamsEnabled = true
private lateinit var chapters: List<ChapterSegment>
/**
* for the player view
*/
private lateinit var exoPlayerView: StyledPlayerView
private var isPlayerLocked: Boolean = false
private var subtitle = mutableListOf<SubtitleConfiguration>()
/**
* user preferences
*/
private var token = ""
private var relatedStreamsEnabled = true
private var autoplayEnabled = false
private val sponsorBlockPrefs = SponsorBlockPrefs()
private var autoRotationEnabled = true
private var playbackSpeed = "1F"
private var pausePlayerOnScreenOffEnabled = false
private var fullscreenOrientationPref = "ratio"
private var watchHistoryEnabled = true
private var watchPositionsEnabled = true
private var useSystemCaptionStyle = true
private var seekIncrement = 5L
private var videoFormatPreference = "WEBM"
private var defRes = ""
private var bufferingGoal = 50000
/**
* for autoplay
*/
private var relatedStreams: List<StreamItem>? = arrayListOf()
private var nextStreamId: String? = null
private var playlistStreamIds: MutableList<String> = arrayListOf()
private var playlistNextPage: String? = null
private var isPlayerLocked: Boolean = false
/**
* for the player notification
*/
private lateinit var mediaSession: MediaSessionCompat
private lateinit var mediaSessionConnector: MediaSessionConnector
private lateinit var playerNotification: PlayerNotificationManager
/**
* for the media description of the notification
*/
private lateinit var title: String
private lateinit var uploader: String
private lateinit var thumbnailUrl: String
private lateinit var chapters: List<ChapterSegment>
private val sponsorBlockPrefs = SponsorBlockPrefs()
private lateinit var subtitle: MutableList<SubtitleConfiguration>
private var autoRotationEnabled = true
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -172,12 +208,8 @@ class PlayerFragment : Fragment() {
super.onViewCreated(view, savedInstanceState)
hideKeyboard()
// save whether auto rotation is enabled
autoRotationEnabled = PreferenceHelper.getBoolean(
requireContext(),
"auto_fullscreen",
false
)
setUserPrefs()
val mainActivity = activity as MainActivity
if (autoRotationEnabled) {
// enable auto rotation
@ -188,8 +220,25 @@ class PlayerFragment : Fragment() {
mainActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
}
setSponsorBlockPrefs()
createExoPlayer()
initializeTransitionLayout()
initializeOnClickActions()
playVideo()
}
private fun setUserPrefs() {
token = PreferenceHelper.getToken(requireContext())
// save whether auto rotation is enabled
autoRotationEnabled = PreferenceHelper.getBoolean(
requireContext(),
"auto_fullscreen",
false
)
// save whether related streams and autoplay are enabled
autoplay = PreferenceHelper.getBoolean(
autoplayEnabled = PreferenceHelper.getBoolean(
requireContext(),
"autoplay",
false
@ -200,13 +249,91 @@ class PlayerFragment : Fragment() {
true
)
setSponsorBlockPrefs()
createExoPlayer(view)
initializeTransitionLayout(view)
playVideo(view)
playbackSpeed = PreferenceHelper.getString(
requireContext(),
"playback_speed",
"1F"
)!!
fullscreenOrientationPref = PreferenceHelper.getString(
requireContext(),
"fullscreen_orientation",
"ratio"
)!!
pausePlayerOnScreenOffEnabled = PreferenceHelper.getBoolean(
requireContext(),
"pause_screen_off",
false
)
watchPositionsEnabled = PreferenceHelper.getBoolean(
requireContext(),
"watch_positions_toggle",
true
)
watchHistoryEnabled = PreferenceHelper.getBoolean(
requireContext(),
"watch_history_toggle",
true
)
useSystemCaptionStyle = PreferenceHelper.getBoolean(
requireContext(),
"system_caption_style",
true
)
seekIncrement = PreferenceHelper.getString(
requireContext(),
"seek_increment",
"5"
)?.toLong()!! * 1000
videoFormatPreference = PreferenceHelper.getString(
requireContext(),
"player_video_format",
"WEBM"
)!!
defRes = PreferenceHelper.getString(
requireContext(),
"default_res",
""
)!!
bufferingGoal = PreferenceHelper.getString(
requireContext(),
"buffering_goal",
"50"
)?.toInt()!! * 1000
}
private fun initializeTransitionLayout(view: View) {
private fun setSponsorBlockPrefs() {
sponsorBlockPrefs.sponsorBlockEnabled =
PreferenceHelper.getBoolean(requireContext(), "sb_enabled_key", true)
sponsorBlockPrefs.sponsorNotificationsEnabled =
PreferenceHelper.getBoolean(requireContext(), "sb_notifications_key", true)
sponsorBlockPrefs.introEnabled =
PreferenceHelper.getBoolean(requireContext(), "intro_category_key", false)
sponsorBlockPrefs.selfPromoEnabled =
PreferenceHelper.getBoolean(requireContext(), "selfpromo_category_key", false)
sponsorBlockPrefs.interactionEnabled =
PreferenceHelper.getBoolean(requireContext(), "interaction_category_key", false)
sponsorBlockPrefs.sponsorsEnabled =
PreferenceHelper.getBoolean(requireContext(), "sponsors_category_key", true)
sponsorBlockPrefs.outroEnabled =
PreferenceHelper.getBoolean(requireContext(), "outro_category_key", false)
sponsorBlockPrefs.fillerEnabled =
PreferenceHelper.getBoolean(requireContext(), "filler_category_key", false)
sponsorBlockPrefs.musicOffTopicEnabled =
PreferenceHelper.getBoolean(requireContext(), "music_offtopic_category_key", false)
sponsorBlockPrefs.previewEnabled =
PreferenceHelper.getBoolean(requireContext(), "preview_category_key", false)
}
private fun initializeTransitionLayout() {
videoId = videoId!!.replace("/watch?v=", "")
val mainActivity = activity as MainActivity
@ -264,7 +391,10 @@ class PlayerFragment : Fragment() {
binding.playerMotionLayout.progress = 1.toFloat()
binding.playerMotionLayout.transitionToStart()
}
// actions that don't depend on video information
private fun initializeOnClickActions() {
binding.closeImageView.setOnClickListener {
Globals.isMiniPlayerVisible = false
binding.playerMotionLayout.transitionToEnd()
@ -292,14 +422,14 @@ class PlayerFragment : Fragment() {
}
}
binding.playImageView.setOnClickListener {
paused = if (paused) {
if (!exoPlayer.isPlaying) {
// start or go on playing
binding.playImageView.setImageResource(R.drawable.ic_pause)
exoPlayer.play()
false
} else {
// pause the video
binding.playImageView.setImageResource(R.drawable.ic_play)
exoPlayer.pause()
true
}
}
@ -329,12 +459,11 @@ class PlayerFragment : Fragment() {
// switching between original aspect ratio (black bars) and zoomed to fill device screen
playerBinding.aspectRatioButton.setOnClickListener {
val isZoomed = exoPlayerView.resizeMode != AspectRatioFrameLayout.RESIZE_MODE_FIT
if (isZoomed) {
exoPlayerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT
isZoomed = false
} else {
exoPlayerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM
isZoomed = true
}
}
@ -355,8 +484,6 @@ class PlayerFragment : Fragment() {
}
// 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)!!
@ -418,11 +545,11 @@ class PlayerFragment : Fragment() {
}
}
binding.commentsRecView.layoutManager = LinearLayoutManager(view.context)
binding.commentsRecView.layoutManager = LinearLayoutManager(view?.context)
binding.commentsRecView.setItemViewCacheSize(20)
binding.relatedRecView.layoutManager =
GridLayoutManager(view.context, resources.getInteger(R.integer.grid_items))
GridLayoutManager(view?.context, resources.getInteger(R.integer.grid_items))
}
private fun setFullscreen() {
@ -437,12 +564,9 @@ class PlayerFragment : Fragment() {
playerBinding.exoTitle.visibility = View.VISIBLE
playerBinding.closeImageButton.visibility = View.GONE
val mainActivity = activity as MainActivity
val fullscreenOrientationPref = PreferenceHelper
.getString(requireContext(), "fullscreen_orientation", "ratio")
scaleControls(1.3F)
val mainActivity = activity as MainActivity
if (!autoRotationEnabled) {
// different orientations of the video are only available when auto rotation is disabled
val orientation = when (fullscreenOrientationPref) {
@ -508,12 +632,7 @@ class PlayerFragment : Fragment() {
}
override fun onPause() {
// pause the player if the screen is turned off
val pausePlayerOnScreenOffEnabled = PreferenceHelper.getBoolean(
requireContext(),
"pause_screen_off",
false
)
// pauses the player if the screen is turned off
// check whether the screen is on
val pm = context?.getSystemService(Context.POWER_SERVICE) as PowerManager
@ -547,11 +666,6 @@ class PlayerFragment : Fragment() {
// save the watch position if video isn't finished and option enabled
private fun saveWatchPosition() {
val watchPositionsEnabled = PreferenceHelper.getBoolean(
requireContext(),
"watch_positions_toggle",
true
)
if (watchPositionsEnabled && exoPlayer.currentPosition != exoPlayer.duration) {
PreferenceHelper.saveWatchPosition(
requireContext(),
@ -586,7 +700,7 @@ class PlayerFragment : Fragment() {
}
}
private fun playVideo(view: View) {
private fun playVideo() {
fun run() {
lifecycleScope.launchWhenCreated {
val response = try {
@ -613,7 +727,7 @@ class PlayerFragment : Fragment() {
// set media sources for the player
setResolutionAndSubtitles(response)
prepareExoPlayerView()
initializePlayerView(view, response)
initializePlayerView(response)
seekToWatchPosition()
exoPlayer.prepare()
exoPlayer.play()
@ -624,8 +738,6 @@ class PlayerFragment : Fragment() {
if (!relatedStreamsEnabled) toggleComments()
// prepare for autoplay
initAutoPlay()
val watchHistoryEnabled =
PreferenceHelper.getBoolean(requireContext(), "Watch_history_toggle", true)
if (watchHistoryEnabled) {
PreferenceHelper.addToWatchHistory(requireContext(), videoId!!, response)
}
@ -653,7 +765,7 @@ class PlayerFragment : Fragment() {
// the function is working recursively
private fun initAutoPlay() {
// save related streams for autoplay
if (autoplay) {
if (autoplayEnabled) {
// if it's a playlist use the next video
if (playlistId != null) {
lateinit var playlist: Playlist // var for saving the list in
@ -710,33 +822,10 @@ class PlayerFragment : Fragment() {
if (videoId != nextStreamId) {
// save the id of the next stream as videoId and load the next video
videoId = nextStreamId
playVideo(view!!)
playVideo()
}
}
private fun setSponsorBlockPrefs() {
sponsorBlockPrefs.sponsorBlockEnabled =
PreferenceHelper.getBoolean(requireContext(), "sb_enabled_key", true)
sponsorBlockPrefs.sponsorNotificationsEnabled =
PreferenceHelper.getBoolean(requireContext(), "sb_notifications_key", true)
sponsorBlockPrefs.introEnabled =
PreferenceHelper.getBoolean(requireContext(), "intro_category_key", false)
sponsorBlockPrefs.selfPromoEnabled =
PreferenceHelper.getBoolean(requireContext(), "selfpromo_category_key", false)
sponsorBlockPrefs.interactionEnabled =
PreferenceHelper.getBoolean(requireContext(), "interaction_category_key", false)
sponsorBlockPrefs.sponsorsEnabled =
PreferenceHelper.getBoolean(requireContext(), "sponsors_category_key", true)
sponsorBlockPrefs.outroEnabled =
PreferenceHelper.getBoolean(requireContext(), "outro_category_key", false)
sponsorBlockPrefs.fillerEnabled =
PreferenceHelper.getBoolean(requireContext(), "filler_category_key", false)
sponsorBlockPrefs.musicOffTopicEnabled =
PreferenceHelper.getBoolean(requireContext(), "music_offtopic_category_key", false)
sponsorBlockPrefs.previewEnabled =
PreferenceHelper.getBoolean(requireContext(), "preview_category_key", false)
}
private fun fetchSponsorBlockSegments() {
fun run() {
lifecycleScope.launch(Dispatchers.IO) {
@ -798,7 +887,6 @@ class PlayerFragment : Fragment() {
player = exoPlayer
}
val useSystemCaptionStyle = PreferenceHelper.getBoolean(requireContext(), "system_caption_style", true)
if (useSystemCaptionStyle) {
// set the subtitle style
val captionStyle = PlayerHelper.getCaptionStyle(requireContext())
@ -807,7 +895,7 @@ class PlayerFragment : Fragment() {
}
}
private fun initializePlayerView(view: View, response: Streams) {
private fun initializePlayerView(response: Streams) {
binding.apply {
playerViewsInfo.text =
context?.getString(R.string.views, response.views.formatShort()) +
@ -876,11 +964,11 @@ class PlayerFragment : Fragment() {
playbackState == Player.STATE_ENDED &&
nextStreamId != null &&
!transitioning &&
autoplay
autoplayEnabled
) {
transitioning = true
// check whether autoplay is enabled
if (autoplay) playNextVideo()
if (autoplayEnabled) playNextVideo()
}
if (playWhenReady && playbackState == Player.STATE_READY) {
@ -961,13 +1049,12 @@ class PlayerFragment : Fragment() {
}
binding.playerChannel.setOnClickListener {
val activity = view.context as MainActivity
val activity = view?.context as MainActivity
val bundle = bundleOf("channel_id" to response.uploaderUrl)
activity.navController.navigate(R.id.channelFragment, bundle)
activity.binding.mainMotionLayout.transitionToEnd()
binding.playerMotionLayout.transitionToEnd()
}
val token = PreferenceHelper.getToken(requireContext())
if (token != "") {
val channelId = response.uploaderUrl?.replace("/channel/", "")
isSubscribed(binding.playerSubscribe, channelId!!)
@ -982,9 +1069,6 @@ class PlayerFragment : Fragment() {
}
private fun enableDoubleTapToSeek() {
val seekIncrement =
PreferenceHelper.getString(requireContext(), "seek_increment", "5")?.toLong()!! * 1000
val hideDoubleTapOverlayDelay = 700L
// enable rewind button
@ -1171,9 +1255,6 @@ class PlayerFragment : Fragment() {
}
private fun setResolutionAndSubtitles(response: Streams) {
val videoFormatPreference =
PreferenceHelper.getString(requireContext(), "player_video_format", "WEBM")
var videosNameArray: Array<CharSequence> = arrayOf()
var videosUrlArray: Array<Uri> = arrayOf()
@ -1222,9 +1303,8 @@ class PlayerFragment : Fragment() {
val captionLanguage = subtitlesNamesList[index]
val captionLanguageCode = subtitleCodesList[index]
// update the icon
// update the icon of the captions button
playerBinding.captions.setImageResource(R.drawable.ic_caption)
playerBinding.captions.setColorFilter(Color.WHITE)
// select the new caption preference
trackSelector.buildUponParameters()
@ -1236,7 +1316,6 @@ class PlayerFragment : Fragment() {
} else {
// none selected
playerBinding.captions.setImageResource(R.drawable.ic_caption_outlined)
playerBinding.captions.setColorFilter(Color.GRAY)
// disable captions
trackSelector.buildUponParameters()
@ -1266,7 +1345,6 @@ class PlayerFragment : Fragment() {
.setItems(
videosNameArray
) { _, which ->
whichQuality = which
if (
videosNameArray[which] == getString(R.string.hls) ||
videosNameArray[which] == "LBRY HLS"
@ -1295,12 +1373,6 @@ class PlayerFragment : Fragment() {
videosNameArray: Array<CharSequence>,
videosUrlArray: Array<Uri>
) {
val defRes = PreferenceHelper.getString(
requireContext(),
"default_res",
""
)!!
if (defRes != "") {
videosNameArray.forEachIndexed { index, pipedStream ->
// search for quality preference in the available stream sources
@ -1334,10 +1406,7 @@ class PlayerFragment : Fragment() {
}
}
private fun createExoPlayer(view: View) {
val bufferingGoal =
PreferenceHelper.getString(requireContext(), "buffering_goal", "50")?.toInt()!! * 1000
private fun createExoPlayer() {
val cronetEngine: CronetEngine = CronetHelper.getCronetEngine()
val cronetDataSourceFactory: CronetDataSource.Factory =
CronetDataSource.Factory(cronetEngine, Executors.newCachedThreadPool())
@ -1367,7 +1436,7 @@ class PlayerFragment : Fragment() {
trackSelector = DefaultTrackSelector(requireContext())
exoPlayer = ExoPlayer.Builder(view.context)
exoPlayer = ExoPlayer.Builder(requireContext())
.setMediaSourceFactory(DefaultMediaSourceFactory(dataSourceFactory))
.setLoadControl(loadControl)
.setTrackSelector(trackSelector)
@ -1416,8 +1485,7 @@ class PlayerFragment : Fragment() {
// hide the close image button
playerBinding.closeImageButton.visibility =
if (isLocked &&
!Globals.isFullScreen &&
autoRotationEnabled
!(Globals.isFullScreen && !autoRotationEnabled)
) View.VISIBLE else View.GONE
// disable double tap to seek when the player is locked
@ -1429,7 +1497,6 @@ class PlayerFragment : Fragment() {
fun run() {
lifecycleScope.launchWhenCreated {
val response = try {
val token = PreferenceHelper.getToken(requireContext())
RetrofitInstance.authApi.isSubscribed(
channel_id,
token
@ -1469,7 +1536,6 @@ class PlayerFragment : Fragment() {
fun run() {
lifecycleScope.launchWhenCreated {
try {
val token = PreferenceHelper.getToken(requireContext())
RetrofitInstance.authApi.subscribe(
token,
Subscribe(channel_id)
@ -1492,7 +1558,6 @@ class PlayerFragment : Fragment() {
fun run() {
lifecycleScope.launchWhenCreated {
try {
val token = PreferenceHelper.getToken(requireContext())
RetrofitInstance.authApi.unsubscribe(
token,
Subscribe(channel_id)
@ -1569,10 +1634,22 @@ class PlayerFragment : Fragment() {
// set portrait mode
unsetFullscreen()
with(binding.playerMotionLayout) {
getConstraintSet(R.id.start).constrainHeight(R.id.player, -1)
enableTransition(R.id.yt_transition, false)
}
binding.linLayout.visibility = View.GONE
Globals.isFullScreen = false
} else {
// enable exoPlayer controls again
exoPlayerView.useController = true
with(binding.playerMotionLayout) {
getConstraintSet(R.id.start).constrainHeight(R.id.player, 0)
enableTransition(R.id.yt_transition, true)
}
binding.linLayout.visibility = View.VISIBLE
}
}
@ -1581,7 +1658,7 @@ class PlayerFragment : Fragment() {
binding.playerScrollView.getHitRect(bounds)
if (SDK_INT >= Build.VERSION_CODES.O &&
exoPlayer.isPlaying && (binding.playerScrollView.getLocalVisibleRect(bounds) || Globals.isFullScreen)
(binding.playerScrollView.getLocalVisibleRect(bounds) || Globals.isFullScreen)
) {
activity?.enterPictureInPictureMode(updatePipParams())
}

View File

@ -32,15 +32,15 @@
<ImageView
android:id="@+id/close_imageButton"
style="@style/PlayerControlTop"
android:layout_marginEnd="-10dp"
android:src="@drawable/ic_close"
app:tint="@android:color/white" />
<ImageView
android:id="@+id/lock_player"
style="@style/PlayerControlTop"
android:layout_marginStart="-5dp"
android:scaleX=".9"
android:scaleY=".9"
android:scaleX=".8"
android:scaleY=".8"
android:src="@drawable/ic_unlocked" />
</LinearLayout>
@ -99,7 +99,7 @@
android:id="@+id/captions"
style="@style/PlayerControlTop"
android:src="@drawable/ic_caption_outlined"
app:tint="@android:color/darker_gray" />
app:tint="@android:color/white" />
<ImageButton
android:id="@+id/repeat_toggle"
@ -121,16 +121,14 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginTop="@dimen/exo_styled_bottom_bar_margin_top"
android:layout_marginTop="10dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/exo_styled_bottom_bar_time_padding"
android:paddingLeft="@dimen/exo_styled_bottom_bar_time_padding"
android:paddingEnd="@dimen/exo_styled_bottom_bar_time_padding"
android:paddingRight="@dimen/exo_styled_bottom_bar_time_padding">
android:paddingStart="10dp"
android:paddingEnd="15dp" >
<LinearLayout
android:id="@id/exo_time"
@ -187,7 +185,6 @@
<ImageButton
android:id="@+id/fullscreen"
style="@style/PlayerControlBottom"
android:layout_marginEnd="5dp"
android:src="@drawable/ic_fullscreen"
app:tint="@android:color/white" />
@ -226,7 +223,7 @@
android:background="@android:color/transparent"
android:clipToPadding="false"
android:gravity="center"
android:padding="@dimen/exo_styled_controls_padding">
android:padding="20dp">
<ImageButton
android:id="@id/exo_play_pause"