mirror of
https://github.com/libre-tube/LibreTube.git
synced 2024-12-14 22:30:30 +05:30
commit
0a8d11458a
@ -107,47 +107,83 @@ class PlayerFragment : Fragment() {
|
|||||||
private lateinit var binding: FragmentPlayerBinding
|
private lateinit var binding: FragmentPlayerBinding
|
||||||
private lateinit var playerBinding: ExoStyledPlayerControlViewBinding
|
private lateinit var playerBinding: ExoStyledPlayerControlViewBinding
|
||||||
|
|
||||||
|
/**
|
||||||
|
* video information
|
||||||
|
*/
|
||||||
private var videoId: String? = null
|
private var videoId: String? = null
|
||||||
private var playlistId: 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
|
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 commentsAdapter: CommentsAdapter? = null
|
||||||
private var commentsLoaded: Boolean? = false
|
private var commentsLoaded: Boolean? = false
|
||||||
private var nextPage: String? = null
|
private var nextPage: String? = null
|
||||||
private var isLoading = true
|
private var isLoading = true
|
||||||
private lateinit var exoPlayerView: StyledPlayerView
|
|
||||||
|
/**
|
||||||
|
* for the player
|
||||||
|
*/
|
||||||
private lateinit var exoPlayer: ExoPlayer
|
private lateinit var exoPlayer: ExoPlayer
|
||||||
private lateinit var trackSelector: DefaultTrackSelector
|
private lateinit var trackSelector: DefaultTrackSelector
|
||||||
private lateinit var segmentData: Segments
|
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 relatedStreams: List<StreamItem>? = arrayListOf()
|
||||||
private var nextStreamId: String? = null
|
private var nextStreamId: String? = null
|
||||||
private var playlistStreamIds: MutableList<String> = arrayListOf()
|
private var playlistStreamIds: MutableList<String> = arrayListOf()
|
||||||
private var playlistNextPage: String? = null
|
private var playlistNextPage: String? = null
|
||||||
|
|
||||||
private var isPlayerLocked: Boolean = false
|
/**
|
||||||
|
* for the player notification
|
||||||
|
*/
|
||||||
private lateinit var mediaSession: MediaSessionCompat
|
private lateinit var mediaSession: MediaSessionCompat
|
||||||
private lateinit var mediaSessionConnector: MediaSessionConnector
|
private lateinit var mediaSessionConnector: MediaSessionConnector
|
||||||
private lateinit var playerNotification: PlayerNotificationManager
|
private lateinit var playerNotification: PlayerNotificationManager
|
||||||
|
|
||||||
|
/**
|
||||||
|
* for the media description of the notification
|
||||||
|
*/
|
||||||
private lateinit var title: String
|
private lateinit var title: String
|
||||||
private lateinit var uploader: String
|
private lateinit var uploader: String
|
||||||
private lateinit var thumbnailUrl: 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?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@ -172,12 +208,8 @@ class PlayerFragment : Fragment() {
|
|||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
hideKeyboard()
|
hideKeyboard()
|
||||||
|
|
||||||
// save whether auto rotation is enabled
|
setUserPrefs()
|
||||||
autoRotationEnabled = PreferenceHelper.getBoolean(
|
|
||||||
requireContext(),
|
|
||||||
"auto_fullscreen",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
val mainActivity = activity as MainActivity
|
val mainActivity = activity as MainActivity
|
||||||
if (autoRotationEnabled) {
|
if (autoRotationEnabled) {
|
||||||
// enable auto rotation
|
// enable auto rotation
|
||||||
@ -188,8 +220,25 @@ class PlayerFragment : Fragment() {
|
|||||||
mainActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
|
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
|
// save whether related streams and autoplay are enabled
|
||||||
autoplay = PreferenceHelper.getBoolean(
|
autoplayEnabled = PreferenceHelper.getBoolean(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
"autoplay",
|
"autoplay",
|
||||||
false
|
false
|
||||||
@ -200,13 +249,91 @@ class PlayerFragment : Fragment() {
|
|||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
|
||||||
setSponsorBlockPrefs()
|
playbackSpeed = PreferenceHelper.getString(
|
||||||
createExoPlayer(view)
|
requireContext(),
|
||||||
initializeTransitionLayout(view)
|
"playback_speed",
|
||||||
playVideo(view)
|
"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=", "")
|
videoId = videoId!!.replace("/watch?v=", "")
|
||||||
|
|
||||||
val mainActivity = activity as MainActivity
|
val mainActivity = activity as MainActivity
|
||||||
@ -264,7 +391,10 @@ class PlayerFragment : Fragment() {
|
|||||||
|
|
||||||
binding.playerMotionLayout.progress = 1.toFloat()
|
binding.playerMotionLayout.progress = 1.toFloat()
|
||||||
binding.playerMotionLayout.transitionToStart()
|
binding.playerMotionLayout.transitionToStart()
|
||||||
|
}
|
||||||
|
|
||||||
|
// actions that don't depend on video information
|
||||||
|
private fun initializeOnClickActions() {
|
||||||
binding.closeImageView.setOnClickListener {
|
binding.closeImageView.setOnClickListener {
|
||||||
Globals.isMiniPlayerVisible = false
|
Globals.isMiniPlayerVisible = false
|
||||||
binding.playerMotionLayout.transitionToEnd()
|
binding.playerMotionLayout.transitionToEnd()
|
||||||
@ -292,14 +422,14 @@ class PlayerFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
binding.playImageView.setOnClickListener {
|
binding.playImageView.setOnClickListener {
|
||||||
paused = if (paused) {
|
if (!exoPlayer.isPlaying) {
|
||||||
|
// start or go on playing
|
||||||
binding.playImageView.setImageResource(R.drawable.ic_pause)
|
binding.playImageView.setImageResource(R.drawable.ic_pause)
|
||||||
exoPlayer.play()
|
exoPlayer.play()
|
||||||
false
|
|
||||||
} else {
|
} else {
|
||||||
|
// pause the video
|
||||||
binding.playImageView.setImageResource(R.drawable.ic_play)
|
binding.playImageView.setImageResource(R.drawable.ic_play)
|
||||||
exoPlayer.pause()
|
exoPlayer.pause()
|
||||||
true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,12 +459,11 @@ class PlayerFragment : Fragment() {
|
|||||||
|
|
||||||
// switching between original aspect ratio (black bars) and zoomed to fill device screen
|
// switching between original aspect ratio (black bars) and zoomed to fill device screen
|
||||||
playerBinding.aspectRatioButton.setOnClickListener {
|
playerBinding.aspectRatioButton.setOnClickListener {
|
||||||
|
val isZoomed = exoPlayerView.resizeMode != AspectRatioFrameLayout.RESIZE_MODE_FIT
|
||||||
if (isZoomed) {
|
if (isZoomed) {
|
||||||
exoPlayerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT
|
exoPlayerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT
|
||||||
isZoomed = false
|
|
||||||
} else {
|
} else {
|
||||||
exoPlayerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM
|
exoPlayerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM
|
||||||
isZoomed = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,8 +484,6 @@ class PlayerFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set default playback speed
|
// set default playback speed
|
||||||
val playbackSpeed =
|
|
||||||
PreferenceHelper.getString(requireContext(), "playback_speed", "1F")!!
|
|
||||||
val playbackSpeeds = context?.resources?.getStringArray(R.array.playbackSpeed)!!
|
val playbackSpeeds = context?.resources?.getStringArray(R.array.playbackSpeed)!!
|
||||||
val playbackSpeedValues =
|
val playbackSpeedValues =
|
||||||
context?.resources?.getStringArray(R.array.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.commentsRecView.setItemViewCacheSize(20)
|
||||||
|
|
||||||
binding.relatedRecView.layoutManager =
|
binding.relatedRecView.layoutManager =
|
||||||
GridLayoutManager(view.context, resources.getInteger(R.integer.grid_items))
|
GridLayoutManager(view?.context, resources.getInteger(R.integer.grid_items))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setFullscreen() {
|
private fun setFullscreen() {
|
||||||
@ -437,12 +564,9 @@ class PlayerFragment : Fragment() {
|
|||||||
playerBinding.exoTitle.visibility = View.VISIBLE
|
playerBinding.exoTitle.visibility = View.VISIBLE
|
||||||
playerBinding.closeImageButton.visibility = View.GONE
|
playerBinding.closeImageButton.visibility = View.GONE
|
||||||
|
|
||||||
val mainActivity = activity as MainActivity
|
|
||||||
val fullscreenOrientationPref = PreferenceHelper
|
|
||||||
.getString(requireContext(), "fullscreen_orientation", "ratio")
|
|
||||||
|
|
||||||
scaleControls(1.3F)
|
scaleControls(1.3F)
|
||||||
|
|
||||||
|
val mainActivity = activity as MainActivity
|
||||||
if (!autoRotationEnabled) {
|
if (!autoRotationEnabled) {
|
||||||
// different orientations of the video are only available when auto rotation is disabled
|
// different orientations of the video are only available when auto rotation is disabled
|
||||||
val orientation = when (fullscreenOrientationPref) {
|
val orientation = when (fullscreenOrientationPref) {
|
||||||
@ -508,12 +632,7 @@ class PlayerFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
// pause the player if the screen is turned off
|
// pauses the player if the screen is turned off
|
||||||
val pausePlayerOnScreenOffEnabled = PreferenceHelper.getBoolean(
|
|
||||||
requireContext(),
|
|
||||||
"pause_screen_off",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
|
|
||||||
// check whether the screen is on
|
// check whether the screen is on
|
||||||
val pm = context?.getSystemService(Context.POWER_SERVICE) as PowerManager
|
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
|
// save the watch position if video isn't finished and option enabled
|
||||||
private fun saveWatchPosition() {
|
private fun saveWatchPosition() {
|
||||||
val watchPositionsEnabled = PreferenceHelper.getBoolean(
|
|
||||||
requireContext(),
|
|
||||||
"watch_positions_toggle",
|
|
||||||
true
|
|
||||||
)
|
|
||||||
if (watchPositionsEnabled && exoPlayer.currentPosition != exoPlayer.duration) {
|
if (watchPositionsEnabled && exoPlayer.currentPosition != exoPlayer.duration) {
|
||||||
PreferenceHelper.saveWatchPosition(
|
PreferenceHelper.saveWatchPosition(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
@ -586,7 +700,7 @@ class PlayerFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun playVideo(view: View) {
|
private fun playVideo() {
|
||||||
fun run() {
|
fun run() {
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
val response = try {
|
val response = try {
|
||||||
@ -613,7 +727,7 @@ class PlayerFragment : Fragment() {
|
|||||||
// set media sources for the player
|
// set media sources for the player
|
||||||
setResolutionAndSubtitles(response)
|
setResolutionAndSubtitles(response)
|
||||||
prepareExoPlayerView()
|
prepareExoPlayerView()
|
||||||
initializePlayerView(view, response)
|
initializePlayerView(response)
|
||||||
seekToWatchPosition()
|
seekToWatchPosition()
|
||||||
exoPlayer.prepare()
|
exoPlayer.prepare()
|
||||||
exoPlayer.play()
|
exoPlayer.play()
|
||||||
@ -624,8 +738,6 @@ class PlayerFragment : Fragment() {
|
|||||||
if (!relatedStreamsEnabled) toggleComments()
|
if (!relatedStreamsEnabled) toggleComments()
|
||||||
// prepare for autoplay
|
// prepare for autoplay
|
||||||
initAutoPlay()
|
initAutoPlay()
|
||||||
val watchHistoryEnabled =
|
|
||||||
PreferenceHelper.getBoolean(requireContext(), "Watch_history_toggle", true)
|
|
||||||
if (watchHistoryEnabled) {
|
if (watchHistoryEnabled) {
|
||||||
PreferenceHelper.addToWatchHistory(requireContext(), videoId!!, response)
|
PreferenceHelper.addToWatchHistory(requireContext(), videoId!!, response)
|
||||||
}
|
}
|
||||||
@ -653,7 +765,7 @@ class PlayerFragment : Fragment() {
|
|||||||
// the function is working recursively
|
// the function is working recursively
|
||||||
private fun initAutoPlay() {
|
private fun initAutoPlay() {
|
||||||
// save related streams for autoplay
|
// save related streams for autoplay
|
||||||
if (autoplay) {
|
if (autoplayEnabled) {
|
||||||
// if it's a playlist use the next video
|
// if it's a playlist use the next video
|
||||||
if (playlistId != null) {
|
if (playlistId != null) {
|
||||||
lateinit var playlist: Playlist // var for saving the list in
|
lateinit var playlist: Playlist // var for saving the list in
|
||||||
@ -710,33 +822,10 @@ class PlayerFragment : Fragment() {
|
|||||||
if (videoId != nextStreamId) {
|
if (videoId != nextStreamId) {
|
||||||
// save the id of the next stream as videoId and load the next video
|
// save the id of the next stream as videoId and load the next video
|
||||||
videoId = nextStreamId
|
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() {
|
private fun fetchSponsorBlockSegments() {
|
||||||
fun run() {
|
fun run() {
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
@ -798,7 +887,6 @@ class PlayerFragment : Fragment() {
|
|||||||
player = exoPlayer
|
player = exoPlayer
|
||||||
}
|
}
|
||||||
|
|
||||||
val useSystemCaptionStyle = PreferenceHelper.getBoolean(requireContext(), "system_caption_style", true)
|
|
||||||
if (useSystemCaptionStyle) {
|
if (useSystemCaptionStyle) {
|
||||||
// set the subtitle style
|
// set the subtitle style
|
||||||
val captionStyle = PlayerHelper.getCaptionStyle(requireContext())
|
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 {
|
binding.apply {
|
||||||
playerViewsInfo.text =
|
playerViewsInfo.text =
|
||||||
context?.getString(R.string.views, response.views.formatShort()) +
|
context?.getString(R.string.views, response.views.formatShort()) +
|
||||||
@ -876,11 +964,11 @@ class PlayerFragment : Fragment() {
|
|||||||
playbackState == Player.STATE_ENDED &&
|
playbackState == Player.STATE_ENDED &&
|
||||||
nextStreamId != null &&
|
nextStreamId != null &&
|
||||||
!transitioning &&
|
!transitioning &&
|
||||||
autoplay
|
autoplayEnabled
|
||||||
) {
|
) {
|
||||||
transitioning = true
|
transitioning = true
|
||||||
// check whether autoplay is enabled
|
// check whether autoplay is enabled
|
||||||
if (autoplay) playNextVideo()
|
if (autoplayEnabled) playNextVideo()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playWhenReady && playbackState == Player.STATE_READY) {
|
if (playWhenReady && playbackState == Player.STATE_READY) {
|
||||||
@ -961,13 +1049,12 @@ class PlayerFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
binding.playerChannel.setOnClickListener {
|
binding.playerChannel.setOnClickListener {
|
||||||
val activity = view.context as MainActivity
|
val activity = view?.context as MainActivity
|
||||||
val bundle = bundleOf("channel_id" to response.uploaderUrl)
|
val bundle = bundleOf("channel_id" to response.uploaderUrl)
|
||||||
activity.navController.navigate(R.id.channelFragment, bundle)
|
activity.navController.navigate(R.id.channelFragment, bundle)
|
||||||
activity.binding.mainMotionLayout.transitionToEnd()
|
activity.binding.mainMotionLayout.transitionToEnd()
|
||||||
binding.playerMotionLayout.transitionToEnd()
|
binding.playerMotionLayout.transitionToEnd()
|
||||||
}
|
}
|
||||||
val token = PreferenceHelper.getToken(requireContext())
|
|
||||||
if (token != "") {
|
if (token != "") {
|
||||||
val channelId = response.uploaderUrl?.replace("/channel/", "")
|
val channelId = response.uploaderUrl?.replace("/channel/", "")
|
||||||
isSubscribed(binding.playerSubscribe, channelId!!)
|
isSubscribed(binding.playerSubscribe, channelId!!)
|
||||||
@ -982,9 +1069,6 @@ class PlayerFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun enableDoubleTapToSeek() {
|
private fun enableDoubleTapToSeek() {
|
||||||
val seekIncrement =
|
|
||||||
PreferenceHelper.getString(requireContext(), "seek_increment", "5")?.toLong()!! * 1000
|
|
||||||
|
|
||||||
val hideDoubleTapOverlayDelay = 700L
|
val hideDoubleTapOverlayDelay = 700L
|
||||||
|
|
||||||
// enable rewind button
|
// enable rewind button
|
||||||
@ -1171,9 +1255,6 @@ class PlayerFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setResolutionAndSubtitles(response: Streams) {
|
private fun setResolutionAndSubtitles(response: Streams) {
|
||||||
val videoFormatPreference =
|
|
||||||
PreferenceHelper.getString(requireContext(), "player_video_format", "WEBM")
|
|
||||||
|
|
||||||
var videosNameArray: Array<CharSequence> = arrayOf()
|
var videosNameArray: Array<CharSequence> = arrayOf()
|
||||||
var videosUrlArray: Array<Uri> = arrayOf()
|
var videosUrlArray: Array<Uri> = arrayOf()
|
||||||
|
|
||||||
@ -1222,9 +1303,8 @@ class PlayerFragment : Fragment() {
|
|||||||
val captionLanguage = subtitlesNamesList[index]
|
val captionLanguage = subtitlesNamesList[index]
|
||||||
val captionLanguageCode = subtitleCodesList[index]
|
val captionLanguageCode = subtitleCodesList[index]
|
||||||
|
|
||||||
// update the icon
|
// update the icon of the captions button
|
||||||
playerBinding.captions.setImageResource(R.drawable.ic_caption)
|
playerBinding.captions.setImageResource(R.drawable.ic_caption)
|
||||||
playerBinding.captions.setColorFilter(Color.WHITE)
|
|
||||||
|
|
||||||
// select the new caption preference
|
// select the new caption preference
|
||||||
trackSelector.buildUponParameters()
|
trackSelector.buildUponParameters()
|
||||||
@ -1236,7 +1316,6 @@ class PlayerFragment : Fragment() {
|
|||||||
} else {
|
} else {
|
||||||
// none selected
|
// none selected
|
||||||
playerBinding.captions.setImageResource(R.drawable.ic_caption_outlined)
|
playerBinding.captions.setImageResource(R.drawable.ic_caption_outlined)
|
||||||
playerBinding.captions.setColorFilter(Color.GRAY)
|
|
||||||
|
|
||||||
// disable captions
|
// disable captions
|
||||||
trackSelector.buildUponParameters()
|
trackSelector.buildUponParameters()
|
||||||
@ -1266,7 +1345,6 @@ class PlayerFragment : Fragment() {
|
|||||||
.setItems(
|
.setItems(
|
||||||
videosNameArray
|
videosNameArray
|
||||||
) { _, which ->
|
) { _, which ->
|
||||||
whichQuality = which
|
|
||||||
if (
|
if (
|
||||||
videosNameArray[which] == getString(R.string.hls) ||
|
videosNameArray[which] == getString(R.string.hls) ||
|
||||||
videosNameArray[which] == "LBRY HLS"
|
videosNameArray[which] == "LBRY HLS"
|
||||||
@ -1295,12 +1373,6 @@ class PlayerFragment : Fragment() {
|
|||||||
videosNameArray: Array<CharSequence>,
|
videosNameArray: Array<CharSequence>,
|
||||||
videosUrlArray: Array<Uri>
|
videosUrlArray: Array<Uri>
|
||||||
) {
|
) {
|
||||||
val defRes = PreferenceHelper.getString(
|
|
||||||
requireContext(),
|
|
||||||
"default_res",
|
|
||||||
""
|
|
||||||
)!!
|
|
||||||
|
|
||||||
if (defRes != "") {
|
if (defRes != "") {
|
||||||
videosNameArray.forEachIndexed { index, pipedStream ->
|
videosNameArray.forEachIndexed { index, pipedStream ->
|
||||||
// search for quality preference in the available stream sources
|
// search for quality preference in the available stream sources
|
||||||
@ -1334,10 +1406,7 @@ class PlayerFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createExoPlayer(view: View) {
|
private fun createExoPlayer() {
|
||||||
val bufferingGoal =
|
|
||||||
PreferenceHelper.getString(requireContext(), "buffering_goal", "50")?.toInt()!! * 1000
|
|
||||||
|
|
||||||
val cronetEngine: CronetEngine = CronetHelper.getCronetEngine()
|
val cronetEngine: CronetEngine = CronetHelper.getCronetEngine()
|
||||||
val cronetDataSourceFactory: CronetDataSource.Factory =
|
val cronetDataSourceFactory: CronetDataSource.Factory =
|
||||||
CronetDataSource.Factory(cronetEngine, Executors.newCachedThreadPool())
|
CronetDataSource.Factory(cronetEngine, Executors.newCachedThreadPool())
|
||||||
@ -1367,7 +1436,7 @@ class PlayerFragment : Fragment() {
|
|||||||
|
|
||||||
trackSelector = DefaultTrackSelector(requireContext())
|
trackSelector = DefaultTrackSelector(requireContext())
|
||||||
|
|
||||||
exoPlayer = ExoPlayer.Builder(view.context)
|
exoPlayer = ExoPlayer.Builder(requireContext())
|
||||||
.setMediaSourceFactory(DefaultMediaSourceFactory(dataSourceFactory))
|
.setMediaSourceFactory(DefaultMediaSourceFactory(dataSourceFactory))
|
||||||
.setLoadControl(loadControl)
|
.setLoadControl(loadControl)
|
||||||
.setTrackSelector(trackSelector)
|
.setTrackSelector(trackSelector)
|
||||||
@ -1416,8 +1485,7 @@ class PlayerFragment : Fragment() {
|
|||||||
// hide the close image button
|
// hide the close image button
|
||||||
playerBinding.closeImageButton.visibility =
|
playerBinding.closeImageButton.visibility =
|
||||||
if (isLocked &&
|
if (isLocked &&
|
||||||
!Globals.isFullScreen &&
|
!(Globals.isFullScreen && !autoRotationEnabled)
|
||||||
autoRotationEnabled
|
|
||||||
) View.VISIBLE else View.GONE
|
) View.VISIBLE else View.GONE
|
||||||
|
|
||||||
// disable double tap to seek when the player is locked
|
// disable double tap to seek when the player is locked
|
||||||
@ -1429,7 +1497,6 @@ class PlayerFragment : Fragment() {
|
|||||||
fun run() {
|
fun run() {
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
val response = try {
|
val response = try {
|
||||||
val token = PreferenceHelper.getToken(requireContext())
|
|
||||||
RetrofitInstance.authApi.isSubscribed(
|
RetrofitInstance.authApi.isSubscribed(
|
||||||
channel_id,
|
channel_id,
|
||||||
token
|
token
|
||||||
@ -1469,7 +1536,6 @@ class PlayerFragment : Fragment() {
|
|||||||
fun run() {
|
fun run() {
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
try {
|
try {
|
||||||
val token = PreferenceHelper.getToken(requireContext())
|
|
||||||
RetrofitInstance.authApi.subscribe(
|
RetrofitInstance.authApi.subscribe(
|
||||||
token,
|
token,
|
||||||
Subscribe(channel_id)
|
Subscribe(channel_id)
|
||||||
@ -1492,7 +1558,6 @@ class PlayerFragment : Fragment() {
|
|||||||
fun run() {
|
fun run() {
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
try {
|
try {
|
||||||
val token = PreferenceHelper.getToken(requireContext())
|
|
||||||
RetrofitInstance.authApi.unsubscribe(
|
RetrofitInstance.authApi.unsubscribe(
|
||||||
token,
|
token,
|
||||||
Subscribe(channel_id)
|
Subscribe(channel_id)
|
||||||
@ -1569,10 +1634,22 @@ class PlayerFragment : Fragment() {
|
|||||||
// set portrait mode
|
// set portrait mode
|
||||||
unsetFullscreen()
|
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
|
Globals.isFullScreen = false
|
||||||
} else {
|
} else {
|
||||||
// enable exoPlayer controls again
|
// enable exoPlayer controls again
|
||||||
exoPlayerView.useController = true
|
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)
|
binding.playerScrollView.getHitRect(bounds)
|
||||||
|
|
||||||
if (SDK_INT >= Build.VERSION_CODES.O &&
|
if (SDK_INT >= Build.VERSION_CODES.O &&
|
||||||
exoPlayer.isPlaying && (binding.playerScrollView.getLocalVisibleRect(bounds) || Globals.isFullScreen)
|
(binding.playerScrollView.getLocalVisibleRect(bounds) || Globals.isFullScreen)
|
||||||
) {
|
) {
|
||||||
activity?.enterPictureInPictureMode(updatePipParams())
|
activity?.enterPictureInPictureMode(updatePipParams())
|
||||||
}
|
}
|
||||||
|
@ -32,15 +32,15 @@
|
|||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/close_imageButton"
|
android:id="@+id/close_imageButton"
|
||||||
style="@style/PlayerControlTop"
|
style="@style/PlayerControlTop"
|
||||||
|
android:layout_marginEnd="-10dp"
|
||||||
android:src="@drawable/ic_close"
|
android:src="@drawable/ic_close"
|
||||||
app:tint="@android:color/white" />
|
app:tint="@android:color/white" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/lock_player"
|
android:id="@+id/lock_player"
|
||||||
style="@style/PlayerControlTop"
|
style="@style/PlayerControlTop"
|
||||||
android:layout_marginStart="-5dp"
|
android:scaleX=".8"
|
||||||
android:scaleX=".9"
|
android:scaleY=".8"
|
||||||
android:scaleY=".9"
|
|
||||||
android:src="@drawable/ic_unlocked" />
|
android:src="@drawable/ic_unlocked" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@ -99,7 +99,7 @@
|
|||||||
android:id="@+id/captions"
|
android:id="@+id/captions"
|
||||||
style="@style/PlayerControlTop"
|
style="@style/PlayerControlTop"
|
||||||
android:src="@drawable/ic_caption_outlined"
|
android:src="@drawable/ic_caption_outlined"
|
||||||
app:tint="@android:color/darker_gray" />
|
app:tint="@android:color/white" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/repeat_toggle"
|
android:id="@+id/repeat_toggle"
|
||||||
@ -121,16 +121,14 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="bottom"
|
android:layout_gravity="bottom"
|
||||||
android:layout_marginTop="@dimen/exo_styled_bottom_bar_margin_top"
|
android:layout_marginTop="10dp"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingStart="@dimen/exo_styled_bottom_bar_time_padding"
|
android:paddingStart="10dp"
|
||||||
android:paddingLeft="@dimen/exo_styled_bottom_bar_time_padding"
|
android:paddingEnd="15dp" >
|
||||||
android:paddingEnd="@dimen/exo_styled_bottom_bar_time_padding"
|
|
||||||
android:paddingRight="@dimen/exo_styled_bottom_bar_time_padding">
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@id/exo_time"
|
android:id="@id/exo_time"
|
||||||
@ -187,7 +185,6 @@
|
|||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/fullscreen"
|
android:id="@+id/fullscreen"
|
||||||
style="@style/PlayerControlBottom"
|
style="@style/PlayerControlBottom"
|
||||||
android:layout_marginEnd="5dp"
|
|
||||||
android:src="@drawable/ic_fullscreen"
|
android:src="@drawable/ic_fullscreen"
|
||||||
app:tint="@android:color/white" />
|
app:tint="@android:color/white" />
|
||||||
|
|
||||||
@ -226,7 +223,7 @@
|
|||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:padding="@dimen/exo_styled_controls_padding">
|
android:padding="20dp">
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@id/exo_play_pause"
|
android:id="@id/exo_play_pause"
|
||||||
|
Loading…
Reference in New Issue
Block a user