Android的WebView中播放HTML5 / H.264 / MP4视频,如何获得在Media

2019-06-28 08:51发布

我有一个Activity是一个WebView 。 我有一个WebChromeClient里面。 这里面,有几个的回调这意味着可以返回MediaPlayer处理的视频比特。 例如:

@Override
public void onPrepared(MediaPlayer mp) {
    Log.i(TAG, " -------------> onPrepared");
}

这些失败火时我加载MP4流进入WebView使用HTML <video>标签(通过注射)。

当我finish()的活动中,logcat的报道如下:

09-13 23:55:24.590: E/MediaPlayer(7949): mOnBufferingUpdateListener is null. Failed to send MEDIA_BUFFERING_UPDATE message.
09-13 23:55:24.680: E/MediaPlayer(7949): mOnBufferingUpdateListener is null. Failed to send MEDIA_BUFFERING_UPDATE message.
09-13 23:55:24.680: E/MediaPlayer(7949): mOnVideoSizeChangedListener is null. Failed to send MEDIA_SET_VIDEO_SIZE message.
09-13 23:55:25.675: E/MediaPlayer(7949): mOnBufferingUpdateListener is null. Failed to send MEDIA_BUFFERING_UPDATE message.
09-13 23:55:26.735: E/MediaPlayer(7949): mOnBufferingUpdateListener is null. Failed to send MEDIA_BUFFERING_UPDATE message.
09-13 23:55:27.755: E/MediaPlayer(7949): mOnBufferingUpdateListener is null. Failed to send MEDIA_BUFFERING_UPDATE message.
09-13 23:55:28.705: E/MediaPlayer(7949): mOnBufferingUpdateListener is null. Failed to send MEDIA_BUFFERING_UPDATE message.

我尝试过,可我不能让它停下来,即使WebView被清除,然后销毁。 当使用加载视频<video>标签,我不知道有什么办法强迫WebChromeClient使用特定MediaPlayer ,我为它创建。 它似乎决心要使用一些隐藏的一个,它报告上面。 有没有办法找到MediaPlayer通过从创建<video>在标签上WebView

--update

下面是初始化的WebView的代码:

        mWebView = new WebView(mContext);

        mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.getSettings().setPluginState(PluginState.OFF);
        mWebView.setVisibility(View.INVISIBLE);
        mWebView.getSettings().setDefaultZoom(WebSettings.ZoomDensity.FAR);
        mWebView.getSettings().setBuiltInZoomControls(false);
        mWebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
        mWebView.getSettings().setLoadWithOverviewMode(true);
        mWebView.getSettings().setUseWideViewPort(true);
        mWebView.clearHistory();
        mWebView.clearFormData();
        mWebView.clearCache(true);
        mWebView.getSettings().setAllowFileAccess(true);
        mWebView.getSettings().setUserAgentString("Android Mozilla/5.0 AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30");

        chrome = new MyWebChromeClient();
        mWebView.setWebChromeClient(chrome);

        wvc = new MyWebViewClient();
        mWebView.setWebViewClient(wvc);

        mDomain = "http://foo.bar.com";
        mWebView.requestFocus(View.FOCUS_DOWN);

        String meat = genMainHTML(R.raw.frame);

        mWebView.loadDataWithBaseURL(mDomain, meat, "text/html", "utf-8", null);

该“框架”代码是推出一些视频的iframe(两者的Vimeo和YouTube似乎采用这种方式,至少)。 我已经修剪这一点,以避免多余的内容:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div>
     <iframe src="-target.url.with.params-" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen>
     </iframe>
</div>
</body>
</html>

在这一类网页视图,存在这个类:

private class MyWebViewClient extends WebViewClient {

    @Override
    public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            String injection = injectPageMonitor();
            if(injection != null && !injectionComplete) {
                // Log.i(TAG, " ---------------> Page Loaded . . .");
                view.loadUrl(injection);
                injectionComplete = true;
        }
    }

    @Override
    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            Log.d(TAG, "*** Error ["+description+"] ["+failingUrl+"]");
        Toast.makeText(mContext, description, Toast.LENGTH_SHORT).show();
    }

}

而且这个类:

    private class MyWebChromeClient extends WebChromeClient implements MediaPlayer.OnInfoListener, MediaPlayer.OnSeekCompleteListener, MediaPlayer.OnErrorListener, MediaPlayer.OnVideoSizeChangedListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnBufferingUpdateListener {

       @Override
       public void onProgressChanged(WebView view, int progress) {
           //Log.e(TAG, " -------------> Progress Changed . . . . ["+progress+"] mWebView ["+mWebView+"] ["+view+"]");
           if(progress == 100) {
                               // Do something really interesting
           }  else  {
               updateBuffering(UPDATE_PERCENT_LAUNCH_EXTRACTOR + (progress / 2));
           }
       }

       @Override
       public boolean onConsoleMessage(ConsoleMessage cm) {
                       // Spit out lots of console messages here
           return(true);
       }
   }

和我所有的秋后算账覆盖,以防万一我能幸运地得到了MediaPlayer的一些反应:

        @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) {
        // Jump up and down because we got a mp!
                    // never happens, so no jumping
    }

作为一个侧面说明,我没有挖过来使用反射和得到阿霍德在MediaPlayer的这种方式,但我总觉得有点ookey做那种事了。 而且即使我有MediaPlayer对象,我不愿意,只是将其释放。 一个小的MP的源代码的研究表明,没有什么不好的事情发生,但。 。 。

这并不是在每个设备上发生的,我已经注意到了。 HTC似乎表现得比三星更好,例如(“同” OS / API级别 - 我不是真的够远大比较两个源树)。

行为注意到下面是讨厌的,但仅限于我(谁是看logcat的输出。对于用户或应用程序似乎没有任何效果。这只是我真的不喜欢说我踢了一个MediaPlayer的实例的概念,设置它忙于缓存了,然后(如果/当用户终止我的应用程序)留下dingleberry挂在那里。我有很多钱,在这一点上在治疗中捆绑起来,它似乎并不被帮助。

提前致谢。

Answer 1:

有没有办法访问MediaPlayer的没有反射 - 的WebViewClient和WebChromeClient不要故意将其暴露。 而你是在说,使用反射可能会导致你打破自己的应用程序或网页视图的代码可以在Android版本,甚至跨越OEM厂商而异正确。

如果你想做到这一点,你必须找到对应于您的视频元素HTML5VideoView的实例。 这个对象创建和维护一个实例来在MediaPlayer为“MPlayer的”。 请参阅https://github.com/android/platform_frameworks_base/blob/jb-mr2-release/core/java/android/webkit/HTML5VideoView.java 。



Answer 2:

你们班

private class MyWebChromeClient extends WebChromeClient 
                                implements ..... MediaPlayer.onCompletion {
}

加入

@Override
public void onCompletion(MediaPlayer mp) {
    // TODO Auto-generated method stub
    mp.release();           
}

摆脱了错误消息对我的WebView后关闭。

现在,如果我能得到的WebView播放/流VIMEO视频:(



文章来源: Android WebView Playing HTML5/h.264/mp4 Video, How to get at the MediaPlayer