Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to hide or handle "add watch later" and "share" buttons in top of the player view #242

Closed
takuya-kikuchi opened this issue Oct 30, 2018 · 14 comments

Comments

@takuya-kikuchi
Copy link

As mentions above, "add watch later" button and "share" button are appearing on top of the player view when playing a video is starting or pausing.

image

And unfortunately, these buttons seem to be respond nothing when clicked...

Are there any way to handle or remove these buttons?

Thanks.

@PierfrancescoSoffritti
Copy link
Owner

Hi, this issue is related to #228 and #226.
Unfortunately YouTube has recently updated their web player. The options that I was using to hide that part of the player's UI is now being ignored.

In the next version of the library I will try to handle this new buttons, by making them clickable. For the moment you could overcome the problem by creating your own custom ui in such a way that those buttons are clickable.

@takuya-kikuchi
Copy link
Author

Thanks for your response!

Ok, I will try it.
Best regards.

@trademunch
Copy link

@PierfrancescoSoffritti original youtube api has share icon and more videos options but those are atleast clickable. is there any callback that we can get for these methods to make them work if it cant be removed?
Also the original youtube player doesn't have watch later option.
Please help.

@PierfrancescoSoffritti
Copy link
Owner

Hi, I haven't made any change on this yet, because it seems like the IFrame API doesn't expose any hooks for intercepting clicks on those buttons.

As suggested in my previous post, at the moment the best way to make those buttons clickable is to disable the android-youtube-player native UI and enable the IFrame player web Ui. Example provided in the sample app.

Repository owner deleted a comment from trademunch Jan 27, 2019
@trademunch
Copy link

@PierfrancescoSoffritti iFrame sample doesn't have full screen button for user to enter or exit full screen.
this method throws an exception:
youTubePlayerView.getPlayerUIController().showFullscreenButton(true);

Caused by: java.lang.RuntimeException: You have inflated a custom player UI. You must manage it with your own controller.

How can we create our own custom UI to add full screen button to app?

@PierfrancescoSoffritti
Copy link
Owner

As explained in the documentation, when you're using a custom ui you need to use your own ui controller. If you try to use the default ui controller it will throw an exception.
The sample app has an example for custom UIs, you can refer to that example.

@trademunch
Copy link

trademunch commented Feb 1, 2019

I have made the following changes to handle add watch later button, share button and More videos button that appear inside the player.

File name: DefaultPlayerUIController.java

Comment the following line:
panel.setOnClickListener(this);

After commenting this, the buttons will start to work. but on video tap, you will not be able to see the bottom progress bar once it has disappeared.

To handle it, inside onStateChange method in the DefaultPlayerUIController.java file
update the playing check with the following and it should work.
if (playing) { startFadeOutViewTimer(); } else { toggleControlsVisibility(); handler.removeCallbacks(fadeOutRunnable); }

So whenever the state would changed to false, the player controls will again be visible.

From the default_player_ui.xml file:

remove the following lines from the view with id: panel

android:clickable="true"
android:focusable="true" 

@PierfrancescoSoffritti
Copy link
Owner

Hi, this solution gives a significant side effect: the behavior of the web UI is exposed, and every time the player is touched the playback is toggled. The native UI is shown only when the video gets paused.

Using both native and web UI doesn't work well in this case. It doesn't result in a very good user experience, I think the result for the user is worse compared to the current behavior of the library.

I suggest following one of the two approaches I mentioned earlier:

  1. if you want to use both native and web UI you should create a custom UI to replace the default native UI and default UI controller of the player.
  2. if you don't care about having native UI you can just disable the native UI and use only the web UI.

@PierfrancescoSoffritti
Copy link
Owner

PierfrancescoSoffritti commented Feb 8, 2019

Starting from version 10.0.0 it will be possible to initialize the player using YouTubePlayerView.initializeWithWebUI.

This is the only way to have access to the non-removable buttons in the web player. Read the doc for more info.

@trademunch
Copy link

@PierfrancescoSoffritti When will version 10.0.0 be out? Really need to handle this.

@PierfrancescoSoffritti
Copy link
Owner

PierfrancescoSoffritti commented Feb 8, 2019

A couple of days.

But it isn't doing anything more than what I have already explained in previous comments. It's just more straightforward.

You can copy paste this and obtain the same thing with version 9.0.1.

@Fiddl3
Copy link

Fiddl3 commented Nov 16, 2021

We can remove these buttons using shouldInterceptRequest.
We can inject css code in to www-player.css by intercepting request

sample example (not bulletproof) (from onCreate()):

mYouTubePlayerView.getYouTubePlayerWhenReady(new YouTubePlayerCallback() {
            @Override
            public void onYouTubePlayer(@NonNull YouTubePlayer youTubePlayer) {

                WebView player = (WebView) youTubePlayer;

                player.clearCache(true); //we will need to reload www-player.css later
                player.setWebViewClient(new WebViewClient() {

            private int loadCount;
            private boolean injected;

            @Override
            public WebResourceResponse shouldInterceptRequest (final WebView view, WebResourceRequest wrr) {

                String url = wrr.getUrl().toString();
                if(url.contains("youtube.com") && url.contains("www-player.css") ) { // find iframe player css file
                    WebResourceResponse resp = doInject(url);
                    if (resp != null) {
                        injected = true;
                        return resp;
                    }
                }
                return super.shouldInterceptRequest(view, wrr);
            }
            @Override
            public void onPageFinished(WebView view, String url) {
                if(!injected && loadCount++ <3) // prevent loop
                    view.reload(); // we need reload because we set WebViewClient
                                   // after WebView started loading the iframe
                                   // only once
            }

            private WebResourceResponse doInject(String url){
                try {
                    Request request = new Request.Builder()
                            .url(url)
                            .build();

                    Response response =
                            new OkHttpClient()
                            .newCall(request)
                            .execute();

                    // inject code that hides the buttons
                    assert response.body() != null;
                    String fin = response
                            .body()
                            .string()
                            +" .ytp-chrome-top-buttons {display: none !important;}"; 

                    return new WebResourceResponse(
                            "text/css",
                            "UTF-8",
                            new ByteArrayInputStream(fin.getBytes())
                    );
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return null;
            }
        });
            }
        });

We can inject any type of code in any file, but css is the fastest way to get desired effect

to hide whole titlebar inject css:

.ytp-chrome-top {display: none !important;}

instead of

.ytp-chrome-top-buttons {display: none !important;}

this solutin will work as long as the iframe player design remains unchanged

@kreativeteksolutions
Copy link

kreativeteksolutions commented Dec 3, 2021

We can remove these buttons using shouldInterceptRequest. We can inject css code in to www-player.css by intercepting request

sample example (not bulletproof) (from onCreate()):

mYouTubePlayerView.getYouTubePlayerWhenReady(new YouTubePlayerCallback() {
            @Override
            public void onYouTubePlayer(@NonNull YouTubePlayer youTubePlayer) {

                WebView player = (WebView) youTubePlayer;

                player.clearCache(true); //we will need to reload www-player.css later
                player.setWebViewClient(new WebViewClient() {

            private int loadCount;
            private boolean injected;

            @Override
            public WebResourceResponse shouldInterceptRequest (final WebView view, WebResourceRequest wrr) {

                String url = wrr.getUrl().toString();
                if(url.contains("youtube.com") && url.contains("www-player.css") ) { // find iframe player css file
                    WebResourceResponse resp = doInject(url);
                    if (resp != null) {
                        injected = true;
                        return resp;
                    }
                }
                return super.shouldInterceptRequest(view, wrr);
            }
            @Override
            public void onPageFinished(WebView view, String url) {
                if(!injected && loadCount++ <3) // prevent loop
                    view.reload(); // we need reload because we set WebViewClient
                                   // after WebView started loading the iframe
                                   // only once
            }

            private WebResourceResponse doInject(String url){
                try {
                    Request request = new Request.Builder()
                            .url(url)
                            .build();

                    Response response =
                            new OkHttpClient()
                            .newCall(request)
                            .execute();

                    // inject code that hides the buttons
                    assert response.body() != null;
                    String fin = response
                            .body()
                            .string()
                            +" .ytp-chrome-top-buttons {display: none !important;}"; 

                    return new WebResourceResponse(
                            "text/css",
                            "UTF-8",
                            new ByteArrayInputStream(fin.getBytes())
                    );
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return null;
            }
        });
            }
        });

We can inject any type of code in any file, but css is the fastest way to get desired effect

to hide whole titlebar inject css:

.ytp-chrome-top {display: none !important;}

instead of

.ytp-chrome-top-buttons {display: none !important;}

this solutin will work as long as the iframe player design remains unchanged

I was trying to use this method but for whatever reason It isn't working for me… Mind pointing out what I am doing wrong, I am attaching my implementation below… Thank you in advance.

youTubePlayerView.getYouTubePlayerWhenReady(youTubePlayer -> {
            youTubePlayer.loadVideo(getVideoId(getIntent().getStringExtra("youtubeLink")),0);
            yPlayer = youTubePlayer;

            WebView player =(WebView) youTubePlayer;

            player.clearCache(true);
            player.setWebViewClient(new WebViewClient(){
                private int loadCount;
                private boolean injected;

                @Override
                public WebResourceResponse shouldInterceptRequest (final WebView view, WebResourceRequest wrr) {

                    String url = wrr.getUrl().toString();
                    if(url.contains("youtube.com") && url.contains("www-player.css") ) { // find iframe player css file
                        WebResourceResponse resp = doInject(url);
                        if (resp != null) {
                            injected = true;
                            return resp;
                        }
                    }
                    return super.shouldInterceptRequest(view, wrr);
                }
                @Override
                public void onPageFinished(WebView view, String url) {
                    if(!injected && loadCount++ <3) // prevent loop
                        view.reload(); // we need reload because we set WebViewClient
                    // after WebView started loading the iframe
                    // only once
                }

                private WebResourceResponse doInject(String url){
                    try {
                        Request request = new Request.Builder()
                                .url(url)
                                .build();

                        Response response =
                                new OkHttpClient()
                                        .newCall(request)
                                        .execute();

                        // inject code that hides the buttons
                        assert response.body() != null;
                        String fin = response
                                .body()
                                .string()
                                +" .ytp-chrome-top-buttons  {display: none !important;}  ";

                        return new WebResourceResponse(
                                "text/css",
                                "UTF-8",
                                new ByteArrayInputStream(fin.getBytes())
                        );
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    return null;
                }
            });

        });

This is the log I am receiving…

2021-12-01 21:54:04.362 20578-20609/com.example.appD/EGL_emulation: eglMakeCurrent: 0xf6e7f2e0: ver 2 0 (tinfo 0xe0687ce0)
2021-12-01 21:54:04.790 20578-20578/com.example.appI/chromium: [INFO:CONSOLE(916)] "Unrecognized feature: 'clipboard-write'.", source: https://www.youtube.com/s/player/54223c10/www-widgetapi.vflset/www-widgetapi.js (916)
2021-12-01 21:54:04.790 20578-20578/com.example.appI/chromium: [INFO:CONSOLE(916)] "Unrecognized feature: 'picture-in-picture'.", source: https://www.youtube.com/s/player/54223c10/www-widgetapi.vflset/www-widgetapi.js (916)
2021-12-01 21:54:05.793 20578-20578/com.example.appD/playerState: UNSTARTED
2021-12-01 21:54:05.823 20578-20578/com.example.appD/playerState: BUFFERING
2021-12-01 21:54:06.023 20578-20578/com.example.appI/chromium: [INFO:CONSOLE(916)] "Unrecognized feature: 'clipboard-write'.", source: https://www.youtube.com/s/player/54223c10/www-widgetapi.vflset/www-widgetapi.js (916)
2021-12-01 21:54:06.023 20578-20578/com.example.appI/chromium: [INFO:CONSOLE(916)] "Unrecognized feature: 'picture-in-picture'.", source: https://www.youtube.com/s/player/54223c10/www-widgetapi.vflset/www-widgetapi.js (916)
2021-12-01 21:54:19.058 20578-20578/com.example.appD/playerState: UNSTARTED

This is the error I get after I press play:
image

Finally, this is the YouTube link I am using as a test

https://www.youtube.com/watch?v=-ezfi6FQ8Ds

@GauravMeghanathiWeDoApps

How can we hide share button on youtubePlayer? is there any method so pls let me know i want to just hide share button

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants