12

我正在尝试在 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-问题-任何-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);
   }
}

当尝试在使用上述 hack 渲染的 webview 上播放 YouTube 视频时,视频矩形是黑色的(但是可以听到声音)。我怀疑硬件加速不适用于表面纹理。

所以问题是:有没有办法在 OpenGL 纹理上播放 youtube 视频?

4

2 回答 2

7

问题是这样的:视频被绘制到视图层次结构窗口后面的单独窗口,并且不容易在SurfaceTexture. 使事情复杂化的是,WebView将定位和调整视频窗口的大小,而不考虑将其自身绘制到Canvas屏幕上显示的窗口之外。此外,视频正在以本机代码呈现,无论如何您都无法以Canvas足够快的速度进行绘制(这就是为视频提供单独窗口的全部想法)。

任何令人满意的解决方案几乎都需要使用私有 API 来访问本机代码中的视频窗口。根据您打算如何使用您的SurfaceTexture,您可能会想出一个解决方法,包括拦截 a 中的 URL,WebViewClient在渲染之前剥离任何视频标签,并将视频置于 aSurfaceViewTextureView您的控制之下。然后,您可以将它放在与您绘制 的位置相关的位置SurfaceTexture,但这会限制您SurfaceTexture对广告牌的使用。不过,这种黑客行为很快就会变得非常丑陋。

简而言之,我没有看到一个干净的方法来做到这一点。这是一个好主意,但它不适用于公共 API。

于 2013-10-14T04:22:37.003 回答
1

尝试使用API 级别 23 中添加的lockHardwareCanvas 。

于 2019-06-19T20:27:34.757 回答