From b795f4458a0a79e43f44dfbb2582be25677441a9 Mon Sep 17 00:00:00 2001 From: Lindong Date: Thu, 29 Jan 2026 01:25:09 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=A7=86=E9=A2=91=E6=92=AD?= =?UTF-8?q?=E6=94=BE=20=E4=BC=98=E5=8C=96Player=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../features/version/VersionActivity.kt | 2 +- .../home/fragment/HomeItemFragment.kt | 10 +- app/src/main/res/mipmap-xxhdpi/icon_play.png | Bin 0 -> 6965 bytes app/src/main/res/mipmap-xxhdpi/icon_play.webp | Bin 1456 -> 0 bytes .../player/options/IFramePlayerOptions.kt | 2 +- .../src/main/res/raw/ayp_youtube_player.html | 70 ++- .../customui/DefaultPlayerUiController.kt | 482 +++++++++--------- .../main/res/layout/ayp_default_player_ui.xml | 2 + 8 files changed, 323 insertions(+), 245 deletions(-) create mode 100644 app/src/main/res/mipmap-xxhdpi/icon_play.png delete mode 100644 app/src/main/res/mipmap-xxhdpi/icon_play.webp diff --git a/app/src/main/java/com/gamedog/vididin/features/version/VersionActivity.kt b/app/src/main/java/com/gamedog/vididin/features/version/VersionActivity.kt index e1a2061..2dc4658 100644 --- a/app/src/main/java/com/gamedog/vididin/features/version/VersionActivity.kt +++ b/app/src/main/java/com/gamedog/vididin/features/version/VersionActivity.kt @@ -39,7 +39,7 @@ class VersionActivity : AppViewsActivity(), OnT // For Testing - val shouldShowDebug = false//BuildConfig.DEBUG + val shouldShowDebug = true//BuildConfig.DEBUG llTesting.isVisible = shouldShowDebug if (shouldShowDebug) { butCash.setOnClickListener { diff --git a/app/src/main/java/com/gamedog/vididin/main/fragments/home/fragment/HomeItemFragment.kt b/app/src/main/java/com/gamedog/vididin/main/fragments/home/fragment/HomeItemFragment.kt index af24bc7..06c4586 100644 --- a/app/src/main/java/com/gamedog/vididin/main/fragments/home/fragment/HomeItemFragment.kt +++ b/app/src/main/java/com/gamedog/vididin/main/fragments/home/fragment/HomeItemFragment.kt @@ -14,7 +14,6 @@ import android.view.animation.Animation import android.view.animation.AnimationSet import android.view.animation.ScaleAnimation import android.widget.FrameLayout -import androidx.annotation.NonNull import androidx.core.view.isVisible import com.ama.core.architecture.appBase.AppViewsEmptyViewModelFragment import com.ama.core.architecture.util.AndroidUtil @@ -28,8 +27,6 @@ import com.gamedog.vididin.youtubestatistic.TickerTimer import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.AbstractYouTubePlayerListener -import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.YouTubePlayerCallback -import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.utils.loadOrCueVideo import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.options.IFramePlayerOptions import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView import com.viddin.videos.free.databinding.VididinappFeatureHomeItemLayoutBinding as ViewBinding @@ -192,7 +189,6 @@ class HomeItemFragment : AppViewsEmptyViewModelFragment() { mPlayer = youTubePlayer val playerUiController = MyPlayerControlView(mPlayerView!!) mPlayerView!!.setCustomPlayerUi(playerUiController.rootView) - if (mPendingPlay) { mPlayer?.loadVideo(mVideoData!!.id, mCurPlayedSecond) } else if (mIsPreloading) { @@ -392,7 +388,6 @@ class HomeItemFragment : AppViewsEmptyViewModelFragment() { private fun hidePlayIconAnim() { - return if (!binding?.playIcon!!.isVisible) { return } @@ -400,7 +395,7 @@ class HomeItemFragment : AppViewsEmptyViewModelFragment() { with (binding?.playIcon!!) { val animationSet = AnimationSet(true) - animationSet.duration = 250 + animationSet.duration = 100 val alphaAnimation = AlphaAnimation(0.6f, 0.3f) val scaleAnimation = ScaleAnimation( 1.0f, 0.5f, @@ -428,12 +423,11 @@ class HomeItemFragment : AppViewsEmptyViewModelFragment() { } private fun showPlayIconAnim() { - return with (binding?.playIcon!!) { visibility = View.VISIBLE val animationSet = AnimationSet(true) - animationSet.duration = 250 + animationSet.duration = 100 val alphaAnimation = AlphaAnimation(0.3f, 0.6f) val scaleAnimation = ScaleAnimation( 0.5f, 1.0f, diff --git a/app/src/main/res/mipmap-xxhdpi/icon_play.png b/app/src/main/res/mipmap-xxhdpi/icon_play.png new file mode 100644 index 0000000000000000000000000000000000000000..c94ae93852217fd57d78f9b057c9ceee8304d1a4 GIT binary patch literal 6965 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xxhdpi/icon_play.webp b/app/src/main/res/mipmap-xxhdpi/icon_play.webp deleted file mode 100644 index 803a4fa2065a4923d09f1d1dee3eaa0247e88eb1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1456 zcmWIYbaPw5%D@or>J$(bU=hK^z`$St#MWTs>FgYEf)U7NU_1dLS%6Zxc_l?b?oJ93 zkx>fl4;UDM5DXHNiwhtutRzs?w`&l!mvynKz%R&|l3JV$RPq6cRf>R?1KlJ7WQ(Lj z*cu>q5`=97VwaZ`lmOKPfY?PLLC!#S3XrXlj>JwvVkZ|AfzZ zZ((5Ab{-*y2$O=uqC~K9EI^VeEscTU({cs|-be-p;R_55T+v`TAc4be3P33tpu6&c zFr6WXA(cUa!IL46A(=rB$T9*(sv(0JFou10GBYsfTOZ&PV1K%xSH->P>^s(F$K?;! zDll%$RdE+uz3Tkl)AqOL*LU=)Xii!jXj*Wl{C{~x!}odt7FWYS9v=~IVPSn1$3nLc z{SR6eSSWEcwaPa=>Pk?Gut-XL(9@W-s6t7CLyb-EhDMWu{}u(27KIS5ViBoUr=>xh zy@zC+1eTq-xT3|f&)k^n^})K}naXDbxLO}~Yxe$C3hCp2$h)wpHnF8Nn zdwZL8Zu#-IH%|V$s`7pA=JS>I0vGGq@}xaimM!ElKXdUX6ELVCpy66ddFhYItwKqb zv%hTL@dg;^P_V#o?{ecgFI`DeCfkzf zyLNZ;oQtzJ6@9k~>gd?yaq8gB%+6IiOr*AMym-{Y`4XqCPkq)i+sk*>PrUg5bkdUE zhw+zq{`<+fyXD!n_Qh4;E_iRzuz_NK2>QCm>EtblQW3UMlalNT< zd)>bXAr9{OQik^)%Y;vf+VubB0j^3F9_h=c_dc4{Yr1Vtm7lq3-jW#>-!nyA181}u z&wt*byq5ig$j=9T&E@;gOb+Js;rB1(($|g_yQo+Cg00X8DR{#J2 diff --git a/youtube/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/options/IFramePlayerOptions.kt b/youtube/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/options/IFramePlayerOptions.kt index fa0ca5b..6a1b537 100644 --- a/youtube/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/options/IFramePlayerOptions.kt +++ b/youtube/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/options/IFramePlayerOptions.kt @@ -11,7 +11,7 @@ import org.json.JSONObject class IFramePlayerOptions private constructor(private val playerOptions: JSONObject) { companion object { - fun getDefault(context: Context) = Builder(context).controls(1).build() + fun getDefault(context: Context) = Builder(context).controls(0).build() } override fun toString(): String { diff --git a/youtube/core/src/main/res/raw/ayp_youtube_player.html b/youtube/core/src/main/res/raw/ayp_youtube_player.html index 33d518a..77b9c97 100644 --- a/youtube/core/src/main/res/raw/ayp_youtube_player.html +++ b/youtube/core/src/main/res/raw/ayp_youtube_player.html @@ -37,23 +37,89 @@ var player; var timerId; + function hideYouTubeUI() { + setInterval(() => { + const playerIFrame = document.querySelector("iframe"); + if (!playerIFrame) { + return; + } + const frameDoc = playerIFrame.contentDocument || playerIFrame.contentWindow.document; + if (!frameDoc) { + return; + } + + const selectorsToHide = [ + '.ytp-chrome-top', + '.ytp-chrome-bottom', + '.ytp-gradient-top', + '.ytp-gradient-bottom', + '.ytp-youtube-button', + '.ytp-watermark', + '.ytp-ce-element', + '.ytp-paid-content-overlay', + '.ytp-bezel-container', + '.ytp-spinner', + '.ytp-cards-teaser', + '.ytp-cards-button', + '.ytp-show-cards-title' + ]; + + selectorsToHide.forEach(selector => { + const elements = frameDoc.querySelectorAll(selector); + elements.forEach(el => { + if (el.style.display !== 'none') { + el.style.display = 'none'; + } + }); + }); + + // Special handling for pause overlays to avoid black screen issue + const pauseOverlays = ['.ytp-pause-overlay', '.ytp-pause-overlay-container']; + pauseOverlays.forEach(selector => { + const elements = frameDoc.querySelectorAll(selector); + elements.forEach(el => { + if (el.style.visibility !== 'hidden') { + el.style.visibility = 'hidden'; + el.style.pointerEvents = 'none'; + } + }); + }); + + if (player && typeof player.unloadModule === 'function') { + player.unloadModule('captions'); + } + + // Disable captions if any + const captions = frameDoc.querySelector('.ytp-caption-window-container'); + if (captions) { + captions.style.display = 'none'; + } + }, 50); + } function onYouTubeIframeAPIReady() { YouTubePlayerBridge.sendYouTubeIFrameAPIReady(); + var playerVars = <>; + // Force some player vars to hide UI elements at the API level + // but avoid overriding everything to stay compatible + playerVars.rel = 0; + playerVars.iv_load_policy = 3; + playerVars.modestbranding = 1; + var youtubePlayerConfig = { height: '100%', width: '100%', events: { - onReady: function(event) { YouTubePlayerBridge.sendReady() }, + onReady: function(event) { YouTubePlayerBridge.sendReady();hideYouTubeUI(); }, onStateChange: function(event) { sendPlayerStateChange(event.data) }, onPlaybackQualityChange: function(event) { YouTubePlayerBridge.sendPlaybackQualityChange(event.data) }, onPlaybackRateChange: function(event) { YouTubePlayerBridge.sendPlaybackRateChange(event.data) }, onError: function(error) { YouTubePlayerBridge.sendError(error.data) }, onApiChange: function(event) { YouTubePlayerBridge.sendApiChange() } }, - playerVars: <> + playerVars: playerVars }; if (<>) { diff --git a/youtube/custom-ui/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/customui/DefaultPlayerUiController.kt b/youtube/custom-ui/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/customui/DefaultPlayerUiController.kt index b6bac32..dcc1c76 100644 --- a/youtube/custom-ui/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/customui/DefaultPlayerUiController.kt +++ b/youtube/custom-ui/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/customui/DefaultPlayerUiController.kt @@ -21,269 +21,285 @@ import com.pierfrancescosoffritti.androidyoutubeplayer.core.customui.views.YouTu import com.pierfrancescosoffritti.androidyoutubeplayer.core.customui.views.YouTubePlayerSeekBarListener class DefaultPlayerUiController( - private val youTubePlayerView: YouTubePlayerView, - private val youTubePlayer: YouTubePlayer + private val youTubePlayerView: YouTubePlayerView, + private val youTubePlayer: YouTubePlayer ) : PlayerUiController { - val rootView: View = View.inflate(youTubePlayerView.context, R.layout.ayp_default_player_ui, null) + val rootView: View = + View.inflate(youTubePlayerView.context, R.layout.ayp_default_player_ui, null) - private var youTubePlayerMenu: YouTubePlayerMenu = DefaultYouTubePlayerMenu( - youTubePlayerView.context - ) + private var youTubePlayerMenu: YouTubePlayerMenu = DefaultYouTubePlayerMenu( + youTubePlayerView.context + ) - /** - * View used for for intercepting clicks and for drawing a black background. - * Could have used controlsContainer, but in this way I'm able to hide all the control at once by hiding controlsContainer - */ - private val panel: View = rootView.findViewById(R.id.panel) + /** + * View used for for intercepting clicks and for drawing a black background. + * Could have used controlsContainer, but in this way I'm able to hide all the control at once by hiding controlsContainer + */ + private val panel: View = rootView.findViewById(R.id.panel) - private val controlsContainer: View = rootView.findViewById(R.id.controls_container) - private val extraViewsContainer: LinearLayout = rootView.findViewById(R.id.extra_views_container) + private val controlsContainer: View = rootView.findViewById(R.id.controls_container) + private val extraViewsContainer: LinearLayout = + rootView.findViewById(R.id.extra_views_container) - private val videoTitle: TextView = rootView.findViewById(R.id.video_title) - private val liveVideoIndicator: TextView = rootView.findViewById(R.id.live_video_indicator) + private val videoTitle: TextView = rootView.findViewById(R.id.video_title) + private val liveVideoIndicator: TextView = rootView.findViewById(R.id.live_video_indicator) - private val progressBar: ProgressBar = rootView.findViewById(R.id.progress) - private val menuButton: ImageView = rootView.findViewById(R.id.menu_button) - private val playPauseButton: ImageView = rootView.findViewById(R.id.play_pause_button) - private val youTubeButton: ImageView = rootView.findViewById(R.id.youtube_button) - private val fullscreenButton: ImageView = rootView.findViewById(R.id.fullscreen_button) + private val progressBar: ProgressBar = rootView.findViewById(R.id.progress) + private val menuButton: ImageView = rootView.findViewById(R.id.menu_button) + private val playPauseButton: ImageView = rootView.findViewById(R.id.play_pause_button) + private val youTubeButton: ImageView = rootView.findViewById(R.id.youtube_button) + private val fullscreenButton: ImageView = rootView.findViewById(R.id.fullscreen_button) - private val customActionLeft: ImageView = rootView.findViewById(R.id.custom_action_left_button) - private val customActionRight: ImageView = rootView.findViewById(R.id.custom_action_right_button) + private val customActionLeft: ImageView = rootView.findViewById(R.id.custom_action_left_button) + private val customActionRight: ImageView = + rootView.findViewById(R.id.custom_action_right_button) - private val youtubePlayerSeekBar: YouTubePlayerSeekBar = rootView.findViewById(R.id.youtube_player_seekbar) - private val fadeControlsContainer: FadeViewHelper = FadeViewHelper(controlsContainer) + private val youtubePlayerSeekBar: YouTubePlayerSeekBar = + rootView.findViewById(R.id.youtube_player_seekbar) + private val fadeControlsContainer: FadeViewHelper = FadeViewHelper(controlsContainer) - private var onFullscreenButtonListener: View.OnClickListener - private var onMenuButtonClickListener: View.OnClickListener + private var onFullscreenButtonListener: View.OnClickListener + private var onMenuButtonClickListener: View.OnClickListener - private var isPlaying = false - private var isPlayPauseButtonEnabled = true - private var isCustomActionLeftEnabled = false - private var isCustomActionRightEnabled = false + private var isPlaying = false + private var isPlayPauseButtonEnabled = true + private var isCustomActionLeftEnabled = false + private var isCustomActionRightEnabled = false - private var isMatchParent = false + private var isMatchParent = false - private val youTubePlayerStateListener = object : AbstractYouTubePlayerListener() { - override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState) { - updateState(state) + private val youTubePlayerStateListener = object : AbstractYouTubePlayerListener() { + override fun onStateChange( + youTubePlayer: YouTubePlayer, + state: PlayerConstants.PlayerState + ) { + updateState(state) - if (state === PlayerConstants.PlayerState.PLAYING || state === PlayerConstants.PlayerState.PAUSED || state === PlayerConstants.PlayerState.VIDEO_CUED) { - panel.setBackgroundColor(ContextCompat.getColor(panel.context, android.R.color.transparent)) - progressBar.visibility = View.GONE + if (state === PlayerConstants.PlayerState.PLAYING || state === PlayerConstants.PlayerState.PAUSED || state === PlayerConstants.PlayerState.VIDEO_CUED) { + panel.setBackgroundColor( + ContextCompat.getColor( + panel.context, + android.R.color.transparent + ) + ) + progressBar.visibility = View.GONE - if (isPlayPauseButtonEnabled) playPauseButton.visibility = View.VISIBLE - if (isCustomActionLeftEnabled) customActionLeft.visibility = View.VISIBLE - if (isCustomActionRightEnabled) customActionRight.visibility = View.VISIBLE + if (isPlayPauseButtonEnabled) playPauseButton.visibility = View.VISIBLE + if (isCustomActionLeftEnabled) customActionLeft.visibility = View.VISIBLE + if (isCustomActionRightEnabled) customActionRight.visibility = View.VISIBLE - updatePlayPauseButtonIcon(state === PlayerConstants.PlayerState.PLAYING) + updatePlayPauseButtonIcon(state === PlayerConstants.PlayerState.PLAYING) - } else { - updatePlayPauseButtonIcon(false) + } else { + updatePlayPauseButtonIcon(false) - if (state === PlayerConstants.PlayerState.BUFFERING) { - progressBar.visibility = View.VISIBLE - panel.setBackgroundColor( - ContextCompat.getColor( - panel.context, - android.R.color.transparent - ) - ) - if (isPlayPauseButtonEnabled) playPauseButton.visibility = View.INVISIBLE + if (state === PlayerConstants.PlayerState.BUFFERING) { +// progressBar.visibility = View.VISIBLE + progressBar.visibility = View.GONE + panel.setBackgroundColor( + ContextCompat.getColor( + panel.context, + android.R.color.transparent + ) + ) + if (isPlayPauseButtonEnabled) playPauseButton.visibility = View.INVISIBLE - customActionLeft.visibility = View.GONE - customActionRight.visibility = View.GONE + customActionLeft.visibility = View.GONE + customActionRight.visibility = View.GONE + } + + if (state === PlayerConstants.PlayerState.UNSTARTED) { + progressBar.visibility = View.GONE + if (isPlayPauseButtonEnabled) playPauseButton.visibility = View.VISIBLE + } + } } - if (state === PlayerConstants.PlayerState.UNSTARTED) { - progressBar.visibility = View.GONE - if (isPlayPauseButtonEnabled) playPauseButton.visibility = View.VISIBLE + override fun onVideoId(youTubePlayer: YouTubePlayer, videoId: String) { + youTubeButton.setOnClickListener { + val intent = Intent( + Intent.ACTION_VIEW, + Uri.parse("https://www.youtube.com/watch?v=" + videoId + "#t=" + youtubePlayerSeekBar.seekBar.progress) + ) + try { + youTubeButton.context.startActivity(intent) + } catch (e: Exception) { + Log.e(javaClass.simpleName, e.message ?: "Can't open url to YouTube") + } + } } - } } - override fun onVideoId(youTubePlayer: YouTubePlayer, videoId: String) { - youTubeButton.setOnClickListener { - val intent = Intent( - Intent.ACTION_VIEW, - Uri.parse("https://www.youtube.com/watch?v=" + videoId + "#t=" + youtubePlayerSeekBar.seekBar.progress) - ) - try { - youTubeButton.context.startActivity(intent) - } catch (e: Exception) { - Log.e(javaClass.simpleName, e.message ?: "Can't open url to YouTube") + init { + onFullscreenButtonListener = View.OnClickListener { + isMatchParent = !isMatchParent + when (isMatchParent) { + true -> youTubePlayerView.matchParent() + false -> youTubePlayerView.wrapContent() + } } - } - } - } - init { - onFullscreenButtonListener = View.OnClickListener { - isMatchParent = !isMatchParent - when (isMatchParent) { - true -> youTubePlayerView.matchParent() - false -> youTubePlayerView.wrapContent() - } + onMenuButtonClickListener = View.OnClickListener { youTubePlayerMenu.show(menuButton) } + + initClickListeners() } - onMenuButtonClickListener = View.OnClickListener { youTubePlayerMenu.show(menuButton) } + private fun initClickListeners() { + fadeControlsContainer.isDisabled = true + youTubePlayer.addListener(youtubePlayerSeekBar) + youTubePlayer.addListener(fadeControlsContainer) + youTubePlayer.addListener(youTubePlayerStateListener) - initClickListeners() - } - - private fun initClickListeners() { - youTubePlayer.addListener(youtubePlayerSeekBar) - youTubePlayer.addListener(fadeControlsContainer) - youTubePlayer.addListener(youTubePlayerStateListener) - - youtubePlayerSeekBar.youtubePlayerSeekBarListener = object : YouTubePlayerSeekBarListener { - override fun seekTo(time: Float) = youTubePlayer.seekTo(time) - } - panel.setOnClickListener { fadeControlsContainer.toggleVisibility() } - playPauseButton.setOnClickListener { onPlayButtonPressed() } - fullscreenButton.setOnClickListener { onFullscreenButtonListener.onClick(fullscreenButton) } - menuButton.setOnClickListener { onMenuButtonClickListener.onClick(menuButton) } - } - - override fun showVideoTitle(show: Boolean): PlayerUiController { - videoTitle.visibility = if (show) View.VISIBLE else View.GONE - return this - } - - override fun setVideoTitle(videoTitle: String): PlayerUiController { - this.videoTitle.text = videoTitle - return this - } - - override fun showUi(show: Boolean): PlayerUiController { - fadeControlsContainer.isDisabled = !show - controlsContainer.visibility = if (show) View.VISIBLE else View.INVISIBLE - return this - } - - override fun showPlayPauseButton(show: Boolean): PlayerUiController { - playPauseButton.visibility = if (show) View.VISIBLE else View.GONE - - isPlayPauseButtonEnabled = show - return this - } - - override fun enableLiveVideoUi(enable: Boolean): PlayerUiController { - youtubePlayerSeekBar.visibility = if (enable) View.INVISIBLE else View.VISIBLE - liveVideoIndicator.visibility = if (enable) View.VISIBLE else View.GONE - return this - } - - override fun setCustomAction1( - icon: Drawable, - clickListener: View.OnClickListener? - ): PlayerUiController { - customActionLeft.setImageDrawable(icon) - customActionLeft.setOnClickListener(clickListener) - showCustomAction1(true) - return this - } - - override fun setCustomAction2( - icon: Drawable, - clickListener: View.OnClickListener? - ): PlayerUiController { - customActionRight.setImageDrawable(icon) - customActionRight.setOnClickListener(clickListener) - showCustomAction2(true) - return this - } - - override fun showCustomAction1(show: Boolean): PlayerUiController { - isCustomActionLeftEnabled = show - customActionLeft.visibility = if (show) View.VISIBLE else View.GONE - return this - } - - override fun showCustomAction2(show: Boolean): PlayerUiController { - isCustomActionRightEnabled = show - customActionRight.visibility = if (show) View.VISIBLE else View.GONE - return this - } - - override fun showMenuButton(show: Boolean): PlayerUiController { - menuButton.visibility = if (show) View.VISIBLE else View.GONE - return this - } - - override fun setMenuButtonClickListener(customMenuButtonClickListener: View.OnClickListener): PlayerUiController { - onMenuButtonClickListener = customMenuButtonClickListener - return this - } - - override fun showCurrentTime(show: Boolean): PlayerUiController { - youtubePlayerSeekBar.videoCurrentTimeTextView.visibility = if (show) View.VISIBLE else View.GONE - return this - } - - override fun showDuration(show: Boolean): PlayerUiController { - youtubePlayerSeekBar.videoDurationTextView.visibility = if (show) View.VISIBLE else View.GONE - return this - } - - override fun showSeekBar(show: Boolean): PlayerUiController { - youtubePlayerSeekBar.seekBar.visibility = if (show) View.VISIBLE else View.INVISIBLE - return this - } - - override fun showBufferingProgress(show: Boolean): PlayerUiController { - youtubePlayerSeekBar.showBufferingProgress = show - return this - } - - override fun showYouTubeButton(show: Boolean): PlayerUiController { - youTubeButton.visibility = if (show) View.VISIBLE else View.GONE - return this - } - - override fun addView(view: View): PlayerUiController { - extraViewsContainer.addView(view, 0) - return this - } - - override fun removeView(view: View): PlayerUiController { - extraViewsContainer.removeView(view) - return this - } - - override fun getMenu(): YouTubePlayerMenu = youTubePlayerMenu - - override fun showFullscreenButton(show: Boolean): PlayerUiController { - fullscreenButton.visibility = if (show) View.VISIBLE else View.GONE - return this - } - - override fun setFullscreenButtonClickListener(customFullscreenButtonClickListener: View.OnClickListener): PlayerUiController { - onFullscreenButtonListener = customFullscreenButtonClickListener - return this - } - - private fun onPlayButtonPressed() { - if (isPlaying) - youTubePlayer.pause() - else - youTubePlayer.play() - } - - private fun updateState(state: PlayerConstants.PlayerState) { - when (state) { - PlayerConstants.PlayerState.ENDED -> isPlaying = false - PlayerConstants.PlayerState.PAUSED -> isPlaying = false - PlayerConstants.PlayerState.PLAYING -> isPlaying = true - else -> {} + youtubePlayerSeekBar.youtubePlayerSeekBarListener = object : YouTubePlayerSeekBarListener { + override fun seekTo(time: Float) = youTubePlayer.seekTo(time) + } + panel.setOnClickListener { fadeControlsContainer.toggleVisibility() } + playPauseButton.setOnClickListener { onPlayButtonPressed() } + fullscreenButton.setOnClickListener { onFullscreenButtonListener.onClick(fullscreenButton) } + menuButton.setOnClickListener { onMenuButtonClickListener.onClick(menuButton) } } - updatePlayPauseButtonIcon(!isPlaying) - } + override fun showVideoTitle(show: Boolean): PlayerUiController { + videoTitle.visibility = if (show) View.VISIBLE else View.GONE + return this + } - private fun updatePlayPauseButtonIcon(playing: Boolean) { - val drawable = if (playing) R.drawable.ayp_ic_pause_36dp else R.drawable.ayp_ic_play_36dp - playPauseButton.setImageResource(drawable) - } + override fun setVideoTitle(videoTitle: String): PlayerUiController { + this.videoTitle.text = videoTitle + return this + } + + override fun showUi(show: Boolean): PlayerUiController { + fadeControlsContainer.isDisabled = !show + controlsContainer.visibility = if (show) View.VISIBLE else View.INVISIBLE + return this + } + + override fun showPlayPauseButton(show: Boolean): PlayerUiController { + playPauseButton.visibility = if (show) View.VISIBLE else View.GONE + + isPlayPauseButtonEnabled = show + return this + } + + override fun enableLiveVideoUi(enable: Boolean): PlayerUiController { + youtubePlayerSeekBar.visibility = if (enable) View.INVISIBLE else View.VISIBLE + liveVideoIndicator.visibility = if (enable) View.VISIBLE else View.GONE + return this + } + + override fun setCustomAction1( + icon: Drawable, + clickListener: View.OnClickListener? + ): PlayerUiController { + customActionLeft.setImageDrawable(icon) + customActionLeft.setOnClickListener(clickListener) + showCustomAction1(true) + return this + } + + override fun setCustomAction2( + icon: Drawable, + clickListener: View.OnClickListener? + ): PlayerUiController { + customActionRight.setImageDrawable(icon) + customActionRight.setOnClickListener(clickListener) + showCustomAction2(true) + return this + } + + override fun showCustomAction1(show: Boolean): PlayerUiController { + isCustomActionLeftEnabled = show + customActionLeft.visibility = if (show) View.VISIBLE else View.GONE + return this + } + + override fun showCustomAction2(show: Boolean): PlayerUiController { + isCustomActionRightEnabled = show + customActionRight.visibility = if (show) View.VISIBLE else View.GONE + return this + } + + override fun showMenuButton(show: Boolean): PlayerUiController { + menuButton.visibility = if (show) View.VISIBLE else View.GONE + return this + } + + override fun setMenuButtonClickListener(customMenuButtonClickListener: View.OnClickListener): PlayerUiController { + onMenuButtonClickListener = customMenuButtonClickListener + return this + } + + override fun showCurrentTime(show: Boolean): PlayerUiController { + youtubePlayerSeekBar.videoCurrentTimeTextView.visibility = + if (show) View.VISIBLE else View.GONE + return this + } + + override fun showDuration(show: Boolean): PlayerUiController { + youtubePlayerSeekBar.videoDurationTextView.visibility = + if (show) View.VISIBLE else View.GONE + return this + } + + override fun showSeekBar(show: Boolean): PlayerUiController { + youtubePlayerSeekBar.seekBar.visibility = if (show) View.VISIBLE else View.INVISIBLE + return this + } + + override fun showBufferingProgress(show: Boolean): PlayerUiController { + youtubePlayerSeekBar.showBufferingProgress = show + return this + } + + override fun showYouTubeButton(show: Boolean): PlayerUiController { + youTubeButton.visibility = if (show) View.VISIBLE else View.GONE + return this + } + + override fun addView(view: View): PlayerUiController { + extraViewsContainer.addView(view, 0) + return this + } + + override fun removeView(view: View): PlayerUiController { + extraViewsContainer.removeView(view) + return this + } + + override fun getMenu(): YouTubePlayerMenu = youTubePlayerMenu + + override fun showFullscreenButton(show: Boolean): PlayerUiController { + fullscreenButton.visibility = if (show) View.VISIBLE else View.GONE + return this + } + + override fun setFullscreenButtonClickListener(customFullscreenButtonClickListener: View.OnClickListener): PlayerUiController { + onFullscreenButtonListener = customFullscreenButtonClickListener + return this + } + + private fun onPlayButtonPressed() { + if (isPlaying) + youTubePlayer.pause() + else + youTubePlayer.play() + } + + private fun updateState(state: PlayerConstants.PlayerState) { + when (state) { + PlayerConstants.PlayerState.ENDED -> isPlaying = false + PlayerConstants.PlayerState.PAUSED -> isPlaying = false + PlayerConstants.PlayerState.PLAYING -> isPlaying = true + else -> {} + } + + updatePlayPauseButtonIcon(!isPlaying) + } + + private fun updatePlayPauseButtonIcon(playing: Boolean) { + val drawable = if (playing) R.drawable.ayp_ic_pause_36dp else R.drawable.ayp_ic_play_36dp + playPauseButton.setImageResource(drawable) + } } diff --git a/youtube/custom-ui/src/main/res/layout/ayp_default_player_ui.xml b/youtube/custom-ui/src/main/res/layout/ayp_default_player_ui.xml index 3d95d5e..0412d01 100644 --- a/youtube/custom-ui/src/main/res/layout/ayp_default_player_ui.xml +++ b/youtube/custom-ui/src/main/res/layout/ayp_default_player_ui.xml @@ -2,6 +2,7 @@