我有一个Activity
WebView
。我里面有一个WebChromeClient
。在其中,有几个回调旨在返回处理视频位的MediaPlayer
。例如:
@Override
public void onPrepared(MediaPlayer mp) {
Log.i(TAG, " -------------> onPrepared");
}
使用HTML WebView
标记(通过注入)将MP4流加载到<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
创建的内容?
- 更新
以下是初始化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>
在该WebView类中,存在此类:
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,但在做完这类事后我总觉得有点蠢蠢欲动。即使我有MediaPlayer对象,我也不愿意发布它。对MP的源代码进行一点研究表明,没有什么不好的事情会发生,但是。 。
我注意到,并非每台设备都会发生这种情况。例如,HTC似乎比三星表现更好(“相同的”操作系统/ API级别 - 我真的不够雄心勃勃,无法比较两个源代码树)。
下面提到的行为很烦人,但仅限于我(正在观看logcat输出。对于用户或应用程序,它似乎没有任何影响。只是我真的不喜欢我开始使用MediaPlayer的想法例如,设置它忙着缓存,然后(如果/当用户终止我的应用程序时)将那个dingleberry挂在那里。此时我在治疗方面有很多钱,但它似乎没有帮助
提前致谢。
答案 0 :(得分:5)
没有反射就无法访问MediaPlayer - WebViewClient和WebChromeClient不会故意公开它。而且你说使用反射可能会导致你破坏你的应用程序或WebView,因为代码可能会因Android版本而异,甚至可能不同于OEM。
如果您想这样做,则必须找到与您的视频元素对应的HTML5VideoView实例。该对象创建并维护MediaPlayer的实例为“mPlayer”。请参阅https://github.com/android/platform_frameworks_base/blob/jb-mr2-release/core/java/android/webkit/HTML5VideoView.java。
答案 1 :(得分:3)
private class MyWebChromeClient extends WebChromeClient
implements ..... MediaPlayer.onCompletion {
}
添加
@Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
mp.release();
}
在webview关闭后,为我删除了错误消息。
现在,如果我能让webview播放/流式传输vimeo视频:(