在 WebView 中加载 YouTube 视频时,全屏选项不可用

Posted

技术标签:

【中文标题】在 WebView 中加载 YouTube 视频时,全屏选项不可用【英文标题】:Full screen option not available when loading YouTube video in WebView 【发布时间】:2016-07-16 11:27:13 【问题描述】:

我在 android 应用程序中使用 webview 工作了很多时间。但是这次我在将 YouTube 视频加载到 WebView 时遇到了奇怪的问题。

看,这是在 Chrome 浏览器中加载的 YouTube 视频的屏幕截图,其中包含全屏选项。

现在,下面是我在 webview 中加载相同视频的应用程序的屏幕截图。但它没有那个全屏选项。

您可以看到两个图像的变化。两个屏幕截图均来自同一设备。但看起来还是不一样。

我的 webView 加载代码是in this pasteboard。

更新

我也看到同样的问题是reported here。但不知道是否有可用的解决方案。

【问题讨论】:

【参考方案1】:

在您的 java 文件中进行以下更改:

view.setWebViewClient(new Browser());
view.setWebChromeClient(new MyWebClient());

在java文件中添加Browser类和MyWebClient这2个类

class Browser
        extends WebViewClient

    Browser() 

    public boolean shouldOverrideUrlLoading(WebView paramWebView, String paramString)
    
        paramWebView.loadUrl(paramString);
        return true;
    


public class MyWebClient
        extends WebChromeClient

    private View mCustomView;
    private WebChromeClient.CustomViewCallback mCustomViewCallback;
    protected FrameLayout mFullscreenContainer;
    private int mOriginalOrientation;
    private int mOriginalSystemUiVisibility;

    public MyWebClient() 

    public Bitmap getDefaultVideoPoster()
    
        if (MainActivity.this == null) 
            return null;
        
        return BitmapFactory.decodeResource(MainActivity.this.getApplicationContext().getResources(), 2130837573);
    

    public void onHideCustomView()
    
        ((FrameLayout)MainActivity.this.getWindow().getDecorView()).removeView(this.mCustomView);
        this.mCustomView = null;
        MainActivity.this.getWindow().getDecorView().setSystemUiVisibility(this.mOriginalSystemUiVisibility);
        MainActivity.this.setRequestedOrientation(this.mOriginalOrientation);
        this.mCustomViewCallback.onCustomViewHidden();
        this.mCustomViewCallback = null;
    

    public void onShowCustomView(View paramView, WebChromeClient.CustomViewCallback paramCustomViewCallback)
    
        if (this.mCustomView != null)
        
            onHideCustomView();
            return;
        
        this.mCustomView = paramView;
        this.mOriginalSystemUiVisibility = MainActivity.this.getWindow().getDecorView().getSystemUiVisibility();
        this.mOriginalOrientation = MainActivity.this.getRequestedOrientation();
        this.mCustomViewCallback = paramCustomViewCallback;
        ((FrameLayout)MainActivity.this.getWindow().getDecorView()).addView(this.mCustomView, new FrameLayout.LayoutParams(-1, -1));
        MainActivity.this.getWindow().getDecorView().setSystemUiVisibility(3846);
    

【讨论】:

想知道为什么这个答案没有得到任何支持,但这确实有效。只有一个错误,“actionBar”向下移动。还在想办法解决。感谢这个答案顺便说一句 @WideFide 你找到 actionBar 的解决方案了吗?我也遇到了同样的问题 有问题但有效的解决方案。那些 id 真的必须是无名的吗? @WideFide 你能告诉我我需要在哪里添加以上两个类吗?它在单独的文件中吗?如果是,那么 MainActivity 是类? 为什么这个答案不正确。这对我来说很好。【参考方案2】:

iFrame 是一个选项,但你可以试试这个

Android 的 WebView 和 WebChromeClient 类扩展可以启用 完整的 html5 视频支持

VideoEnabledWebView

我还没有尝试过,但希望对你有所帮助。

【讨论】:

真正成就了我的一天......过去 10 天一直在寻找类似的东西,谢谢@M D【参考方案3】:

如果我理解正确,您有一个包含第二个 iframe(youtube 的 iframe)的 iframe。 尝试将 allowfullscreen 属性添加到“父”iframe。

要获得完整的浏览器支持,它应该如下所示:

<iframe src="your_page_url" allowfullscreen="allowfullscreen" mozallowfullscreen="mozallowfullscreen" msallowfullscreen="msallowfullscreen" oallowfullscreen="oallowfullscreen" webkitallowfullscreen="webkitallowfullscreen"> </iframe>

【讨论】:

我直接将 url 加载到 webview 中。我没有在其中附加任何 iframe 标记。所以如果我追加它,它会工作吗? 是的。请尝试,或者您可以做一件事。将此参数附加到 youtube url ?allowfullscreen=true 我已经尝试过你的方法。我正在以这种方式加载视频,但它没有加载视频。 mWebView.loadUrl(""); 我在 logcat 中遇到如下错误:拒绝加载无效 URL:%3Ciframe%20src%3D%27https://www.youtube.com/watch?v=zxyauCOc5gs'allowfullscreen='allowfullscreen' mozallowfullscreen='mozallowfullscreen' msallowfullscreen='msallowfullscreen' oallowfullscreen='oallowfullscreen' webkitallowfullscreen='webkitallowfullscreen'> 03【参考方案4】:

Kotlin 上@Ameya Bonkinpelliwar 的答案

class WebChrome(activity: Activity) : WebChromeClient() 

    private val activityRef = WeakReference(activity)

    private var customView: View? = null
    private var customViewCallback: CustomViewCallback? = null

    private var originalOrientation = 0
    private var originalSystemUiVisibility = 0

    override fun onProgressChanged(view: WebView, progress: Int) 
        view.context.activityCallback<MainActivity> 
            onProgress(progress)
        
    

    override fun getDefaultVideoPoster(): Bitmap? 
        return activityRef.get()?.run 
            BitmapFactory.decodeResource(applicationContext.resources, 2130837573)
        
    

    override fun onHideCustomView() 
        activityRef.get()?.run 
            (window.decorView as ViewGroup).removeView(customView)
            customView = null
            window.decorView.systemUiVisibility = originalSystemUiVisibility
            requestedOrientation = originalOrientation
        
        customViewCallback?.onCustomViewHidden()
        customViewCallback = null
    

    override fun onShowCustomView(view: View?, viewCallback: CustomViewCallback?) 
        if (customView != null) 
            onHideCustomView()
            return
        
        customView = view
        activityRef.get()?.run 
            originalSystemUiVisibility = window.decorView.systemUiVisibility
            originalOrientation = requestedOrientation
            customViewCallback = viewCallback
            (window.decorView as ViewGroup).addView(
                customView,
                ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT
                )
            )
            window.decorView.systemUiVisibility = 3846
        
    

【讨论】:

【参考方案5】:
//Add WebChromeClient to your webview 
//With navigation option and player controls overlapping handlled.

    class UriChromeClient extends WebChromeClient 
            private View mCustomView;
            private WebChromeClient.CustomViewCallback mCustomViewCallback;
            protected FrameLayout mFullscreenContainer;
            private int mOriginalOrientation;
            private int mOriginalSystemUiVisibility;

            @SuppressLint("SetjavascriptEnabled")
            @Override
            public boolean onCreateWindow(WebView view, boolean isDialog,
                                          boolean isUserGesture, Message resultMsg) 
                mWebviewPop = new WebView(getApplicationContext());
                mWebviewPop.setVerticalScrollBarEnabled(false);
                mWebviewPop.setHorizontalScrollBarEnabled(false);
                mWebviewPop.setWebViewClient(new MyWebViewClient());
                mWebviewPop.getSettings().setSupportMultipleWindows(true);
                mWebviewPop.getSettings().setJavaScriptEnabled(true);
                mWebviewPop.getSettings().setUserAgentString(mWebviewPop.getSettings().getUserAgentString().replace("; wv", ""));
    //            mWebviewPop.getSettings().setUserAgentString(USER_AGENT);
                mWebviewPop.getSettings().setSaveFormData(true);
                mWebviewPop.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.MATCH_PARENT));
                mContainer.addView(mWebviewPop);
                WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
                transport.setWebView(mWebviewPop);
                resultMsg.sendToTarget();

                return true;
            

            @Override
            public void onCloseWindow(WebView window) 
                Log.d("onCloseWindow", "called");
            

            //
            public Bitmap getDefaultVideoPoster() 
                if (mCustomView == null) 
                    return null;
                
                return BitmapFactory.decodeResource(getApplicationContext().getResources(), 2130837573);
            

            public void onHideCustomView() 
                ((FrameLayout) getWindow().getDecorView()).removeView(this.mCustomView);
                this.mCustomView = null;
                getWindow().getDecorView().setSystemUiVisibility(this.mOriginalSystemUiVisibility);
                setRequestedOrientation(this.mOriginalOrientation);
                this.mCustomViewCallback.onCustomViewHidden();
                this.mCustomViewCallback = null;
            

            public void onShowCustomView(View paramView, WebChromeClient.CustomViewCallback paramCustomViewCallback) 
                if (this.mCustomView != null) 
                    onHideCustomView();
                    return;
                
                this.mCustomView = paramView;
                this.mCustomView.setBackgroundColor(Color.BLACK);
                this.mOriginalSystemUiVisibility = getWindow().getDecorView().getSystemUiVisibility();
                this.mOriginalOrientation = getRequestedOrientation();
                this.mCustomViewCallback = paramCustomViewCallback;
                ((FrameLayout) getWindow().getDecorView()).addView(this.mCustomView, new FrameLayout.LayoutParams(-1, -1));
                getWindow().getDecorView().setSystemUiVisibility(3846);

                this.mCustomView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() 
                    @Override
                    public void onSystemUiVisibilityChange(int visibility) 
                        if ((visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) 
                            updateControls(getNavigationBarHeight());
                         else 
                            updateControls(0);
                        

                    
                );

            

            void updateControls(int bottomMargin) 
                FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) this.mCustomView.getLayoutParams();
                params.bottomMargin = bottomMargin;
                this.mCustomView.setLayoutParams(params);
            
        

        int getNavigationBarHeight() 
            Resources resources = getResources();
            int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
            if (resourceId > 0) 
                return resources.getDimensionPixelSize(resourceId);
            
            return 0;
        


        private void loadURL(WebView view, String url) 
            ConnectivityManager cm = (ConnectivityManager) getApplication().getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo netInfo = cm.getActiveNetworkInfo();
            if (netInfo != null && netInfo.isConnected()) 
                view.setVisibility(View.VISIBLE);
                noNetworkText.setVisibility(View.GONE);
                view.loadUrl(url);

             else 
                Log.d(TAG, "loadURL: no network");
                view.setVisibility(View.INVISIBLE);
                noNetworkText.setVisibility(View.VISIBLE);
            
        

    

【讨论】:

欢迎来到***。除了您提供的答案之外,请考虑提供一个简短说明,说明为什么以及如何解决此问题。

以上是关于在 WebView 中加载 YouTube 视频时,全屏选项不可用的主要内容,如果未能解决你的问题,请参考以下文章

在 webview 中加载 flv 视频的问题

无法在 Fancybox 中加载 YouTube 视频 - 空白页

Chrome 扩展程序未在 YouTube 的浏览器导航中加载

Android:如何在 WebView 中加载 html 字符串?

Android WebView 混合内容未在 api 级别 < 21 中加载

如何使用 Youtube API 在 RecyclerView 中加载 Youtube 缩略图