我正在尝试在SurfaceTexture上绘制WebView,以便我可以在OpenGL中渲染它。
到目前为止,我以标准方式在WebView中成功播放了YouTube视频:
...
webView.getSettings().setJavaScriptEnabled(true);
if (Build.VERSION.SDK_INT < 8)
{
webView.getSettings().setPluginsEnabled(true);
}
else
{
webView.getSettings().setPluginState(WebSettings.PluginState.ON);
}
webView.setWebChromeClient(new WebChromeClient() { });
webView.setWebViewClient(new WebViewClient());
...
也打开了硬件加速:
<application
android:hardwareAccelerated="true"
...
我还基于本教程在OpenGL中成功渲染了WebView(除了播放视频):http://anuraagsridhar.wordpress.com/2013/03/13/rendering-an-android-webview-or-for-that-matter-any-android-view-directly-to-opengl/
WebView的附加初始化(因此它总是“纵向”并且适合纹理):
Point p = new Point();
activity.getWindow().getWindowManager().getDefaultDisplay().getSize(p);
webView.setLayoutParams(new ViewGroup.LayoutParams(p.x, p.y));
surfaceTexture.setDefaultBufferSize(p.x, p.y);
覆盖WebView的onDraw方法:
@Override
public void onDraw(Canvas c)
{
try
{
Point p = new Point();
activity.getWindow().getWindowManager().getDefaultDisplay().getSize(p);
Canvas canvas = surfaceTexture.lockCanvas(new Rect(0,0,p.x,p.y));
canvas.save();
canvas.translate(-scrollL, -scrollT);
super.onDraw(canvas);
canvas.restore();
surfaceTexture.unlockCanvasAndPost(canvas);
}
catch (Surface.OutOfResourcesException e)
{
throw new RuntimeException(e);
}
}
当尝试使用上述黑客在webview上播放YouTube视频时,视频矩形为黑色(但可以听到声音)。 我怀疑硬件加速对表面纹理不起作用。
所以问题是: 有没有办法在OpenGL纹理上播放YouTube视频?
答案 0 :(得分:5)
问题在于:视频被绘制到视图层次结构窗口后面的单独窗口,并且无法在SurfaceTexture
上绘制。为了使问题复杂化,WebView
将对视频窗口进行定位和调整大小,而不考虑将其自身绘制到除了将在屏幕上显示的Canvas
之外的Canvas
。此外,视频使用本机代码进行渲染,您无法以足够快的速度绘制到SurfaceTexture
以便跟上(这就是为视频提供单独窗口的全部理念)。
任何令人满意的解决方案几乎都需要使用私有API来访问本机代码中的视频窗口。根据您计划使用WebViewClient
的方式,您可能会想出一种解决方法,涉及拦截SurfaceView
中的网址,在呈现之前删除任何视频标记,并将视频放入{{1在您的控制之下或TextureView
。然后,您可以将其放在与SurfaceTexture
的绘制位置相关的位置,但这会限制您使用SurfaceTexture
到广告牌。不过,那种黑客行为会很快变得非常丑陋。
简单地说,我没有看到干净的方法来做到这一点。这是一个不错的主意,但它不适用于公共API。
答案 1 :(得分:0)
尝试使用在API级别23中添加的lockHardwareCanvas。