Android WebView with an embedded youtube video, full screen button freezes video

后端 未结 3 1154
陌清茗
陌清茗 2020-11-29 04:54

I have an android webview that loads a wordpress blog. Some blog posts contain youtube videos which I would like the user to be able to make full screen if they wish. The pr

相关标签:
3条回答
  • 2020-11-29 05:09

    This is something I've spent the last day or so tearing my hair out over. Based on various bits of code from around the web I've managed to get it working.

    First, you need to create a custom WebChromeClient class, which implements the onShowCustomView and onHideCustomView methods.

    private class MyWebChromeClient extends WebChromeClient {
        FrameLayout.LayoutParams LayoutParameters = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
                FrameLayout.LayoutParams.MATCH_PARENT);
    
        @Override
        public void onShowCustomView(View view, CustomViewCallback callback) {
            // if a view already exists then immediately terminate the new one
            if (mCustomView != null) {
                callback.onCustomViewHidden();
                return;
            }
            mContentView = (RelativeLayout) findViewById(R.id.activity_main);
            mContentView.setVisibility(View.GONE);
            mCustomViewContainer = new FrameLayout(MainActivity.this);
            mCustomViewContainer.setLayoutParams(LayoutParameters);
            mCustomViewContainer.setBackgroundResource(android.R.color.black);
            view.setLayoutParams(LayoutParameters);
            mCustomViewContainer.addView(view);
            mCustomView = view;
            mCustomViewCallback = callback;
            mCustomViewContainer.setVisibility(View.VISIBLE);
            setContentView(mCustomViewContainer);
        }
    
        @Override
        public void onHideCustomView() {
            if (mCustomView == null) {
                return;
            } else {
                // Hide the custom view.  
                mCustomView.setVisibility(View.GONE);
                // Remove the custom view from its container.  
                mCustomViewContainer.removeView(mCustomView);
                mCustomView = null;
                mCustomViewContainer.setVisibility(View.GONE);
                mCustomViewCallback.onCustomViewHidden();
                // Show the content view.  
                mContentView.setVisibility(View.VISIBLE);
                setContentView(mContentView);
            }
        }
    }
    

    Basically, what is happening here is when the full screen button gets pressed, we're creating a new view to hold the video and hiding the main view. And then when full screen is closed, we do the opposite - get rid of the new view and display the original view.

    You'll need to also add all those properties to your activity class:

    private MyWebChromeClient mWebChromeClient = null;
    private View mCustomView;
    private RelativeLayout mContentView;
    private FrameLayout mCustomViewContainer;
    private WebChromeClient.CustomViewCallback mCustomViewCallback;
    

    And you probably want to make it close the fullscreen video when the back button is pressed:

    @Override
    public void onBackPressed() {
        if (mCustomViewContainer != null)
            mWebChromeClient.onHideCustomView();
        else if (myWebView.canGoBack())
            myWebView.goBack();
        else
            super.onBackPressed();
    }
    

    Then it's just a matter of using your new class when you create your webview:

    myWebView = (WebView) findViewById(R.id.webView1);
    mWebChromeClient = new WMWebChromeClient();
    myWebView.setWebChromeClient(mWebChromeClient);
    

    This works for me on Android 4.x. Not sure about earlier versions as my app isn't targeting them.

    I found these links particularly useful: WebView and HTML5 <video> and http://code.google.com/p/html5webview/source/browse/trunk/HTML5WebView/src/org/itri/html5webview/HTML5WebView.java

    0 讨论(0)
  • 2020-11-29 05:20

    You can start an external YouTube app when you will cath video info URLif it is not important to show YouTube video directly in application.

    To catch video info URL You need to owerride onLoadResource method:

    new WebViewClient() {
    
        @Override
        public void onLoadResource(WebView view, String url) {
    
            if (url.startsWith("http://www.youtube.com/get_video_info?")) {
                try {
                    String path = url.replace("http://www.youtube.com/get_video_info?", "");
    
                    String[] parqamValuePairs = path.split("&");
    
                    String videoId = null;
    
                    for (String pair : parqamValuePairs) {
                        if (pair.startsWith("video_id")) {
                            videoId = pair.split("=")[1];
                            break;
                        }
                    }
    
                    if(videoId != null){
                        startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.youtube.com"))
                                .setData(Uri.parse("http://www.youtube.com/watch?v=" + videoId)));
                        needRefresh = true;
    
                        return;
                    }
                } catch (Exception ex) {
                }
            } else {
                super.onLoadResource(view, url);
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-29 05:24

    Thanks to @Mark Parnell for his response, but he is doing it in hard way with heavy UI changes, maybe this way is cleaner and more understandable:

    When fullscreen button clicked, chrome client gives us fullscreen view and then we should add it to our activity view :

    Define this variable global to hold fullscreen view reference in our activity:

    public class MyAmazingActivity extends AppCompatActivity {
        private View fullscreenView;
        //...
    }
    

    Then web chrome client will notify us about showing and hiding fullscreen view in onShowCustomView and onHideCustomView methods:

    WebChromeClient webChromeClient = new WebChromeClient() {
    
                private ViewGroup rootView;
                private WebChromeClient.CustomViewCallback customViewCallback;
    
                @Override
                public void onShowCustomView(View view, CustomViewCallback callback) {
    
                    //Destroy full screen view if already exists
                    if (fullscreenView != null) {
                        callback.onCustomViewHidden();
                        return;
                    }
    
                    //Layout params to fit fullscreen view in our activity
                    ViewGroup.LayoutParams layoutParams = 
                            new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                                    ViewGroup.LayoutParams.MATCH_PARENT);
                    //Catch root of current activity to add fullscreen view
                    rootView = (ViewGroup) WebViewBaseActivity.this.webView.getRootView();
                    
                    //Store full screen view, we need it to destroy it out of scope
                    fullscreenView = view;
    
                    customViewCallback = callback;
                    rootView.addView(fullscreenView, layoutParams);
                }
    
                @Override
                public void onHideCustomView() {
                    //Make sure fullscreen view exists
                    if (fullscreenView != null) {
                        
                        //Remove fullscreen view from activity root view
                        rootView.removeView(fullscreenView);
                        fullscreenView = null;
    
                        //Tell browser we did remove fullscreen view
                        customViewCallback.onCustomViewHidden();
                    }
                }
    
            };
    

    And finally removing fullscreen view when back pressed(User expects this behaviour):

    @Override
    public void onBackPressed() {
        if (fullscreenView != null) {
            webChromeClient.onHideCustomView();
        }
    }       
    
    0 讨论(0)
提交回复
热议问题