检测Android SurfaceView是否正在绘制/移动

7
我正在使用libvlc在一款Android应用程序中播放网络流。本地代码在SurfaceView上绘制图像。 假设视频停止,我无法访问本地代码,如何检测SurfaceView是否仍在移动(视频未冻结)? 我尝试了getViewTreeObserver().addOnDrawListener();和getViewTreeObserver().addOnPreDrawListener();但它们没有我所期望的效果。 谢谢。

你在Surface View中使用媒体播放器来运行视频吗? - Ahmed
我正在使用运行在本地代码上的 VLC。 - Ambi
2个回答

7
你无法从SurfaceView中获得该信息,因为SurfaceView本身并不知道。
SurfaceView的工作是设置Surface,并在视图布局中创建一个可以透过看到的空洞。一旦它完成了这些工作,它就不再积极参与视频显示的过程中了。内容从解码器流向Surface,由SurfaceFlinger(系统图形合成器)管理。
例如,DRM视频的工作原理就是这样的。播放视频的应用程序无法访问受DRM保护的视频帧。(实际上,SurfaceFlinger也不能访问,但这是一个更长的故事。)
了解内容是否仍在到达的最好方法是询问视频源是否仍在向您发送内容。另一种方法是将SurfaceView更改为TextureView,并提供一个onSurfaceTextureUpdated()回调方法。

我尝试了这种方法,但不幸的是,如果图像被冻结并且不再改变,回调函数也会被执行。因此,这不能用于检测流是否已经冻结。 - Display name
@Seppl 如果回调正在触发,通常意味着新的帧正在传递。没有测试来判断新帧是否具有与上一帧相同的内容。如果您查看源代码(https://android.googlesource.com/platform/frameworks/base/+/marshmallow-mr1-release/core/java/android/view/TextureView.java#426),则会发现回调仅在设置`mUpdateLayer`时触发。这是由`updateLayer()`设置的,当帧到达时也会调用它,但也会在某些应用程序驱动的更新(大小更改,视图可见等)时进行调用。定期调用表示帧正在到达。 - fadden

1
我不确定你在这里想要实现什么,但是你可以通过实现一个称为SurfaceHolder.Callback的接口来查看Surface View是否正在渲染。该接口使您可以访问以下方法:
  1. On Surface Created - 在Surface首次创建后立即调用此方法。
  2. On Surface Changed - 在对Surface进行任何结构更改(格式或大小)后立即调用此方法。
  3. On Surface Destroyed - 在Surface即将被销毁之前立即调用此方法。
请参阅Surface View的文档documentation。有关SurfaceHolder,请查看link。基本上,为了知道...

我已经尝试了这条路,但对于我的问题没有帮助。 我正在尝试检测视频是否仍在播放或者卡在一个画面上。当这种情况发生时,Surface已经触发了onCreate和onChanged。 - Ambi
SurfaceView的回调对此并不有用 - 它们不会在内容更新时触发。 - fadden

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接