From a9b5a70292b00f7b2f61d79d2debea22462a0c85 Mon Sep 17 00:00:00 2001 From: Pierfrancesco Soffritti Date: Sun, 7 Aug 2022 09:29:42 +0100 Subject: [PATCH 01/16] Update readme (#875) Add Genius to the apps that are using the library --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5b755410..6720412c 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ A lengthier explanation to why you may want to consider using an alternative to A list of published apps that are using this library: ([let me know](https://github.com/PierfrancescoSoffritti/android-youtube-player/issues) if you want to add your app to this list) +- [Genius](https://play.google.com/store/apps/details?id=com.genius.android) - [reddit is fun](https://play.google.com/store/apps/details?id=com.andrewshu.android.reddit) - [Mobile Movie Database](https://play.google.com/store/apps/details?id=com.tmdb.themoviedatabase) - [dingo](https://play.google.com/store/apps/details?id=com.dingo) From fb43b1a12098a1f0d2a7e3ccccd1b5c6f1a021ec Mon Sep 17 00:00:00 2001 From: Praveen-Pable Date: Sun, 19 Feb 2023 14:20:25 +0530 Subject: [PATCH 02/16] Add fullScreen function in IFramePlayerOptions for set fs value --- .../core/player/options/IFramePlayerOptions.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/options/IFramePlayerOptions.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/options/IFramePlayerOptions.kt index 0bf7a905..e402ecd1 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/options/IFramePlayerOptions.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/options/IFramePlayerOptions.kt @@ -141,6 +141,16 @@ class IFramePlayerOptions private constructor(private val playerOptions: JSONObj return this } + /** + * Setting this parameter to 0 prevents the fullscreen button from displaying in the player. + * See original documentation for more info: https://developers.google.com/youtube/player_parameters#Parameters + * @param fs if set to 1: the player fullscreen button display. If set to 0: the player fullscreen button not display + */ + fun fullScreen(fs: Int): Builder { + addInt(FS, fs) + return this + } + private fun addString(key: String, value: String) { try { builderOptions.put(key, value) From f745898c99e80f3d75b7ace9ecf6061754f76dac Mon Sep 17 00:00:00 2001 From: Praveen-Pable Date: Sun, 19 Feb 2023 17:53:39 +0530 Subject: [PATCH 03/16] Add sample for simple fullscreen video functionality --- core-sample-app/src/main/AndroidManifest.xml | 5 ++ .../core/sampleapp/MainActivity.java | 2 + .../SimpleFullscreenExampleActivity.java | 66 +++++++++++++++++++ .../activity_simple_fullscreen_example.xml | 26 ++++++++ .../src/main/res/values/strings.xml | 1 + 5 files changed, 100 insertions(+) create mode 100644 core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/simpleFullscreenExample/SimpleFullscreenExampleActivity.java create mode 100644 core-sample-app/src/main/res/layout/activity_simple_fullscreen_example.xml diff --git a/core-sample-app/src/main/AndroidManifest.xml b/core-sample-app/src/main/AndroidManifest.xml index f2c078d4..b32662ed 100644 --- a/core-sample-app/src/main/AndroidManifest.xml +++ b/core-sample-app/src/main/AndroidManifest.xml @@ -86,6 +86,11 @@ android:configChanges="orientation|screenSize|keyboardHidden|smallestScreenSize|screenLayout" android:hardwareAccelerated="true" android:label="@string/simple_example" /> + { + if (youTubePlayerView.isFullScreen()) { + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + } else { + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + } + + }); + + getLifecycle().addObserver(youTubePlayerView); + } + + @Override + public void onConfigurationChanged(@NonNull Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + // Checks the orientation of the screen + if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { + youTubePlayerView.enterFullScreen(); + } + else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ + youTubePlayerView.exitFullScreen(); + } + } +} diff --git a/core-sample-app/src/main/res/layout/activity_simple_fullscreen_example.xml b/core-sample-app/src/main/res/layout/activity_simple_fullscreen_example.xml new file mode 100644 index 00000000..09302a9f --- /dev/null +++ b/core-sample-app/src/main/res/layout/activity_simple_fullscreen_example.xml @@ -0,0 +1,26 @@ + + + + + + + + \ No newline at end of file diff --git a/core-sample-app/src/main/res/values/strings.xml b/core-sample-app/src/main/res/values/strings.xml index 3ebc216b..14a75b9c 100644 --- a/core-sample-app/src/main/res/values/strings.xml +++ b/core-sample-app/src/main/res/values/strings.xml @@ -1,6 +1,7 @@ ayp API Simple example + Simple Fullscreen example Complete example RecyclerView example Custom UI example From 47c68aa21dc634883d30c15d9e561cbd11b30859 Mon Sep 17 00:00:00 2001 From: Praveen-Pable Date: Sun, 19 Feb 2023 19:13:43 +0530 Subject: [PATCH 04/16] add view in onStateChange function parameter declaration override onShowCustomView and onHideCustomView for webchromeclient --- .../notifications/NotificationManager.java | 3 ++- .../ui/SimpleChromeCastUiController.java | 2 +- .../customUiExample/CustomPlayerUiController.java | 2 +- .../playerStateExample/PlayerStateActivity.java | 3 ++- .../core/player/PlayerConstants.kt | 2 +- .../listeners/AbstractYouTubePlayerListener.kt | 3 ++- .../player/listeners/YouTubePlayerListener.kt | 3 ++- .../core/player/utils/PlaybackResumer.kt | 3 ++- .../core/player/utils/YouTubePlayerTracker.kt | 3 ++- .../core/player/views/LegacyYouTubePlayerView.kt | 2 +- .../core/player/views/WebViewYouTubePlayer.kt | 15 +++++++++++++++ .../core/ui/DefaultPlayerUiController.kt | 2 +- .../core/ui/utils/FadeViewHelper.kt | 2 +- .../core/ui/views/YouTubePlayerSeekBar.kt | 3 ++- 14 files changed, 35 insertions(+), 13 deletions(-) diff --git a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/chromecastExample/notifications/NotificationManager.java b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/chromecastExample/notifications/NotificationManager.java index 05631978..0b782cd1 100644 --- a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/chromecastExample/notifications/NotificationManager.java +++ b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/chromecastExample/notifications/NotificationManager.java @@ -7,6 +7,7 @@ import android.content.Intent; import android.os.Build; import android.util.Log; +import android.view.View; import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants; import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer; @@ -85,7 +86,7 @@ public void dismissNotification() { @SuppressLint("SwitchIntDef") @Override - public void onStateChange(@NonNull YouTubePlayer youTubePlayer, @NonNull PlayerConstants.PlayerState state) { + public void onStateChange(@NonNull YouTubePlayer youTubePlayer, @NonNull PlayerConstants.PlayerState state, @NonNull View view) { switch (state) { case PLAYING: notificationBuilder.mActions.get(0).icon = R.drawable.ic_pause_24dp; diff --git a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/chromecastExample/ui/SimpleChromeCastUiController.java b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/chromecastExample/ui/SimpleChromeCastUiController.java index e36272c2..675e642b 100644 --- a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/chromecastExample/ui/SimpleChromeCastUiController.java +++ b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/chromecastExample/ui/SimpleChromeCastUiController.java @@ -56,7 +56,7 @@ public void setYouTubePlayer(@Nullable YouTubePlayer youTubePlayer) { } @Override - public void onStateChange(@NonNull YouTubePlayer youTubePlayer, @NonNull PlayerConstants.PlayerState state) { + public void onStateChange(@NonNull YouTubePlayer youTubePlayer, @NonNull PlayerConstants.PlayerState state, @NonNull View view) { newSeekBarProgress = -1; updateControlsState(state); diff --git a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/customUiExample/CustomPlayerUiController.java b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/customUiExample/CustomPlayerUiController.java index 05d5e489..c1c17364 100644 --- a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/customUiExample/CustomPlayerUiController.java +++ b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/customUiExample/CustomPlayerUiController.java @@ -74,7 +74,7 @@ public void onReady(@NonNull YouTubePlayer youTubePlayer) { } @Override - public void onStateChange(@NonNull YouTubePlayer youTubePlayer, @NonNull PlayerConstants.PlayerState state) { + public void onStateChange(@NonNull YouTubePlayer youTubePlayer, @NonNull PlayerConstants.PlayerState state, @NonNull View view) { if(state == PlayerConstants.PlayerState.PLAYING || state == PlayerConstants.PlayerState.PAUSED || state == PlayerConstants.PlayerState.VIDEO_CUED) panel.setBackgroundColor(ContextCompat.getColor(context, android.R.color.transparent)); else diff --git a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/playerStateExample/PlayerStateActivity.java b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/playerStateExample/PlayerStateActivity.java index bf26a7e3..e9cf5c8d 100644 --- a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/playerStateExample/PlayerStateActivity.java +++ b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/playerStateExample/PlayerStateActivity.java @@ -5,6 +5,7 @@ import androidx.core.util.Pair; import androidx.appcompat.app.AppCompatActivity; +import android.view.View; import android.widget.Button; import android.widget.TextView; @@ -52,7 +53,7 @@ youTubePlayer, getLifecycle(), } @Override - public void onStateChange(@NonNull YouTubePlayer youTubePlayer, @NonNull PlayerConstants.PlayerState state) { + public void onStateChange(@NonNull YouTubePlayer youTubePlayer, @NonNull PlayerConstants.PlayerState state, @NonNull View view) { onNewState(state); } diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/PlayerConstants.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/PlayerConstants.kt index 69dafeb6..e7aece18 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/PlayerConstants.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/PlayerConstants.kt @@ -3,7 +3,7 @@ package com.pierfrancescosoffritti.androidyoutubeplayer.core.player class PlayerConstants { enum class PlayerState { - UNKNOWN, UNSTARTED, ENDED, PLAYING, PAUSED, BUFFERING, VIDEO_CUED + UNKNOWN, UNSTARTED, ENDED, PLAYING, PAUSED, BUFFERING, VIDEO_CUED, SHOW_CUSTOM_VIEW, HIDE_CUSTOM_VIEW } enum class PlaybackQuality { diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/AbstractYouTubePlayerListener.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/AbstractYouTubePlayerListener.kt index 6f6624db..5a17a02c 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/AbstractYouTubePlayerListener.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/AbstractYouTubePlayerListener.kt @@ -1,5 +1,6 @@ package com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners +import android.view.View import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer @@ -8,7 +9,7 @@ import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer */ abstract class AbstractYouTubePlayerListener : YouTubePlayerListener { override fun onReady(youTubePlayer: YouTubePlayer) {} - override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState) {} + override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState, view: View?) {} override fun onPlaybackQualityChange(youTubePlayer: YouTubePlayer, playbackQuality: PlayerConstants.PlaybackQuality) {} override fun onPlaybackRateChange(youTubePlayer: YouTubePlayer, playbackRate: PlayerConstants.PlaybackRate) {} override fun onError(youTubePlayer: YouTubePlayer, error: PlayerConstants.PlayerError) {} diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/YouTubePlayerListener.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/YouTubePlayerListener.kt index 1fdd7eb0..d4595776 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/YouTubePlayerListener.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/YouTubePlayerListener.kt @@ -1,5 +1,6 @@ package com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners +import android.view.View import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer @@ -14,7 +15,7 @@ interface YouTubePlayerListener { * Called every time the state of the player changes. Check [PlayerConstants.PlayerState] to see all the possible states. * @param state a state from [PlayerConstants.PlayerState] */ - fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState) + fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState, view: View? = null) /** * Called every time the quality of the playback changes. Check [PlayerConstants.PlaybackQuality] to see all the possible values. diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/utils/PlaybackResumer.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/utils/PlaybackResumer.kt index bc46a1dd..3737922f 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/utils/PlaybackResumer.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/utils/PlaybackResumer.kt @@ -1,5 +1,6 @@ package com.pierfrancescosoffritti.androidyoutubeplayer.core.player.utils +import android.view.View import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.AbstractYouTubePlayerListener @@ -28,7 +29,7 @@ internal class PlaybackResumer : AbstractYouTubePlayerListener() { error = null } - override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState) { + override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState, view: View?) { when (state) { PlayerConstants.PlayerState.ENDED -> { isPlaying = false diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/utils/YouTubePlayerTracker.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/utils/YouTubePlayerTracker.kt index 5ea0b240..7d4d9404 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/utils/YouTubePlayerTracker.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/utils/YouTubePlayerTracker.kt @@ -1,5 +1,6 @@ package com.pierfrancescosoffritti.androidyoutubeplayer.core.player.utils +import android.view.View import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.AbstractYouTubePlayerListener @@ -21,7 +22,7 @@ class YouTubePlayerTracker : AbstractYouTubePlayerListener() { var videoId: String? = null private set - override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState) { + override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState, view: View?) { this.state = state } diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/LegacyYouTubePlayerView.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/LegacyYouTubePlayerView.kt index a2f05729..69abdc53 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/LegacyYouTubePlayerView.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/LegacyYouTubePlayerView.kt @@ -50,7 +50,7 @@ internal class LegacyYouTubePlayerView(context: Context, attrs: AttributeSet? = // stop playing if the user loads a video but then leaves the app before the video starts playing. youTubePlayer.addListener(object : AbstractYouTubePlayerListener() { - override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState) { + override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState, view: View?) { if(state == PlayerConstants.PlayerState.PLAYING && !isEligibleForPlayback()) youTubePlayer.pause() } diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/WebViewYouTubePlayer.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/WebViewYouTubePlayer.kt index 205b9d25..70922d1c 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/WebViewYouTubePlayer.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/WebViewYouTubePlayer.kt @@ -114,6 +114,21 @@ internal class WebViewYouTubePlayer constructor(context: Context, attrs: Attribu // if the video's thumbnail is not in memory, show a black screen webChromeClient = object : WebChromeClient() { + + override fun onShowCustomView(view: View?, callback: CustomViewCallback?) { + super.onShowCustomView(view, callback) + youTubePlayerListeners.forEach { + it.onStateChange(this@WebViewYouTubePlayer, PlayerConstants.PlayerState.SHOW_CUSTOM_VIEW, view) + } + } + + override fun onHideCustomView() { + super.onHideCustomView() + youTubePlayerListeners.forEach { + it.onStateChange(this@WebViewYouTubePlayer, PlayerConstants.PlayerState.HIDE_CUSTOM_VIEW) + } + } + override fun getDefaultVideoPoster(): Bitmap? { val result = super.getDefaultVideoPoster() diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/DefaultPlayerUiController.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/DefaultPlayerUiController.kt index 1102b6ea..5074350d 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/DefaultPlayerUiController.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/DefaultPlayerUiController.kt @@ -60,7 +60,7 @@ class DefaultPlayerUiController(private val youTubePlayerView: YouTubePlayerView private var isCustomActionRightEnabled = false private val youTubePlayerStateListener = object : AbstractYouTubePlayerListener() { - override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState) { + override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState, view: View?) { updateState(state) if (state === PlayerConstants.PlayerState.PLAYING || state === PlayerConstants.PlayerState.PAUSED || state === PlayerConstants.PlayerState.VIDEO_CUED) { diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/utils/FadeViewHelper.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/utils/FadeViewHelper.kt index 943c6c28..fc1cf5dc 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/utils/FadeViewHelper.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/utils/FadeViewHelper.kt @@ -75,7 +75,7 @@ class FadeViewHelper(val targetView: View): YouTubePlayerListener { } } - override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState) { + override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState, view: View?) { updateState(state) when(state) { diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/views/YouTubePlayerSeekBar.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/views/YouTubePlayerSeekBar.kt index 12362607..02e4e884 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/views/YouTubePlayerSeekBar.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/views/YouTubePlayerSeekBar.kt @@ -4,6 +4,7 @@ import android.content.Context import android.util.AttributeSet import android.util.TypedValue import android.view.Gravity +import android.view.View import android.widget.LinearLayout import android.widget.SeekBar import android.widget.TextView @@ -114,7 +115,7 @@ class YouTubePlayerSeekBar(context: Context, attrs: AttributeSet? = null): Linea // YouTubePlayerListener - override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState) { + override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState, view: View?) { newSeekBarProgress = -1 updateState(state) } From f9df9cfe91dffd7b68def632b27f44b7052aacef Mon Sep 17 00:00:00 2001 From: Praveen-Pable Date: Sun, 19 Feb 2023 19:19:00 +0530 Subject: [PATCH 05/16] sample full screen example using state change handle --- .../SimpleFullscreenExampleActivity.java | 45 ++++++++++++++----- .../activity_simple_fullscreen_example.xml | 18 ++++---- 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/simpleFullscreenExample/SimpleFullscreenExampleActivity.java b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/simpleFullscreenExample/SimpleFullscreenExampleActivity.java index dd316a0b..80ca09d9 100644 --- a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/simpleFullscreenExample/SimpleFullscreenExampleActivity.java +++ b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/simpleFullscreenExample/SimpleFullscreenExampleActivity.java @@ -4,9 +4,10 @@ import android.content.res.Configuration; import android.os.Bundle; import android.view.View; +import android.widget.FrameLayout; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; - +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.options.IFramePlayerOptions; @@ -16,6 +17,7 @@ public class SimpleFullscreenExampleActivity extends AppCompatActivity { private YouTubePlayerView youTubePlayerView; + private FrameLayout customView; @Override protected void onCreate(Bundle savedInstanceState) { @@ -28,9 +30,40 @@ protected void onCreate(Bundle savedInstanceState) { .build(); youTubePlayerView = findViewById(R.id.youtube_player_view); + customView = findViewById(R.id.customView); youTubePlayerView.setEnableAutomaticInitialization(false); youTubePlayerView.initialize(new AbstractYouTubePlayerListener() { + @Override + public void onStateChange(@NonNull YouTubePlayer youTubePlayer, @NonNull PlayerConstants.PlayerState state, @NonNull View view) { + switch (state) { + case SHOW_CUSTOM_VIEW: { + // for display full screen landscape view + youTubePlayerView.setVisibility(View.GONE); + customView.setVisibility(View.VISIBLE); + customView.addView(view); + if (!youTubePlayerView.isFullScreen()) { + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + } + break; + } + + case HIDE_CUSTOM_VIEW: { + // for display normal portrait view + youTubePlayerView.setVisibility(View.VISIBLE); + customView.setVisibility(View.GONE); + if (youTubePlayerView.isFullScreen()) { + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + } + break; + } + + default: { + break; + } + } + } + @Override public void onReady(@NonNull YouTubePlayer youTubePlayer) { super.onReady(youTubePlayer); @@ -38,16 +71,6 @@ public void onReady(@NonNull YouTubePlayer youTubePlayer) { } }, iFramePlayerOptions); - View viewButtonFullScreen = findViewById(R.id.view_button_fullscreen); - viewButtonFullScreen.setOnClickListener(view -> { - if (youTubePlayerView.isFullScreen()) { - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); - } else { - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); - } - - }); - getLifecycle().addObserver(youTubePlayerView); } diff --git a/core-sample-app/src/main/res/layout/activity_simple_fullscreen_example.xml b/core-sample-app/src/main/res/layout/activity_simple_fullscreen_example.xml index 09302a9f..28404310 100644 --- a/core-sample-app/src/main/res/layout/activity_simple_fullscreen_example.xml +++ b/core-sample-app/src/main/res/layout/activity_simple_fullscreen_example.xml @@ -13,14 +13,14 @@ app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" /> - + \ No newline at end of file From 15e002d5b5c8072980bd567179d1d19eb5fb90d5 Mon Sep 17 00:00:00 2001 From: Praveen-Pable Date: Wed, 8 Mar 2023 14:11:08 +0530 Subject: [PATCH 06/16] Changes are made as per suggestion 1. Revert code for onStateChange method defination, remove view from parameter 2. Remove SHOW_CUSTOM_VIEW and HIDE_CUSTOM_VIEW from PlayerState 3. Create seperate method for handle callback of onShowCustomView and onHideCustomView Also update SimpleFullscreenExampleActivity code accordingly --- .../notifications/NotificationManager.java | 3 +- .../ui/SimpleChromeCastUiController.java | 2 +- .../CustomPlayerUiController.java | 2 +- .../PlayerStateActivity.java | 3 +- .../SimpleFullscreenExampleActivity.java | 45 ++++++++----------- .../core/player/PlayerConstants.kt | 2 +- .../AbstractYouTubePlayerListener.kt | 5 ++- .../player/listeners/YouTubePlayerListener.kt | 15 ++++++- .../core/player/utils/PlaybackResumer.kt | 3 +- .../core/player/utils/YouTubePlayerTracker.kt | 3 +- .../player/views/LegacyYouTubePlayerView.kt | 2 +- .../core/player/views/WebViewYouTubePlayer.kt | 4 +- .../core/ui/DefaultPlayerUiController.kt | 2 +- .../core/ui/utils/FadeViewHelper.kt | 5 ++- .../core/ui/views/YouTubePlayerSeekBar.kt | 5 ++- 15 files changed, 56 insertions(+), 45 deletions(-) diff --git a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/chromecastExample/notifications/NotificationManager.java b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/chromecastExample/notifications/NotificationManager.java index 0b782cd1..05631978 100644 --- a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/chromecastExample/notifications/NotificationManager.java +++ b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/chromecastExample/notifications/NotificationManager.java @@ -7,7 +7,6 @@ import android.content.Intent; import android.os.Build; import android.util.Log; -import android.view.View; import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants; import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer; @@ -86,7 +85,7 @@ public void dismissNotification() { @SuppressLint("SwitchIntDef") @Override - public void onStateChange(@NonNull YouTubePlayer youTubePlayer, @NonNull PlayerConstants.PlayerState state, @NonNull View view) { + public void onStateChange(@NonNull YouTubePlayer youTubePlayer, @NonNull PlayerConstants.PlayerState state) { switch (state) { case PLAYING: notificationBuilder.mActions.get(0).icon = R.drawable.ic_pause_24dp; diff --git a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/chromecastExample/ui/SimpleChromeCastUiController.java b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/chromecastExample/ui/SimpleChromeCastUiController.java index 675e642b..e36272c2 100644 --- a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/chromecastExample/ui/SimpleChromeCastUiController.java +++ b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/chromecastExample/ui/SimpleChromeCastUiController.java @@ -56,7 +56,7 @@ public void setYouTubePlayer(@Nullable YouTubePlayer youTubePlayer) { } @Override - public void onStateChange(@NonNull YouTubePlayer youTubePlayer, @NonNull PlayerConstants.PlayerState state, @NonNull View view) { + public void onStateChange(@NonNull YouTubePlayer youTubePlayer, @NonNull PlayerConstants.PlayerState state) { newSeekBarProgress = -1; updateControlsState(state); diff --git a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/customUiExample/CustomPlayerUiController.java b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/customUiExample/CustomPlayerUiController.java index c1c17364..05d5e489 100644 --- a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/customUiExample/CustomPlayerUiController.java +++ b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/customUiExample/CustomPlayerUiController.java @@ -74,7 +74,7 @@ public void onReady(@NonNull YouTubePlayer youTubePlayer) { } @Override - public void onStateChange(@NonNull YouTubePlayer youTubePlayer, @NonNull PlayerConstants.PlayerState state, @NonNull View view) { + public void onStateChange(@NonNull YouTubePlayer youTubePlayer, @NonNull PlayerConstants.PlayerState state) { if(state == PlayerConstants.PlayerState.PLAYING || state == PlayerConstants.PlayerState.PAUSED || state == PlayerConstants.PlayerState.VIDEO_CUED) panel.setBackgroundColor(ContextCompat.getColor(context, android.R.color.transparent)); else diff --git a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/playerStateExample/PlayerStateActivity.java b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/playerStateExample/PlayerStateActivity.java index e9cf5c8d..bf26a7e3 100644 --- a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/playerStateExample/PlayerStateActivity.java +++ b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/playerStateExample/PlayerStateActivity.java @@ -5,7 +5,6 @@ import androidx.core.util.Pair; import androidx.appcompat.app.AppCompatActivity; -import android.view.View; import android.widget.Button; import android.widget.TextView; @@ -53,7 +52,7 @@ youTubePlayer, getLifecycle(), } @Override - public void onStateChange(@NonNull YouTubePlayer youTubePlayer, @NonNull PlayerConstants.PlayerState state, @NonNull View view) { + public void onStateChange(@NonNull YouTubePlayer youTubePlayer, @NonNull PlayerConstants.PlayerState state) { onNewState(state); } diff --git a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/simpleFullscreenExample/SimpleFullscreenExampleActivity.java b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/simpleFullscreenExample/SimpleFullscreenExampleActivity.java index 80ca09d9..cfed533f 100644 --- a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/simpleFullscreenExample/SimpleFullscreenExampleActivity.java +++ b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/simpleFullscreenExample/SimpleFullscreenExampleActivity.java @@ -4,15 +4,16 @@ import android.content.res.Configuration; import android.os.Bundle; import android.view.View; +import android.webkit.WebChromeClient; import android.widget.FrameLayout; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; -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.options.IFramePlayerOptions; import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView; import com.pierfrancescosoffritti.aytplayersample.R; +import org.jetbrains.annotations.Nullable; public class SimpleFullscreenExampleActivity extends AppCompatActivity { @@ -35,32 +36,24 @@ protected void onCreate(Bundle savedInstanceState) { youTubePlayerView.setEnableAutomaticInitialization(false); youTubePlayerView.initialize(new AbstractYouTubePlayerListener() { @Override - public void onStateChange(@NonNull YouTubePlayer youTubePlayer, @NonNull PlayerConstants.PlayerState state, @NonNull View view) { - switch (state) { - case SHOW_CUSTOM_VIEW: { - // for display full screen landscape view - youTubePlayerView.setVisibility(View.GONE); - customView.setVisibility(View.VISIBLE); - customView.addView(view); - if (!youTubePlayerView.isFullScreen()) { - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); - } - break; - } - - case HIDE_CUSTOM_VIEW: { - // for display normal portrait view - youTubePlayerView.setVisibility(View.VISIBLE); - customView.setVisibility(View.GONE); - if (youTubePlayerView.isFullScreen()) { - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); - } - break; - } + public void onShowCustomView(@Nullable View view, @Nullable WebChromeClient.CustomViewCallback callback) { + super.onShowCustomView(view, callback); + // for display full screen landscape view + youTubePlayerView.setVisibility(View.GONE); + customView.setVisibility(View.VISIBLE); + customView.addView(view); + if (!youTubePlayerView.isFullScreen()) { + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + } + } - default: { - break; - } + @Override + public void onHideCustomView() { + super.onHideCustomView(); + youTubePlayerView.setVisibility(View.VISIBLE); + customView.setVisibility(View.GONE); + if (youTubePlayerView.isFullScreen()) { + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } } diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/PlayerConstants.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/PlayerConstants.kt index e7aece18..69dafeb6 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/PlayerConstants.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/PlayerConstants.kt @@ -3,7 +3,7 @@ package com.pierfrancescosoffritti.androidyoutubeplayer.core.player class PlayerConstants { enum class PlayerState { - UNKNOWN, UNSTARTED, ENDED, PLAYING, PAUSED, BUFFERING, VIDEO_CUED, SHOW_CUSTOM_VIEW, HIDE_CUSTOM_VIEW + UNKNOWN, UNSTARTED, ENDED, PLAYING, PAUSED, BUFFERING, VIDEO_CUED } enum class PlaybackQuality { diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/AbstractYouTubePlayerListener.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/AbstractYouTubePlayerListener.kt index 5a17a02c..7841e010 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/AbstractYouTubePlayerListener.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/AbstractYouTubePlayerListener.kt @@ -1,6 +1,7 @@ package com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners import android.view.View +import android.webkit.WebChromeClient import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer @@ -9,7 +10,7 @@ import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer */ abstract class AbstractYouTubePlayerListener : YouTubePlayerListener { override fun onReady(youTubePlayer: YouTubePlayer) {} - override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState, view: View?) {} + override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState) {} override fun onPlaybackQualityChange(youTubePlayer: YouTubePlayer, playbackQuality: PlayerConstants.PlaybackQuality) {} override fun onPlaybackRateChange(youTubePlayer: YouTubePlayer, playbackRate: PlayerConstants.PlaybackRate) {} override fun onError(youTubePlayer: YouTubePlayer, error: PlayerConstants.PlayerError) {} @@ -18,4 +19,6 @@ abstract class AbstractYouTubePlayerListener : YouTubePlayerListener { override fun onVideoDuration(youTubePlayer: YouTubePlayer, duration: Float) {} override fun onVideoLoadedFraction(youTubePlayer: YouTubePlayer, loadedFraction: Float) {} override fun onVideoId(youTubePlayer: YouTubePlayer, videoId: String) {} + override fun onShowCustomView(view: View?, callback: WebChromeClient.CustomViewCallback?) {} + override fun onHideCustomView() {} } diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/YouTubePlayerListener.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/YouTubePlayerListener.kt index d4595776..ff6e7ea4 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/YouTubePlayerListener.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/YouTubePlayerListener.kt @@ -1,6 +1,7 @@ package com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners import android.view.View +import android.webkit.WebChromeClient import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer @@ -15,7 +16,7 @@ interface YouTubePlayerListener { * Called every time the state of the player changes. Check [PlayerConstants.PlayerState] to see all the possible states. * @param state a state from [PlayerConstants.PlayerState] */ - fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState, view: View? = null) + fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState) /** * Called every time the quality of the playback changes. Check [PlayerConstants.PlaybackQuality] to see all the possible values. @@ -61,4 +62,16 @@ interface YouTubePlayerListener { fun onVideoId(youTubePlayer: YouTubePlayer, videoId: String) fun onApiChange(youTubePlayer: YouTubePlayer) + + /** + * Called when current page has entered full screen mode. + * @param view is the View object to be shown. + * @param callback invoke this callback to request the page to exit full screen mode. + */ + fun onShowCustomView(view: View?, callback: WebChromeClient.CustomViewCallback?) + + /** + * Called when current page has exited full screen mode. + */ + fun onHideCustomView() } diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/utils/PlaybackResumer.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/utils/PlaybackResumer.kt index 3737922f..bc46a1dd 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/utils/PlaybackResumer.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/utils/PlaybackResumer.kt @@ -1,6 +1,5 @@ package com.pierfrancescosoffritti.androidyoutubeplayer.core.player.utils -import android.view.View import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.AbstractYouTubePlayerListener @@ -29,7 +28,7 @@ internal class PlaybackResumer : AbstractYouTubePlayerListener() { error = null } - override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState, view: View?) { + override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState) { when (state) { PlayerConstants.PlayerState.ENDED -> { isPlaying = false diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/utils/YouTubePlayerTracker.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/utils/YouTubePlayerTracker.kt index 7d4d9404..5ea0b240 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/utils/YouTubePlayerTracker.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/utils/YouTubePlayerTracker.kt @@ -1,6 +1,5 @@ package com.pierfrancescosoffritti.androidyoutubeplayer.core.player.utils -import android.view.View import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.AbstractYouTubePlayerListener @@ -22,7 +21,7 @@ class YouTubePlayerTracker : AbstractYouTubePlayerListener() { var videoId: String? = null private set - override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState, view: View?) { + override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState) { this.state = state } diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/LegacyYouTubePlayerView.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/LegacyYouTubePlayerView.kt index 69abdc53..a2f05729 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/LegacyYouTubePlayerView.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/LegacyYouTubePlayerView.kt @@ -50,7 +50,7 @@ internal class LegacyYouTubePlayerView(context: Context, attrs: AttributeSet? = // stop playing if the user loads a video but then leaves the app before the video starts playing. youTubePlayer.addListener(object : AbstractYouTubePlayerListener() { - override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState, view: View?) { + override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState) { if(state == PlayerConstants.PlayerState.PLAYING && !isEligibleForPlayback()) youTubePlayer.pause() } diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/WebViewYouTubePlayer.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/WebViewYouTubePlayer.kt index 70922d1c..b00b13e0 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/WebViewYouTubePlayer.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/WebViewYouTubePlayer.kt @@ -118,14 +118,14 @@ internal class WebViewYouTubePlayer constructor(context: Context, attrs: Attribu override fun onShowCustomView(view: View?, callback: CustomViewCallback?) { super.onShowCustomView(view, callback) youTubePlayerListeners.forEach { - it.onStateChange(this@WebViewYouTubePlayer, PlayerConstants.PlayerState.SHOW_CUSTOM_VIEW, view) + it.onShowCustomView(view = view, callback = callback) } } override fun onHideCustomView() { super.onHideCustomView() youTubePlayerListeners.forEach { - it.onStateChange(this@WebViewYouTubePlayer, PlayerConstants.PlayerState.HIDE_CUSTOM_VIEW) + it.onHideCustomView() } } diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/DefaultPlayerUiController.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/DefaultPlayerUiController.kt index 5074350d..1102b6ea 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/DefaultPlayerUiController.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/DefaultPlayerUiController.kt @@ -60,7 +60,7 @@ class DefaultPlayerUiController(private val youTubePlayerView: YouTubePlayerView private var isCustomActionRightEnabled = false private val youTubePlayerStateListener = object : AbstractYouTubePlayerListener() { - override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState, view: View?) { + override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState) { updateState(state) if (state === PlayerConstants.PlayerState.PLAYING || state === PlayerConstants.PlayerState.PAUSED || state === PlayerConstants.PlayerState.VIDEO_CUED) { diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/utils/FadeViewHelper.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/utils/FadeViewHelper.kt index fc1cf5dc..c1966a09 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/utils/FadeViewHelper.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/utils/FadeViewHelper.kt @@ -2,6 +2,7 @@ package com.pierfrancescosoffritti.androidyoutubeplayer.core.ui.utils import android.animation.Animator import android.view.View +import android.webkit.WebChromeClient import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.YouTubePlayerListener @@ -75,7 +76,7 @@ class FadeViewHelper(val targetView: View): YouTubePlayerListener { } } - override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState, view: View?) { + override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState) { updateState(state) when(state) { @@ -104,4 +105,6 @@ class FadeViewHelper(val targetView: View): YouTubePlayerListener { override fun onVideoDuration(youTubePlayer: YouTubePlayer, duration: Float) { } override fun onVideoLoadedFraction(youTubePlayer: YouTubePlayer, loadedFraction: Float) { } override fun onVideoId(youTubePlayer: YouTubePlayer, videoId: String) { } + override fun onShowCustomView(view: View?, callback: WebChromeClient.CustomViewCallback?) { } + override fun onHideCustomView() { } } \ No newline at end of file diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/views/YouTubePlayerSeekBar.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/views/YouTubePlayerSeekBar.kt index 02e4e884..4bf8c679 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/views/YouTubePlayerSeekBar.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/views/YouTubePlayerSeekBar.kt @@ -5,6 +5,7 @@ import android.util.AttributeSet import android.util.TypedValue import android.view.Gravity import android.view.View +import android.webkit.WebChromeClient import android.widget.LinearLayout import android.widget.SeekBar import android.widget.TextView @@ -115,7 +116,7 @@ class YouTubePlayerSeekBar(context: Context, attrs: AttributeSet? = null): Linea // YouTubePlayerListener - override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState, view: View?) { + override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState) { newSeekBarProgress = -1 updateState(state) } @@ -151,6 +152,8 @@ class YouTubePlayerSeekBar(context: Context, attrs: AttributeSet? = null): Linea override fun onPlaybackQualityChange(youTubePlayer: YouTubePlayer, playbackQuality: PlayerConstants.PlaybackQuality) { } override fun onPlaybackRateChange(youTubePlayer: YouTubePlayer, playbackRate: PlayerConstants.PlaybackRate) { } override fun onError(youTubePlayer: YouTubePlayer, error: PlayerConstants.PlayerError) { } + override fun onShowCustomView(view: View?, callback: WebChromeClient.CustomViewCallback?) { } + override fun onHideCustomView() { } } interface YouTubePlayerSeekBarListener { From bda3b480e14c10ddf1422ffa6fb07c73bf66dfc7 Mon Sep 17 00:00:00 2001 From: Sebastian Adam Date: Sat, 5 Nov 2022 12:08:13 +0100 Subject: [PATCH 07/16] Start Video without Audio Focus (#896) * Update readme (#875) Add Genius to the apps that are using the library * added mute option * added mute option * changed wording of new method descriptions * removed link in README.md Co-authored-by: Pierfrancesco Soffritti --- .idea/gradle.xml | 1 - .../player/options/IFramePlayerOptions.kt | 20 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 5b34ba33..6e9c9bf7 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -17,7 +17,6 @@ - diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/options/IFramePlayerOptions.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/options/IFramePlayerOptions.kt index e402ecd1..6c9dcc57 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/options/IFramePlayerOptions.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/options/IFramePlayerOptions.kt @@ -24,6 +24,7 @@ class IFramePlayerOptions private constructor(private val playerOptions: JSONObj class Builder { companion object { private const val AUTO_PLAY = "autoplay" + private const val MUTE = "mute" private const val CONTROLS = "controls" private const val ENABLE_JS_API = "enablejsapi" private const val FS = "fs" @@ -42,6 +43,7 @@ class IFramePlayerOptions private constructor(private val playerOptions: JSONObj init { addInt(AUTO_PLAY, 0) + addInt(MUTE, 0) addInt(CONTROLS, 0) addInt(ENABLE_JS_API, 1) addInt(FS, 0) @@ -66,6 +68,24 @@ class IFramePlayerOptions private constructor(private val playerOptions: JSONObj return this } + /** + * Controls if the video is played automatically after the player is initialized. + * @param autoplay if set to 1: the player will start automatically. If set to 0: the player will not start automatically + */ + fun autoplay(controls: Int): Builder { + addInt(AUTO_PLAY, controls) + return this + } + + /** + * Controls if the player will be initialized mute or not. + * @param mute if set to 1: the player will start muted and without acquiring Audio Focus. If set to 0: the player will acquire Audio Focus + */ + fun mute(controls: Int): Builder { + addInt(MUTE, controls) + return this + } + /** * Controls the related videos shown at the end of a video. * @param rel If set to 0: related videos will come from the same channel as the video that was just played. If set to 1: related videos will come from multiple channels. From a64f078c00a3e2e592a5ed58536f6e332da156d3 Mon Sep 17 00:00:00 2001 From: Serkali-sudo <59535990+Serkali-sudo@users.noreply.github.com> Date: Sun, 6 Nov 2022 11:08:34 +0300 Subject: [PATCH 08/16] Add Workarounds To Readme.md (#891) Add FAQ section to README with workarounds --- README.md | 330 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 329 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6720412c..5c1be165 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,15 @@ Also remember when publishing your app on the PlayStore to write title and descr 3. [Receiver](#receiver) 4. [Registration](#registration) 5. [Hosting the Chromecast receiver](#hosting-the-chromecast-receiver) - + +# FAQ +1. [Workarounds](#workarounds) + 1. [Change video quality](#change-video-quality) + 2. [Login to YouTube account](#login-to-youtube-account) + 3. [Block Ads (Auto Ad Skip)](#block-ads) + 4. [Remove views that cannot be removed by the controls parameter](#remove-annoying-views) + 5. [Force to hide subtitles](#hide-captions) + 6. [Play Next Recomended Video](#play-next-recomended-video) # Sample app :memo: Both the **core module** and the **chromecast module** have a sample app, to provide examples of usage of the libraries. @@ -942,6 +950,326 @@ In order to use your receiver you need a receiverId. This is the ID of your rece ### Hosting the chromecast-receiver You will be required to host your receiver somewhere, host it where you prefer. Firebase free hosting may be a good option, for development. +# Workarounds +The following sections provides unofficial workarounds that can't be implemented in the library because they might break at anytime. To use them you will need to create your own fork of the library. Use them at your own peril. Using any of these workarounds might break YouTube terms of service. + +These workaround have been provided by the community of users of this library. Thanks to @Serkali-sudo for the help! + +## Change Video Quality +The IFrame Player API currently doesn't support changing the video quality on modile devices, but we can do it indirectly. + +The IFrame player keeps the quality value in a window interface called [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage). We can access it and change it from there. + +In order to access the player's `localStorage`, you need to turn on the `domStorageEnabled` setting in the webview. + +Go to `WebViewYouTubePlayer#initWebView` and add this line to enable `domStorage`: + +```kt + settings.domStorageEnabled = true +``` + +Add these functions to `ayp_youtube_player.html`: + + +```js +// Return the available quality options for the current video. +// Not all videos have the same quality options, so we need to check what's available first. +// this function will return an array like: ["hd1080","hd720","large","medium","small","tiny","auto"] +function sendVideoQuality(player) { + YouTubePlayerBridge.sendVideoQuality(JSON.stringify(player.getAvailableQualityLevels())) +} + +function setPlaybackQuality(playbackQuality) { + if (playbackQuality == "auto") { + localStorage.removeItem("yt-player-quality"); + } else { + var now = Date.now(); + // this will set `playbackQuality` as the selected video quality, untile it expires + localStorage.setItem("yt-player-quality", JSON.stringify({ + data: playbackQuality, + creation: now, + expiration: now + 2419200000 + })); + } + + // after changing the quality you need to reload the video to see changes. + // reload the video and start playing where it was. + if (player) { + var currentTime = player.getCurrentTime(); + player.loadVideoById(player.getVideoData().video_id, currentTime); + } +} +``` + +To receive events from the webview, add this to `YouTubePlayerBridge.kt`: + +```kt +@JavascriptInterface +fun sendVideoQuality(quality: String) { + mainThreadHandler.post { + for(listener in youTubePlayerOwner.getListeners()) { + // also add this new method to the listener interface + listener.onVideoQuality(youTubePlayerOwner.getInstance(), quality) + } + } +} +``` + +Add this to the `YoutubePlayer` interface: + +```kt +fun setPlaybackQuality(quality: String) +``` + +And implement it in `WebViewYouTubePlayer.kt` + +```kt +override fun setPlaybackQuality(quality: String) { + mainThreadHandler.post { loadUrl("javascript:setPlaybackQuality('$quality')") } +} +``` + +Now you should be able to change the quality of your videos :) + +Get all the available qualities using `YouTubePlayerListener#onVideoQuality` and set the player's quality using `youtubePlayer#setPlaybackQuality`. + +## Login to YouTube account + +By logging in you will be able to play private videos from the user. + +The idea here is to create a `WebView` and use it to authentucate with YouTube. The results of the authentication will be shared with the `WebView` containing the YouTube player. + +```java +private void log_in() { + WebView webView = new WebView(context); + webView.getSettings().setJavaScriptEnabled(true); + webView.getSettings().setDomStorageEnabled(true); + webView.getSettings().setSavePassword(true); + webView.getSettings().setSaveFormData(true); + webView.loadUrl("https://accounts.google.com/ServiceLogin?service=youtube&uilel=3&passive=true&continue=https%3A%2F%2Fwww.youtube.com%2Fsignin%3Faction_handle_signin%3Dtrue%26app%3Dm%26hl%3Dtr%26next%3Dhttps%253A%252F%252Fm.youtube.com%252F"); + webView.setWebViewClient(new WebViewClient() { + @Override + public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { + //if webview redirects to youtube.com it means we're logged in + if ( + request.getUrl().toString().startsWith("https://m.youtube.com") || + request.getUrl().toString().startsWith("https://www.youtube.com") + ) { + Log.d(TAG, "Logged in"); + Toast.makeText(MainActivity.this, "Logged in", Toast.LENGTH_SHORT).show(); + return false; + } + return false; + } + }); +} +``` + +In `WebViewYouTubePlayer#initWebView` add this code to enable dom storage, to avoid being logged out constantly: + +```kt + settings.domStorageEnabled = true +``` + +## Block Ads + +This workaround searches for the `video-ads` element in the webview by running a query selector every 100 milliseconds. When it finds a `video-ads` element, first mutes it, then subtracts the duration of the ad from the duration of the main video and unmutes it again. + +Add this function to `ayp_youtube_player.html` and call it from `sendPlayerStateChange`: + +```js +let adblockIntervalId; + +function initializeAdBlock() { + if (adblockIntervalId) { + clearInterval(adblockIntervalId); + } + + const playerIFrame = document.querySelector("iframe"); + if (playerIFrame) { + adblockIntervalId = setInterval(() => { + if (!playerIFrame) { + return; + } + + const frameDoc = playerIFrame.contentDocument; + if (!frameDoc) { + return; + } + + + const adsContainer = frameDoc.querySelector('.video-ads'); + if (!adsContainer || adsContainer.childElementCount == 0) { + return; + } + + const adsVideo = adsContainer.querySelector("video"); + + if (adsVideo) { + adsVideo.muted = true; + adsVideo.style.display = 'none'; + adsVideo.currentTime = adsVideo.duration - 0.15; + adsVideo.muted = false; + adsVideo.style.display = ''; + if (adblockIntervalId) { + clearInterval(adblockIntervalId); + } + } + else { + const isAdShowing = frameDoc.getElementsByClassName('ad-showing').length != 0; + if (!isAdShowing) { + return; + } + + const mainVideo = frameDoc.querySelector('.html5-main-video'); + if (!mainVideo) { + return; + } + + mainVideo.muted = true; + mainVideo.currentTime = mainVideo.duration - 0.15; + mainVideo.muted = false; + if (adblockIntervalId) { + clearInterval(adblockIntervalId); + } + } + }, 100); + } +} +``` + +## Remove Annoying Views + +This workaround provides ways to remove annoying views from the player that can't be removed with official APIs. + +### Hide Title + +Hide title and channel picture at once + +Add this to `ayp_youtube_player.html`, and call it inside `onReady`. + +```js +function hideVideoTitle() { + setInterval(() => { + const playerIFrame = document.querySelector("iframe"); + if (!playerIFrame) { + return; + } + + const frameDoc = playerIFrame.contentDocument; + if (!frameDoc) { + return; + } + + const title = frameDoc.querySelector('.ytp-chrome-top'); + if (title) { + title.style.display = 'none'; + } + }, 100); +} +``` + +### Hide 'More Videos' section that covers most of the video when paused (Only visible on tablets and bigger screens) + +Add this to `ayp_youtube_player.html`, and call it inside `onReady`. + +```js +function hideTabletPopup() { + setInterval(() => { + const playerIFrame = document.querySelector("iframe"); + if (!playerIFrame) { + return; + } + + const frameDoc = playerIFrame.contentDocument; + if (!frameDoc) { + return; + } + + const collection = frameDoc.getElementsByClassName("ytp-pause-overlay-container")[0]; + if (!collection) { + return; + } + collection.style.display = 'none'; + }, 100); +} +``` +## Hide Captions + +Add this to `ayp_youtube_player.html`, and call it inside `onReady`. + +```js +function hideCaption() { + setInterval(() => { + if(!player) { + return; + } + player.unloadModule('captions'); + }, 1000); +} +``` + +To enable captions + +```js +function hideCaption() { + if(!player) { + return; + } + player.loadModule('captions'); +} +``` + +## Play Next Recomended Video + +This workaround gets the id from 'more videos' and plays it as a next video, you can think of it like the "recomended" section on YouTube. You can use it like auto-play on YouTube. + +If the `rel` paramter is set to 0: the next video will come from the same channel as the video that was just played. + +If the `rel` paramater is set to 1: the next video will be from related videos that come from multiple channels. + +Add this to `ayp_youtube_player.html`, and call it inside `onReady`. + +```js +function playNextVideo() { + const playerIFrame = document.querySelector("iframe"); + if (!playerIFrame) { + return; + } + + const frameDoc = playerIFrame.contentDocument; + if (!frameDoc) { + return; + } + + const nextVideo = frameDoc.querySelectorAll('.ytp-suggestions a') + if(!nextVideo){ + return; + } + + let videoId = nextVideo[0].href.split('v=')[1]; + let ampersandIndex = videoId.indexOf('&'); + if (ampersandIndex != -1) { + videoId = videoId.substring(0, ampersandIndex); + } + player.loadVideoById(videoId, 0); +} +``` + +Then add this method to the `YouTubePlayer` interface: + +```kt +fun playNextVideo() +``` + +And implement it in `WebViewYouTubePlayer` + +```kt +override fun playNextVideo() { + mainThreadHandler.post { loadUrl("javascript:playNextVideo()") } +} +``` + --- For any question feel free to [open an issue on the GitHub repository](https://github.com/PierfrancescoSoffritti/android-youtube-player/issues). From 4a5505d22e3b8baeba54a38df0de391a1d0b2a34 Mon Sep 17 00:00:00 2001 From: PierfrancescoSoffritti Date: Fri, 10 Mar 2023 07:19:09 +0000 Subject: [PATCH 09/16] Update FUNDING.yml --- FUNDING.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/FUNDING.yml b/FUNDING.yml index 38a63039..eefab3cf 100644 --- a/FUNDING.yml +++ b/FUNDING.yml @@ -1,2 +1 @@ -ko_fi: psoffritti -custom: ['paypal.me/psoffritti'] \ No newline at end of file +github: PierfrancescoSoffritti \ No newline at end of file From 9330183c101c08b767050a2e0759cfb1a3a441fe Mon Sep 17 00:00:00 2001 From: PierfrancescoSoffritti Date: Sun, 12 Mar 2023 18:28:10 +0000 Subject: [PATCH 10/16] Update Gradle Plugin to 7.4.2 --- chromecast-sender-sample-app/build.gradle | 9 ++++++--- .../src/main/AndroidManifest.xml | 3 +-- chromecast-sender/build.gradle | 1 + chromecast-sender/src/main/AndroidManifest.xml | 2 +- core-sample-app/build.gradle | 9 ++++++--- core-sample-app/src/main/AndroidManifest.xml | 3 +-- core/build.gradle | 1 + core/src/main/AndroidManifest.xml | 3 +-- dependencies.gradle | 4 ++-- gradle/wrapper/gradle-wrapper.properties | 2 +- 10 files changed, 21 insertions(+), 16 deletions(-) diff --git a/chromecast-sender-sample-app/build.gradle b/chromecast-sender-sample-app/build.gradle index 2f4f6f2b..d7f16306 100644 --- a/chromecast-sender-sample-app/build.gradle +++ b/chromecast-sender-sample-app/build.gradle @@ -19,11 +19,14 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } - - // this is needed because I'm importing 2 modules called "core" (core and com.psoffritti.librarysampleapptemplate:core) (https://discuss.kotlinlang.org/t/disable-meta-inf-generation-in-gradle-android-project/3830) packagingOptions { - exclude 'META-INF/core_release.kotlin_module' + resources { + // this is needed because I'm importing 2 modules called "core" (core and com.psoffritti.librarysampleapptemplate:core) (https://discuss.kotlinlang.org/t/disable-meta-inf-generation-in-gradle-android-project/3830) + excludes += ['META-INF/core_release.kotlin_module'] + } } + + namespace 'com.pierfrancescosoffritti.cyplayersample' } dependencies { diff --git a/chromecast-sender-sample-app/src/main/AndroidManifest.xml b/chromecast-sender-sample-app/src/main/AndroidManifest.xml index d1e74a4a..ae517f1a 100644 --- a/chromecast-sender-sample-app/src/main/AndroidManifest.xml +++ b/chromecast-sender-sample-app/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - + + diff --git a/core-sample-app/build.gradle b/core-sample-app/build.gradle index 73be19ba..e4707e8d 100644 --- a/core-sample-app/build.gradle +++ b/core-sample-app/build.gradle @@ -24,11 +24,14 @@ android { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } - - // this is needed because I'm importing 2 modules called "core" (core and com.psoffritti.librarysampleapptemplate:core) (https://discuss.kotlinlang.org/t/disable-meta-inf-generation-in-gradle-android-project/3830) packagingOptions { - exclude 'META-INF/core_release.kotlin_module' + resources { + // this is needed because I'm importing 2 modules called "core" (core and com.psoffritti.librarysampleapptemplate:core) (https://discuss.kotlinlang.org/t/disable-meta-inf-generation-in-gradle-android-project/3830) + excludes += ['META-INF/core_release.kotlin_module'] + } } + + namespace 'com.pierfrancescosoffritti.aytplayersample' } dependencies { diff --git a/core-sample-app/src/main/AndroidManifest.xml b/core-sample-app/src/main/AndroidManifest.xml index b32662ed..d2dd4222 100644 --- a/core-sample-app/src/main/AndroidManifest.xml +++ b/core-sample-app/src/main/AndroidManifest.xml @@ -1,7 +1,6 @@ + xmlns:android="http://schemas.android.com/apk/res/android"> + xmlns:android="http://schemas.android.com/apk/res/android"> diff --git a/dependencies.gradle b/dependencies.gradle index 4a13e23c..fc56c2bc 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -10,13 +10,13 @@ ext.versions = [ publishVersionCode_chromecast : 12, // Plugins - gradlePlugin : '7.0.4', + gradlePlugin : '7.4.2', dexCount : '3.0.1', gradleNexus : '1.1.0', dokka : '1.6.0', // Kotlin - kotlin : '1.6.0', + kotlin : '1.6.21', // AndroidX androidxCore : '1.4.2', diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c43a04ec..b9af8aff 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Mon Aug 09 16:15:03 BST 2021 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME From 3209235f520bd32391bb6e4fb5525a2277918aba Mon Sep 17 00:00:00 2001 From: PierfrancescoSoffritti Date: Sun, 12 Mar 2023 19:09:11 +0000 Subject: [PATCH 11/16] Rename full screen logic to be more explicit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing methods to handle full screen mode in `YouTubePlayerView` only change the view’s `LayoutParams` to fill its parent or wrap its content. The naming is misleading because they don’t change the state of the IFrame Player. This change is in preparation of future integration with the full screen state of the IFrame Player. List of main changes in this commit (these are also breaking changes): * Replace YouTubePlayerView#enterFullScreen with YouTubePlayerView#matchParent * Replace YouTubePlayerView#existFullScreen with YouTubePlayerView#wrapContent * Remove YouTubePlayerView#toggleFullScreen * Remove YouTubePlayerView#isFullScreen * Remove `YouTubePlayerFullScreenListener` interface --- .../CompleteExampleActivity.java | 17 ++++-- .../CustomPlayerUiController.java | 27 +-------- .../customUiExample/CustomUiActivity.java | 5 +- .../DefaultCustomUiExampleActivity.java | 4 +- .../FragmentExampleFragment.java | 4 +- .../IFramePlayerOptionsExampleActivity.java | 4 +- .../liveVideoExample/LiveVideoActivity.java | 4 +- .../NoLifecycleObserverExampleActivity.java | 4 +- .../PictureInPictureActivity.java | 4 +- .../PlaylistExampleActivity.java | 4 +- .../simpleExample/SimpleExampleActivity.java | 4 +- .../YouTubePlayerFullScreenListener.kt | 7 --- .../core/player/utils/FullScreenHelper.kt | 56 ------------------- .../core/player/views/YouTubePlayerView.kt | 41 ++++++++------ .../core/ui/DefaultPlayerUiController.kt | 12 +++- 15 files changed, 67 insertions(+), 130 deletions(-) delete mode 100644 core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/YouTubePlayerFullScreenListener.kt delete mode 100644 core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/utils/FullScreenHelper.kt diff --git a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/completeExample/CompleteExampleActivity.java b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/completeExample/CompleteExampleActivity.java index d660b516..31c0beea 100644 --- a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/completeExample/CompleteExampleActivity.java +++ b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/completeExample/CompleteExampleActivity.java @@ -23,7 +23,7 @@ public class CompleteExampleActivity extends AppCompatActivity { private YouTubePlayerView youTubePlayerView; - private FullScreenHelper fullScreenHelper = new FullScreenHelper(this); + private boolean isPlayerMatchParent = false; // a list of videos not available in some countries, to test if they're handled gracefully. // private String[] nonPlayableVideoIds = { "sop2V_MREEI" }; @@ -44,19 +44,24 @@ public void onConfigurationChanged(@NonNull Configuration newConfig) { // Checks the orientation of the screen if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { - youTubePlayerView.enterFullScreen(); + youTubePlayerView.matchParent(); + isPlayerMatchParent = true; } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ - youTubePlayerView.exitFullScreen(); + youTubePlayerView.wrapContent(); + isPlayerMatchParent = false; } } @Override public void onBackPressed() { - if (youTubePlayerView.isFullScreen()) - youTubePlayerView.exitFullScreen(); - else + if (isPlayerMatchParent) { + youTubePlayerView.wrapContent(); + isPlayerMatchParent = false; + } + else { super.onBackPressed(); + } } private void initYouTubePlayerView() { diff --git a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/customUiExample/CustomPlayerUiController.java b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/customUiExample/CustomPlayerUiController.java index 05d5e489..5a91779c 100644 --- a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/customUiExample/CustomPlayerUiController.java +++ b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/customUiExample/CustomPlayerUiController.java @@ -14,14 +14,10 @@ import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer; import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView; import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.AbstractYouTubePlayerListener; -import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.YouTubePlayerFullScreenListener; import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.utils.YouTubePlayerTracker; import com.pierfrancescosoffritti.aytplayersample.R; -class CustomPlayerUiController extends AbstractYouTubePlayerListener implements YouTubePlayerFullScreenListener { - - private final View playerUi; - +class CustomPlayerUiController extends AbstractYouTubePlayerListener { private Context context; private YouTubePlayer youTubePlayer; private YouTubePlayerView youTubePlayerView; @@ -36,7 +32,6 @@ class CustomPlayerUiController extends AbstractYouTubePlayerListener implements private boolean fullscreen = false; CustomPlayerUiController(Context context, View customPlayerUi, YouTubePlayer youTubePlayer, YouTubePlayerView youTubePlayerView) { - this.playerUi = customPlayerUi; this.context = context; this.youTubePlayer = youTubePlayer; this.youTubePlayerView = youTubePlayerView; @@ -61,8 +56,8 @@ private void initViews(View playerUi) { }); enterExitFullscreenButton.setOnClickListener( (view) -> { - if(fullscreen) youTubePlayerView.exitFullScreen(); - else youTubePlayerView.enterFullScreen(); + if(fullscreen) youTubePlayerView.wrapContent(); + else youTubePlayerView.matchParent(); fullscreen = !fullscreen; }); @@ -93,20 +88,4 @@ public void onCurrentSecond(@NonNull YouTubePlayer youTubePlayer, float second) public void onVideoDuration(@NonNull YouTubePlayer youTubePlayer, float duration) { videoDurationTextView.setText(duration+""); } - - @Override - public void onYouTubePlayerEnterFullScreen() { - ViewGroup.LayoutParams viewParams = playerUi.getLayoutParams(); - viewParams.height = ViewGroup.LayoutParams.MATCH_PARENT; - viewParams.width = ViewGroup.LayoutParams.MATCH_PARENT; - playerUi.setLayoutParams(viewParams); - } - - @Override - public void onYouTubePlayerExitFullScreen() { - ViewGroup.LayoutParams viewParams = playerUi.getLayoutParams(); - viewParams.height = ViewGroup.LayoutParams.WRAP_CONTENT; - viewParams.width = ViewGroup.LayoutParams.MATCH_PARENT; - playerUi.setLayoutParams(viewParams); - } } diff --git a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/customUiExample/CustomUiActivity.java b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/customUiExample/CustomUiActivity.java index 9ce972a1..c3ebeb80 100644 --- a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/customUiExample/CustomUiActivity.java +++ b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/customUiExample/CustomUiActivity.java @@ -35,7 +35,6 @@ protected void onCreate(Bundle savedInstanceState) { public void onReady(@NonNull YouTubePlayer youTubePlayer) { CustomPlayerUiController customPlayerUiController = new CustomPlayerUiController(CustomUiActivity.this, customPlayerUi, youTubePlayer, youTubePlayerView); youTubePlayer.addListener(customPlayerUiController); - youTubePlayerView.addFullScreenListener(customPlayerUiController); YouTubePlayerUtils.loadOrCueVideo( youTubePlayer, getLifecycle(), @@ -56,10 +55,10 @@ public void onConfigurationChanged(@NonNull Configuration newConfig) { // Checks the orientation of the screen if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { - youTubePlayerView.enterFullScreen(); + youTubePlayerView.matchParent(); } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ - youTubePlayerView.exitFullScreen(); + youTubePlayerView.wrapContent(); } } } diff --git a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/defaultCustomUiExample/DefaultCustomUiExampleActivity.java b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/defaultCustomUiExample/DefaultCustomUiExampleActivity.java index 222251b0..5998beec 100644 --- a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/defaultCustomUiExample/DefaultCustomUiExampleActivity.java +++ b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/defaultCustomUiExample/DefaultCustomUiExampleActivity.java @@ -65,10 +65,10 @@ public void onConfigurationChanged(@NonNull Configuration newConfig) { // Checks the orientation of the screen if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { - youTubePlayerView.enterFullScreen(); + youTubePlayerView.matchParent(); } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ - youTubePlayerView.exitFullScreen(); + youTubePlayerView.wrapContent(); } } diff --git a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/fragmentExample/FragmentExampleFragment.java b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/fragmentExample/FragmentExampleFragment.java index 4d3c5ce6..2867e39b 100644 --- a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/fragmentExample/FragmentExampleFragment.java +++ b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/fragmentExample/FragmentExampleFragment.java @@ -41,10 +41,10 @@ public void onConfigurationChanged(@NonNull Configuration newConfig) { // Checks the orientation of the screen if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { - youTubePlayerView.enterFullScreen(); + youTubePlayerView.matchParent(); } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ - youTubePlayerView.exitFullScreen(); + youTubePlayerView.wrapContent(); } } diff --git a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/iFramePlayerOptionsExample/IFramePlayerOptionsExampleActivity.java b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/iFramePlayerOptionsExample/IFramePlayerOptionsExampleActivity.java index a9828c71..26b5e08e 100644 --- a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/iFramePlayerOptionsExample/IFramePlayerOptionsExampleActivity.java +++ b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/iFramePlayerOptionsExample/IFramePlayerOptionsExampleActivity.java @@ -60,10 +60,10 @@ public void onConfigurationChanged(@NonNull Configuration newConfig) { // Checks the orientation of the screen if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { - youTubePlayerView.enterFullScreen(); + youTubePlayerView.matchParent(); } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ - youTubePlayerView.exitFullScreen(); + youTubePlayerView.wrapContent(); } } diff --git a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/liveVideoExample/LiveVideoActivity.java b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/liveVideoExample/LiveVideoActivity.java index 4765f301..a9ecc064 100644 --- a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/liveVideoExample/LiveVideoActivity.java +++ b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/liveVideoExample/LiveVideoActivity.java @@ -33,10 +33,10 @@ public void onConfigurationChanged(@NonNull Configuration newConfig) { // Checks the orientation of the screen if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { - youTubePlayerView.enterFullScreen(); + youTubePlayerView.matchParent(); } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ - youTubePlayerView.exitFullScreen(); + youTubePlayerView.wrapContent(); } } diff --git a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/noLifecycleObserverExample/NoLifecycleObserverExampleActivity.java b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/noLifecycleObserverExample/NoLifecycleObserverExampleActivity.java index ac8e01f4..3192b125 100644 --- a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/noLifecycleObserverExample/NoLifecycleObserverExampleActivity.java +++ b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/noLifecycleObserverExample/NoLifecycleObserverExampleActivity.java @@ -50,10 +50,10 @@ public void onConfigurationChanged(@NonNull Configuration newConfig) { // Checks the orientation of the screen if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { - youTubePlayerView.enterFullScreen(); + youTubePlayerView.matchParent(); } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ - youTubePlayerView.exitFullScreen(); + youTubePlayerView.wrapContent(); } } } diff --git a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/pictureInPictureExample/PictureInPictureActivity.java b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/pictureInPictureExample/PictureInPictureActivity.java index 0e1b4183..d5f13c92 100644 --- a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/pictureInPictureExample/PictureInPictureActivity.java +++ b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/pictureInPictureExample/PictureInPictureActivity.java @@ -69,9 +69,9 @@ public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode, Conf super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig); if(isInPictureInPictureMode) { - youTubePlayerView.enterFullScreen(); + youTubePlayerView.matchParent(); } else { - youTubePlayerView.exitFullScreen(); + youTubePlayerView.wrapContent(); } } } diff --git a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/playlistExample/PlaylistExampleActivity.java b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/playlistExample/PlaylistExampleActivity.java index 20e72cd5..187a4b84 100644 --- a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/playlistExample/PlaylistExampleActivity.java +++ b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/playlistExample/PlaylistExampleActivity.java @@ -48,10 +48,10 @@ public void onConfigurationChanged(@NonNull Configuration newConfig) { // Checks the orientation of the screen if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { - youTubePlayerView.enterFullScreen(); + youTubePlayerView.matchParent(); } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ - youTubePlayerView.exitFullScreen(); + youTubePlayerView.wrapContent(); } } } diff --git a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/simpleExample/SimpleExampleActivity.java b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/simpleExample/SimpleExampleActivity.java index 1946c4b8..65324957 100644 --- a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/simpleExample/SimpleExampleActivity.java +++ b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/simpleExample/SimpleExampleActivity.java @@ -28,10 +28,10 @@ public void onConfigurationChanged(@NonNull Configuration newConfig) { // Checks the orientation of the screen if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { - youTubePlayerView.enterFullScreen(); + youTubePlayerView.matchParent(); } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ - youTubePlayerView.exitFullScreen(); + youTubePlayerView.wrapContent(); } } } diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/YouTubePlayerFullScreenListener.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/YouTubePlayerFullScreenListener.kt deleted file mode 100644 index bfbaa55d..00000000 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/YouTubePlayerFullScreenListener.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners - - -interface YouTubePlayerFullScreenListener { - fun onYouTubePlayerEnterFullScreen() - fun onYouTubePlayerExitFullScreen() -} diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/utils/FullScreenHelper.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/utils/FullScreenHelper.kt deleted file mode 100644 index 2649015b..00000000 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/utils/FullScreenHelper.kt +++ /dev/null @@ -1,56 +0,0 @@ -package com.pierfrancescosoffritti.androidyoutubeplayer.core.player.utils - -import android.view.View -import android.view.ViewGroup -import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.YouTubePlayerFullScreenListener - -import java.util.HashSet - -internal class FullScreenHelper(private val targetView: View) { - - var isFullScreen: Boolean = false - private set - - private val fullScreenListeners = mutableSetOf() - - fun enterFullScreen() { - if (isFullScreen) return - - isFullScreen = true - - val viewParams = targetView.layoutParams - viewParams.height = ViewGroup.LayoutParams.MATCH_PARENT - viewParams.width = ViewGroup.LayoutParams.MATCH_PARENT - targetView.layoutParams = viewParams - - for (fullScreenListener in fullScreenListeners) - fullScreenListener.onYouTubePlayerEnterFullScreen() - } - - fun exitFullScreen() { - if (!isFullScreen) return - - isFullScreen = false - - val viewParams = targetView.layoutParams - viewParams.height = ViewGroup.LayoutParams.WRAP_CONTENT - viewParams.width = ViewGroup.LayoutParams.MATCH_PARENT - targetView.layoutParams = viewParams - - for (fullScreenListener in fullScreenListeners) - fullScreenListener.onYouTubePlayerExitFullScreen() - } - - fun toggleFullScreen() { - if (isFullScreen) exitFullScreen() - else enterFullScreen() - } - - fun addFullScreenListener(fullScreenListener: YouTubePlayerFullScreenListener): Boolean { - return fullScreenListeners.add(fullScreenListener) - } - - fun removeFullScreenListener(fullScreenListener: YouTubePlayerFullScreenListener): Boolean { - return fullScreenListeners.remove(fullScreenListener) - } -} diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/YouTubePlayerView.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/YouTubePlayerView.kt index 65c5f435..3f66919d 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/YouTubePlayerView.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/YouTubePlayerView.kt @@ -12,11 +12,8 @@ import com.pierfrancescosoffritti.androidyoutubeplayer.R 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.listeners.YouTubePlayerFullScreenListener import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.YouTubePlayerListener import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.options.IFramePlayerOptions -import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.utils.FullScreenHelper -import com.pierfrancescosoffritti.androidyoutubeplayer.core.ui.PlayerUiController import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.utils.loadOrCueVideo class YouTubePlayerView(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0): @@ -26,7 +23,6 @@ class YouTubePlayerView(context: Context, attrs: AttributeSet? = null, defStyleA constructor(context: Context, attrs: AttributeSet? = null): this(context, attrs, 0) private val legacyTubePlayerView: LegacyYouTubePlayerView = LegacyYouTubePlayerView(context) - private val fullScreenHelper = FullScreenHelper(this) // this is a publicly accessible API var enableAutomaticInitialization: Boolean @@ -149,21 +145,32 @@ class YouTubePlayerView(context: Context, attrs: AttributeSet? = null, defStyleA fun removeYouTubePlayerListener(youTubePlayerListener: YouTubePlayerListener) = legacyTubePlayerView.youTubePlayer.removeListener(youTubePlayerListener) - fun enterFullScreen() = fullScreenHelper.enterFullScreen() - - fun exitFullScreen() = fullScreenHelper.exitFullScreen() - - fun toggleFullScreen() = fullScreenHelper.toggleFullScreen() - - fun isFullScreen() = fullScreenHelper.isFullScreen + /** + * Convenience method to set the [YouTubePlayerView] width and height to match parent. + */ + fun matchParent() { + setLayoutParams( + targetWidth = ViewGroup.LayoutParams.MATCH_PARENT, + targetHeight = ViewGroup.LayoutParams.MATCH_PARENT + ) + } /** - * Adds a [YouTubePlayerFullScreenListener] to the view. - * - * [YouTubePlayerFullScreenListener.onYouTubePlayerEnterFullScreen] and [YouTubePlayerFullScreenListener.onYouTubePlayerExitFullScreen] - * are called when [YouTubePlayerView.enterFullScreen] and [YouTubePlayerView.exitFullScreen] are called. + * Convenience method to set the [YouTubePlayerView] width to match parent and + * height to wrap content. */ - fun addFullScreenListener(fullScreenListener: YouTubePlayerFullScreenListener) = fullScreenHelper.addFullScreenListener(fullScreenListener) + fun wrapContent() { + setLayoutParams( + targetWidth = ViewGroup.LayoutParams.MATCH_PARENT, + targetHeight = ViewGroup.LayoutParams.WRAP_CONTENT + ) + } - fun removeFullScreenListener(fullScreenListener: YouTubePlayerFullScreenListener) = fullScreenHelper.removeFullScreenListener(fullScreenListener) + @Suppress("SameParameterValue") + private fun setLayoutParams(targetWidth: Int, targetHeight: Int) { + layoutParams = layoutParams.apply { + width = targetWidth + height = targetHeight + } + } } \ No newline at end of file diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/DefaultPlayerUiController.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/DefaultPlayerUiController.kt index 1102b6ea..b1d4ff14 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/DefaultPlayerUiController.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/DefaultPlayerUiController.kt @@ -5,6 +5,7 @@ import android.graphics.drawable.Drawable import android.net.Uri import android.util.Log import android.view.View +import android.view.ViewGroup import android.widget.ImageView import android.widget.LinearLayout import android.widget.ProgressBar @@ -59,6 +60,8 @@ class DefaultPlayerUiController(private val youTubePlayerView: YouTubePlayerView private var isCustomActionLeftEnabled = false private var isCustomActionRightEnabled = false + private var isMatchParent = false + private val youTubePlayerStateListener = object : AbstractYouTubePlayerListener() { override fun onStateChange(youTubePlayer: YouTubePlayer, state: PlayerConstants.PlayerState) { updateState(state) @@ -105,7 +108,14 @@ class DefaultPlayerUiController(private val youTubePlayerView: YouTubePlayerView } init { - onFullScreenButtonListener = View.OnClickListener { youTubePlayerView.toggleFullScreen() } + onFullScreenButtonListener = View.OnClickListener { + isMatchParent = !isMatchParent + when (isMatchParent) { + true -> youTubePlayerView.matchParent() + false -> youTubePlayerView.wrapContent() + } + } + onMenuButtonClickListener = View.OnClickListener { youTubePlayerMenu.show(menuButton) } initClickListeners() From 90d1148f17a127e080755f50244f22f73b36a0a5 Mon Sep 17 00:00:00 2001 From: PierfrancescoSoffritti Date: Sun, 12 Mar 2023 19:14:29 +0000 Subject: [PATCH 12/16] Add .idea/ to gitignore --- .gitignore | 5 +- .idea/caches/build_file_checksums.ser | Bin 724 -> 0 bytes .idea/codeStyles/Project.xml | 113 -------------------------- .idea/gradle.xml | 2 - .idea/jarRepositories.xml | 18 ++-- .idea/misc.xml | 73 +---------------- .idea/modules.xml | 24 ------ 7 files changed, 11 insertions(+), 224 deletions(-) delete mode 100644 .idea/caches/build_file_checksums.ser delete mode 100644 .idea/codeStyles/Project.xml delete mode 100644 .idea/modules.xml diff --git a/.gitignore b/.gitignore index 4c5089c3..a4eaee4f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,7 @@ *.iml .gradle /local.properties -/.idea/workspace.xml -/.idea/libraries -/.idea/dictionaries -/.idea/gradle.xml +/.idea .DS_Store /build /captures diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser deleted file mode 100644 index de33ccdc86943fff1303e40b46f1e65ab9a8dc3a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 724 zcmZ4UmVvdnh`~NNKUXg?FQq6yGexf?KR>5fFEb@IQ7^qHF(oHeub?PDD>b=9F91S2 zm1gFoxMk*~I%lLNXBU^|7Q2L-Ts|(GuF1r}mx#p?K1J<&)?@JhXP;7uJ z%*&nd^!d&`2i=NVSM1SWy0nBrGdZIuKQ}cQ7;3u3sd*`>ML69FH-+J>xlhIW>f05E zZp-${PBJcG5Xi|-PRs#CRzYe}NoHzsDO_=vgk$NPiW1(Cn5wu(u1oHgFbIM|12qWX zs&8;^^ZU9y*1hT9@`5A3zR8v_$YD4ThgOE>GXVm#l-w_$IJkPk#3&=6MTj(n;VedJ z*I7pjr?K@&E!cL)S}dc4LBrW9CbT%Us5quLKP{~&1{%sScnrBB+jFy@VH3;C2F@98 JemK=t001yu0tx^C diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index ae78c113..00000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,113 +0,0 @@ - - - - - -
- - - - xmlns:android - - ^$ - - - -
-
- - - - xmlns:.* - - ^$ - - - BY_NAME - -
-
- - - - .*:id - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:name - - http://schemas.android.com/apk/res/android - - - -
-
- - - - name - - ^$ - - - -
-
- - - - style - - ^$ - - - -
-
- - - - .* - - ^$ - - - BY_NAME - -
-
- - - - .* - - http://schemas.android.com/apk/res/android - - - ANDROID_ATTRIBUTE_ORDER - -
-
- - - - .* - - .* - - - BY_NAME - -
-
-
-
-
-
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 6e9c9bf7..f1281195 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -1,13 +1,11 @@ - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 030cbfbb..54d5acd7 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,77 +1,6 @@ - - - - - - - - - - - - + diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index e60ae16a..00000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From 3db29964bd41428fba7141a7c027f6d88e1b7896 Mon Sep 17 00:00:00 2001 From: PierfrancescoSoffritti Date: Sun, 12 Mar 2023 19:16:21 +0000 Subject: [PATCH 13/16] Remove .idea folder --- .gitignore | 2 +- .idea/compiler.xml | 6 ------ .idea/gradle.xml | 21 --------------------- .idea/jarRepositories.xml | 35 ----------------------------------- .idea/misc.xml | 10 ---------- .idea/vcs.xml | 6 ------ 6 files changed, 1 insertion(+), 79 deletions(-) delete mode 100644 .idea/compiler.xml delete mode 100644 .idea/gradle.xml delete mode 100644 .idea/jarRepositories.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/vcs.xml diff --git a/.gitignore b/.gitignore index a4eaee4f..344526f5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ *.iml .gradle /local.properties -/.idea +.idea/ .DS_Store /build /captures diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index fb7f4a8a..00000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index f1281195..00000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml deleted file mode 100644 index 80cff4c4..00000000 --- a/.idea/jarRepositories.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 54d5acd7..00000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1ddf..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From 7d1d6769f559043b65d3c5df8c2cd574c3db2214 Mon Sep 17 00:00:00 2001 From: Pierfrancesco Soffritti Date: Sun, 12 Mar 2023 19:16:59 +0000 Subject: [PATCH 14/16] Update readme (#875) (#931) Add Genius to the apps that are using the library From 2ff16ee285dca32bbfe7da674a25a3e791ebc650 Mon Sep 17 00:00:00 2001 From: Pierfrancesco Soffritti Date: Mon, 13 Mar 2023 08:33:28 +0000 Subject: [PATCH 15/16] Clean up full screen implementation --- .../SimpleFullscreenExampleActivity.java | 56 ++++++++----------- .../activity_simple_fullscreen_example.xml | 13 ++--- .../AbstractYouTubePlayerListener.kt | 2 - .../player/listeners/FullScreenListener.kt | 31 ++++++++++ .../player/listeners/YouTubePlayerListener.kt | 12 ---- .../player/options/IFramePlayerOptions.kt | 4 +- .../player/views/LegacyYouTubePlayerView.kt | 14 +++-- .../core/player/views/WebViewYouTubePlayer.kt | 30 +++++++--- .../core/player/views/YouTubePlayerView.kt | 42 ++++++++++++-- .../core/ui/utils/FadeViewHelper.kt | 2 - .../core/ui/views/YouTubePlayerSeekBar.kt | 2 - 11 files changed, 130 insertions(+), 78 deletions(-) create mode 100644 core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/FullScreenListener.kt diff --git a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/simpleFullscreenExample/SimpleFullscreenExampleActivity.java b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/simpleFullscreenExample/SimpleFullscreenExampleActivity.java index cfed533f..40c4ff3c 100644 --- a/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/simpleFullscreenExample/SimpleFullscreenExampleActivity.java +++ b/core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/simpleFullscreenExample/SimpleFullscreenExampleActivity.java @@ -1,24 +1,27 @@ package com.pierfrancescosoffritti.androidyoutubeplayer.core.sampleapp.examples.simpleFullscreenExample; import android.content.pm.ActivityInfo; -import android.content.res.Configuration; import android.os.Bundle; import android.view.View; -import android.webkit.WebChromeClient; import android.widget.FrameLayout; + import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; + import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer; import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.AbstractYouTubePlayerListener; +import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.FullScreenListener; import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.options.IFramePlayerOptions; import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView; import com.pierfrancescosoffritti.aytplayersample.R; -import org.jetbrains.annotations.Nullable; + +import kotlin.Unit; +import kotlin.jvm.functions.Function0; public class SimpleFullscreenExampleActivity extends AppCompatActivity { private YouTubePlayerView youTubePlayerView; - private FrameLayout customView; + private FrameLayout fullScreenViewContainer; @Override protected void onCreate(Bundle savedInstanceState) { @@ -27,36 +30,36 @@ protected void onCreate(Bundle savedInstanceState) { IFramePlayerOptions iFramePlayerOptions = new IFramePlayerOptions.Builder() .controls(1) - .fullScreen(1) + .fullscreen(1) .build(); youTubePlayerView = findViewById(R.id.youtube_player_view); - customView = findViewById(R.id.customView); + fullScreenViewContainer = findViewById(R.id.full_screen_view_container); youTubePlayerView.setEnableAutomaticInitialization(false); - youTubePlayerView.initialize(new AbstractYouTubePlayerListener() { + + youTubePlayerView.addFullScreenListener(new FullScreenListener() { @Override - public void onShowCustomView(@Nullable View view, @Nullable WebChromeClient.CustomViewCallback callback) { - super.onShowCustomView(view, callback); + public void onEnterFullScreen(@NonNull View fullScreenView, @NonNull Function0 exitFullScreen) { // for display full screen landscape view youTubePlayerView.setVisibility(View.GONE); - customView.setVisibility(View.VISIBLE); - customView.addView(view); - if (!youTubePlayerView.isFullScreen()) { - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); - } + fullScreenViewContainer.setVisibility(View.VISIBLE); + fullScreenViewContainer.addView(fullScreenView); + + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } @Override - public void onHideCustomView() { - super.onHideCustomView(); + public void onExitFullScreen() { youTubePlayerView.setVisibility(View.VISIBLE); - customView.setVisibility(View.GONE); - if (youTubePlayerView.isFullScreen()) { - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); - } + fullScreenViewContainer.setVisibility(View.GONE); + fullScreenViewContainer.removeAllViews(); + + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); } + }); + youTubePlayerView.initialize(new AbstractYouTubePlayerListener() { @Override public void onReady(@NonNull YouTubePlayer youTubePlayer) { super.onReady(youTubePlayer); @@ -66,17 +69,4 @@ public void onReady(@NonNull YouTubePlayer youTubePlayer) { getLifecycle().addObserver(youTubePlayerView); } - - @Override - public void onConfigurationChanged(@NonNull Configuration newConfig) { - super.onConfigurationChanged(newConfig); - - // Checks the orientation of the screen - if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { - youTubePlayerView.enterFullScreen(); - } - else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ - youTubePlayerView.exitFullScreen(); - } - } } diff --git a/core-sample-app/src/main/res/layout/activity_simple_fullscreen_example.xml b/core-sample-app/src/main/res/layout/activity_simple_fullscreen_example.xml index 28404310..d1f7a1b4 100644 --- a/core-sample-app/src/main/res/layout/activity_simple_fullscreen_example.xml +++ b/core-sample-app/src/main/res/layout/activity_simple_fullscreen_example.xml @@ -2,7 +2,6 @@ @@ -14,13 +13,13 @@ app:layout_constraintStart_toStartOf="parent" /> + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> \ No newline at end of file diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/AbstractYouTubePlayerListener.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/AbstractYouTubePlayerListener.kt index 7841e010..6bd9daaa 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/AbstractYouTubePlayerListener.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/AbstractYouTubePlayerListener.kt @@ -19,6 +19,4 @@ abstract class AbstractYouTubePlayerListener : YouTubePlayerListener { override fun onVideoDuration(youTubePlayer: YouTubePlayer, duration: Float) {} override fun onVideoLoadedFraction(youTubePlayer: YouTubePlayer, loadedFraction: Float) {} override fun onVideoId(youTubePlayer: YouTubePlayer, videoId: String) {} - override fun onShowCustomView(view: View?, callback: WebChromeClient.CustomViewCallback?) {} - override fun onHideCustomView() {} } diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/FullScreenListener.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/FullScreenListener.kt new file mode 100644 index 00000000..6b75b7de --- /dev/null +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/FullScreenListener.kt @@ -0,0 +1,31 @@ +package com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners + +import android.view.View + +/** + * Interface used to keep track of full screen events + */ +interface FullScreenListener { + /** + * Notify the host application that the player has entered full screen mode + * (the full screen button in the player UI has been clicked). + * After this call, the video will no longer be rendered in the [YouTubePlayerView], + * but will instead be rendered in [fullScreenView]. + * The host application should add this View to a container that fills the screen + * in order to actually display the video full screen. + * + * The application can explicitly exit fullscreen mode by invoking [exitFullScreen] + * (for example when the user presses the back button). + * However, the player will show its own UI to exist fullscreen. + * Regardless of how the player exits fullscreen mode, [onEnterFullScreen] will be invoked, + * signaling for the application to remove the custom View. + */ + fun onEnterFullScreen(fullScreenView: View, exitFullScreen: () -> Unit) + + /** + * Notify the host application that the player has exited full screen mode. + * The host application must hide the custom View (the View which was previously passed to + * [onEnterFullScreen]). After this call, the video will render in the player again. + */ + fun onExitFullScreen() +} \ No newline at end of file diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/YouTubePlayerListener.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/YouTubePlayerListener.kt index ff6e7ea4..0ed37f2b 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/YouTubePlayerListener.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/YouTubePlayerListener.kt @@ -62,16 +62,4 @@ interface YouTubePlayerListener { fun onVideoId(youTubePlayer: YouTubePlayer, videoId: String) fun onApiChange(youTubePlayer: YouTubePlayer) - - /** - * Called when current page has entered full screen mode. - * @param view is the View object to be shown. - * @param callback invoke this callback to request the page to exit full screen mode. - */ - fun onShowCustomView(view: View?, callback: WebChromeClient.CustomViewCallback?) - - /** - * Called when current page has exited full screen mode. - */ - fun onHideCustomView() } diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/options/IFramePlayerOptions.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/options/IFramePlayerOptions.kt index 6c9dcc57..e948e9f7 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/options/IFramePlayerOptions.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/options/IFramePlayerOptions.kt @@ -164,9 +164,9 @@ class IFramePlayerOptions private constructor(private val playerOptions: JSONObj /** * Setting this parameter to 0 prevents the fullscreen button from displaying in the player. * See original documentation for more info: https://developers.google.com/youtube/player_parameters#Parameters - * @param fs if set to 1: the player fullscreen button display. If set to 0: the player fullscreen button not display + * @param fs if set to 1: the player fullscreen button will be show. If set to 0: the player fullscreen button will not be shown. */ - fun fullScreen(fs: Int): Builder { + fun fullscreen(fs: Int): Builder { addInt(FS, fs) return this } diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/LegacyYouTubePlayerView.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/LegacyYouTubePlayerView.kt index a2f05729..065cdb8e 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/LegacyYouTubePlayerView.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/LegacyYouTubePlayerView.kt @@ -13,6 +13,7 @@ import androidx.lifecycle.OnLifecycleEvent 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.FullScreenListener import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.YouTubePlayerCallback import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.YouTubePlayerListener import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.options.IFramePlayerOptions @@ -23,13 +24,16 @@ import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.utils.Playbac * Legacy internal implementation of YouTubePlayerView. The user facing YouTubePlayerView delegates * most of its actions to this one. */ -internal class LegacyYouTubePlayerView(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0): - SixteenByNineFrameLayout(context, attrs, defStyleAttr), LifecycleObserver { +internal class LegacyYouTubePlayerView( + context: Context, + listener: FullScreenListener, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +): SixteenByNineFrameLayout(context, attrs, defStyleAttr), LifecycleObserver { - constructor(context: Context): this(context, null, 0) - constructor(context: Context, attrs: AttributeSet? = null): this(context, attrs, 0) + constructor(context: Context): this(context, FakeWebViewYouTubeListener,null, 0) - internal val youTubePlayer: WebViewYouTubePlayer = WebViewYouTubePlayer(context) + internal val youTubePlayer: WebViewYouTubePlayer = WebViewYouTubePlayer(context, listener) private val networkListener = NetworkListener() private val playbackResumer = PlaybackResumer() diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/WebViewYouTubePlayer.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/WebViewYouTubePlayer.kt index b00b13e0..a2d683a2 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/WebViewYouTubePlayer.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/WebViewYouTubePlayer.kt @@ -14,17 +14,33 @@ import com.pierfrancescosoffritti.androidyoutubeplayer.R import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayerBridge +import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.FullScreenListener import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.YouTubePlayerListener import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.options.IFramePlayerOptions import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.toFloat import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.utils.Utils import java.util.* + +internal object FakeWebViewYouTubeListener : FullScreenListener { + override fun onEnterFullScreen(fullScreenView: View, exitFullScreen: () -> Unit) { } + override fun onExitFullScreen() { } +} + /** * WebView implementation of [YouTubePlayer]. The player runs inside the WebView, using the IFrame Player API. */ -internal class WebViewYouTubePlayer constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) - : WebView(context, attrs, defStyleAttr), YouTubePlayer, YouTubePlayerBridge.YouTubePlayerBridgeCallbacks { +internal class WebViewYouTubePlayer constructor( + context: Context, + private val listener: FullScreenListener, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : WebView(context, attrs, defStyleAttr), + YouTubePlayer, + YouTubePlayerBridge.YouTubePlayerBridgeCallbacks { + + /** Constructor used by tools */ + constructor(context: Context) : this(context, FakeWebViewYouTubeListener) private lateinit var youTubePlayerInitListener: (YouTubePlayer) -> Unit @@ -115,18 +131,14 @@ internal class WebViewYouTubePlayer constructor(context: Context, attrs: Attribu // if the video's thumbnail is not in memory, show a black screen webChromeClient = object : WebChromeClient() { - override fun onShowCustomView(view: View?, callback: CustomViewCallback?) { + override fun onShowCustomView(view: View, callback: CustomViewCallback) { super.onShowCustomView(view, callback) - youTubePlayerListeners.forEach { - it.onShowCustomView(view = view, callback = callback) - } + listener.onEnterFullScreen(view) { callback.onCustomViewHidden() } } override fun onHideCustomView() { super.onHideCustomView() - youTubePlayerListeners.forEach { - it.onHideCustomView() - } + listener.onExitFullScreen() } override fun getDefaultVideoPoster(): Bitmap? { diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/YouTubePlayerView.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/YouTubePlayerView.kt index 3f66919d..468cd07c 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/YouTubePlayerView.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/YouTubePlayerView.kt @@ -4,6 +4,8 @@ import android.content.Context import android.util.AttributeSet import android.view.View import android.view.ViewGroup +import android.view.ViewGroup.LayoutParams +import android.widget.FrameLayout import androidx.annotation.LayoutRes import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleObserver @@ -13,22 +15,50 @@ 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.listeners.YouTubePlayerListener +import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.* import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.options.IFramePlayerOptions import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.utils.loadOrCueVideo -class YouTubePlayerView(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0): - SixteenByNineFrameLayout(context, attrs, defStyleAttr), LifecycleObserver { +private val matchParent get() = FrameLayout.LayoutParams( + LayoutParams.MATCH_PARENT, + LayoutParams.MATCH_PARENT +) + +class YouTubePlayerView( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : SixteenByNineFrameLayout(context, attrs, defStyleAttr), LifecycleObserver { constructor(context: Context): this(context, null, 0) constructor(context: Context, attrs: AttributeSet? = null): this(context, attrs, 0) - private val legacyTubePlayerView: LegacyYouTubePlayerView = LegacyYouTubePlayerView(context) + private val fullScreenListeners = mutableListOf() + + /** + * A single [FullScreenListener] that is always added to the WebView, + * responsible for calling all optional listeners added from clients of the library. + */ + private val webViewFullScreenListener = object : FullScreenListener { + override fun onEnterFullScreen(fullScreenView: View, exitFullScreen: () -> Unit) { + fullScreenListeners.forEach { it.onEnterFullScreen(fullScreenView, exitFullScreen) } + } + + override fun onExitFullScreen() { + fullScreenListeners.forEach { it.onExitFullScreen() } + } + } + + private val legacyTubePlayerView = LegacyYouTubePlayerView( + context, + webViewFullScreenListener + ) // this is a publicly accessible API var enableAutomaticInitialization: Boolean init { - addView(legacyTubePlayerView, LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)) + addView(legacyTubePlayerView, matchParent) val typedArray = context.theme.obtainStyledAttributes(attrs, R.styleable.YouTubePlayerView, 0, 0) @@ -145,6 +175,10 @@ class YouTubePlayerView(context: Context, attrs: AttributeSet? = null, defStyleA fun removeYouTubePlayerListener(youTubePlayerListener: YouTubePlayerListener) = legacyTubePlayerView.youTubePlayer.removeListener(youTubePlayerListener) + fun addFullScreenListener(fullScreenListener: FullScreenListener) = fullScreenListeners.add(fullScreenListener) + + fun removeFullScreenListener(fullScreenListener: FullScreenListener) = fullScreenListeners.remove(fullScreenListener) + /** * Convenience method to set the [YouTubePlayerView] width and height to match parent. */ diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/utils/FadeViewHelper.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/utils/FadeViewHelper.kt index c1966a09..af98bbc5 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/utils/FadeViewHelper.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/utils/FadeViewHelper.kt @@ -105,6 +105,4 @@ class FadeViewHelper(val targetView: View): YouTubePlayerListener { override fun onVideoDuration(youTubePlayer: YouTubePlayer, duration: Float) { } override fun onVideoLoadedFraction(youTubePlayer: YouTubePlayer, loadedFraction: Float) { } override fun onVideoId(youTubePlayer: YouTubePlayer, videoId: String) { } - override fun onShowCustomView(view: View?, callback: WebChromeClient.CustomViewCallback?) { } - override fun onHideCustomView() { } } \ No newline at end of file diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/views/YouTubePlayerSeekBar.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/views/YouTubePlayerSeekBar.kt index 4bf8c679..1ad56bea 100644 --- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/views/YouTubePlayerSeekBar.kt +++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/views/YouTubePlayerSeekBar.kt @@ -152,8 +152,6 @@ class YouTubePlayerSeekBar(context: Context, attrs: AttributeSet? = null): Linea override fun onPlaybackQualityChange(youTubePlayer: YouTubePlayer, playbackQuality: PlayerConstants.PlaybackQuality) { } override fun onPlaybackRateChange(youTubePlayer: YouTubePlayer, playbackRate: PlayerConstants.PlaybackRate) { } override fun onError(youTubePlayer: YouTubePlayer, error: PlayerConstants.PlayerError) { } - override fun onShowCustomView(view: View?, callback: WebChromeClient.CustomViewCallback?) { } - override fun onHideCustomView() { } } interface YouTubePlayerSeekBarListener { From 1a3fcee276a1c5582d5c71e7e6253c0515f6ff61 Mon Sep 17 00:00:00 2001 From: Pierfrancesco Soffritti Date: Tue, 14 Mar 2023 07:38:23 +0000 Subject: [PATCH 16/16] Rename example Activity to FullscreenExampleActivity --- core-sample-app/src/main/AndroidManifest.xml | 4 ++-- .../core/sampleapp/MainActivity.java | 4 ++-- .../FullscreenExampleActivity.java} | 18 +++++++++++------- ...ple.xml => activity_fullscreen_example.xml} | 4 ++-- .../src/main/res/values/strings.xml | 2 +- 5 files changed, 18 insertions(+), 14 deletions(-) rename core-sample-app/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/sampleapp/examples/{simpleFullscreenExample/SimpleFullscreenExampleActivity.java => fullscreenExample/FullscreenExampleActivity.java} (84%) rename core-sample-app/src/main/res/layout/{activity_simple_fullscreen_example.xml => activity_fullscreen_example.xml} (91%) diff --git a/core-sample-app/src/main/AndroidManifest.xml b/core-sample-app/src/main/AndroidManifest.xml index d2dd4222..c0e1f76b 100644 --- a/core-sample-app/src/main/AndroidManifest.xml +++ b/core-sample-app/src/main/AndroidManifest.xml @@ -86,10 +86,10 @@ android:hardwareAccelerated="true" android:label="@string/simple_example" /> + android:label="@string/fullscreen_example" /> exitFullScreen) { - // for display full screen landscape view + // the video will continue playing in fullScreenView youTubePlayerView.setVisibility(View.GONE); fullScreenViewContainer.setVisibility(View.VISIBLE); fullScreenViewContainer.addView(fullScreenView); + // optionally request landscape orientation setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } @Override public void onExitFullScreen() { + // the video will continue playing in the player youTubePlayerView.setVisibility(View.VISIBLE); fullScreenViewContainer.setVisibility(View.GONE); fullScreenViewContainer.removeAllViews(); diff --git a/core-sample-app/src/main/res/layout/activity_simple_fullscreen_example.xml b/core-sample-app/src/main/res/layout/activity_fullscreen_example.xml similarity index 91% rename from core-sample-app/src/main/res/layout/activity_simple_fullscreen_example.xml rename to core-sample-app/src/main/res/layout/activity_fullscreen_example.xml index d1f7a1b4..3f799e5b 100644 --- a/core-sample-app/src/main/res/layout/activity_simple_fullscreen_example.xml +++ b/core-sample-app/src/main/res/layout/activity_fullscreen_example.xml @@ -14,8 +14,8 @@ ayp API Simple example - Simple Fullscreen example + Fullscreen example Complete example RecyclerView example Custom UI example