带有嵌入式 youtube 视频的 Android WebView,全屏按钮冻结视频

Posted

技术标签:

【中文标题】带有嵌入式 youtube 视频的 Android WebView,全屏按钮冻结视频【英文标题】:Android WebView with an embedded youtube video, full screen button freezes video 【发布时间】:2013-01-23 16:22:51 【问题描述】:

我有一个加载 wordpress 博客的 android webview。一些博客文章包含 youtube 视频,我希望用户能够根据需要制作全屏。问题是 html5 全屏按钮在单击时什么都不做,而是冻结视图。 有什么想法吗?

【问题讨论】:

【参考方案1】:

这是我在最后一天左右把头发扯下来的东西。基于来自网络的各种代码,我设法让它工作。

首先,您需要创建一个自定义的WebChromeClient 类,它实现了onShowCustomViewonHideCustomView 方法。

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);
        
    

基本上,这里发生的是当按下全屏按钮时,我们正在创建一个新视图来保存视频并隐藏主视图。然后当全屏关闭时,我们会做相反的事情——去掉新视图并显示原始视图。

您还需要将所有这些属性添加到您的活动类中:

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

您可能希望在按下后退按钮时关闭全屏视频:

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

那么在你创建 webview 时使用你的新类就很简单了:

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

这适用于我在 Android 4.x 上。不确定早期版本,因为我的应用没有针对它们。

我发现这些链接特别有用:WebView and HTML5 <video> 和 http://code.google.com/p/html5webview/source/browse/trunk/HTML5WebView/src/org/itri/html5webview/HTML5WebView.java

【讨论】:

在您的代码示例中,全屏视图上下文中的 mContentView 是什么?我想这是您夸大的某种布局,但是您是如何使其全屏显示的。您可以为您的 mContentView 对象发布 XML 吗? mContentView 是主要的活动视图,当视频全屏时它会被隐藏。不过,我不会自动全屏播放视频;用户在观看视频时会这样做(如果他们愿意)。 @MarkParnell 请在这里也给您的 cmets ***.com/questions/18533678/… @MarkParnell 感谢您的解决方案,但我收到错误“尝试在没有有效媒体播放器的情况下调用 getDuration”也有错误(-38,0)。有什么想法吗? 退出活动后,我看到无穷无尽的V/MediaPlayer(15998): isPlaying: 0 消息。为什么退出活动时媒体播放器仍然处于活动状态?【参考方案2】:

如果在应用程序中直接显示 YouTube 视频并不重要,当您将视频信息 URL 插入时,您可以启动外部 YouTube 应用程序。

要捕获视频信息 URL,您需要使用 onLoadResource 方法:

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);
        
    

【讨论】:

不错的代码,但是当我按下视频时,它也开始在 webview 中播放,我该如何取消呢? 你可以调用WebView.reload()。但是如果你不需要启动外国应用程序,你可以直接在应用程序中实现全屏视频。【参考方案3】:

感谢@Mark Parnell 的回复,但他正在艰难地进行大量 UI 更改,也许这种方式更简洁、更容易理解:

当点击全屏按钮时,chrome 客户端会为我们提供全屏视图,然后我们应该将其添加到我们的活动视图中:

定义这个全局变量以在我们的活动中保存全屏视图引用:

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

然后 web chrome 客户端将通知我们在 onShowCustomViewonHideCustomView 方法中显示和隐藏全屏视图:

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();
                
            

        ;

最后按下后删除全屏视图(用户期望这种行为):

@Override
public void onBackPressed() 
    if (fullscreenView != null) 
        webChromeClient.onHideCustomView();
    
       

【讨论】:

以上是关于带有嵌入式 youtube 视频的 Android WebView,全屏按钮冻结视频的主要内容,如果未能解决你的问题,请参考以下文章

带有“autoplay=1”的嵌入式 youtube 视频。它是不是计入观看次数?

嵌入带有自动播放和无控件的 youtube 视频

使用 HTML5 嵌入式视频与使用带有 YouTube 链接的 iframe 有啥区别?

如何将 youtube 视频嵌入为带有自动播放、循环和隐藏观看、分享、Youtube 徽标和视频标题的标题?

如何嵌入带有 4000 多个视频的缩略图的 youtube 频道

嵌入没有任何徽标或 youtube 链接的 youtube 视频