Android - 在 SurfaceTexture 上绘制 YouTube 视频 [英] Android - draw YouTube video on SurfaceTexture

查看:22
本文介绍了Android - 在 SurfaceTexture 上绘制 YouTube 视频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 SurfaceTexture 上绘制一个 WebView,以便我可以在 OpenGL 中呈现它.

I'm trying to draw a WebView on SurfaceTexture so I can render it in OpenGL.

到目前为止,我以标准方式在 WebView 中成功播放了 youtube 视频:

So far, I successfully played youtube video in WebView the standard way:

  ...
  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/

And I also successfully rendered the WebView in OpenGL (except playing the video) based on this tutorial: http://anuraagsridhar.wordpress.com/2013/03/13/rendering-an-android-webview-or-for-that-matter-any-android-view-directly-to-opengl/

WebView 的额外初始化(所以它总是纵向"并适合纹理):

Additional initialization of the WebView (so it is always 'portrait' and fits into the texture):

 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 方法:

Overriden onDraw method of the WebView:

@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 视频时,视频矩形是黑色的(但是可以听到声音).我怀疑硬件加速对表面纹理不起作用.

When trying to play YouTube video on webview rendered using the above hack, the video rectangle is black (however the sound can be heard). I suspect that the hardware acceleration does not work on surface texture.

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

So the question is: Is there any way to play a youtube video on OpenGL texture?

推荐答案

问题是这样的:视频被绘制到一个单独的窗口,该窗口位于视图层次结构的窗口后面,并且不容易在您的 表面纹理.更复杂的是,WebView 将定位和调整视频窗口的大小,而不考虑自己是否被绘制到一个 Canvas 而不是将显示在屏幕上的那个.此外,视频是以本机代码呈现的,无论如何您都无法以足够快的速度绘制到 Canvas 以跟上(这就是为视频提供单独窗口的全部想法).

The problem is this: the video is being drawn to a separate window that is behind the view hierarchy's window and is not readily accessible to be drawn on your SurfaceTexture. To complicate the matter, the WebView will have positioned and sized the video window without regard for itself being drawn to a Canvas other than the one that would be displayed on the screen. Furthermore, the video is being rendered in native code, and you wouldn't be able to draw to a Canvas fast enough to keep up anyway (that's the whole idea behind giving the video a separate window).

任何令人满意的解决方案几乎都需要使用私有 API 来访问本机代码中的视频窗口.根据您计划如何使用 SurfaceTexture,您可能会想出一种解决方法,包括拦截 WebViewClient 中的 URL,在渲染之前去除所有视频标签,然后放置您控制的 SurfaceViewTextureView 中的视频.然后,您可以将其放置在与您绘制 SurfaceTexture 的位置相关的位置,但这会将您对 SurfaceTexture 的使用限制为广告牌.不过,这种 hack 很快就会变得非常丑陋.

Any satisfactory solution would almost necessarily require use of the private APIs to get access to the video window in native code. Depending on how you plan to use your SurfaceTexture, you might come up with a workaround that involves intercepting URLs in a WebViewClient, stripping out any video tags before rendering, and placing the video in a SurfaceView or TextureView under your control. You can then put it where it should be in relation to where you've drawn the SurfaceTexture, but that limits your usage of the SurfaceTexture to billboarding. That sort of hack would get very ugly very quickly, though.

简而言之,我认为没有一种干净的方法可以做到这一点.这是一个不错的主意,但它不适用于公共 API.

Put simply, I don't see a clean way to do this. It's a nice idea, but it's just not workable with the public API.

这篇关于Android - 在 SurfaceTexture 上绘制 YouTube 视频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆