【发布时间】:2015-09-09 09:55:29
【问题描述】:
我是 Android 新手,想编写一个在播放视频时测量帧速率的应用。为此,我使用 MediaPlayer 并将其显示在 SurfaceView 上。在这个星座中,是否有可能获得所需的渲染统计数据来计算帧率?谢谢
【问题讨论】:
标签: android video surfaceview frame-rate
我是 Android 新手,想编写一个在播放视频时测量帧速率的应用。为此,我使用 MediaPlayer 并将其显示在 SurfaceView 上。在这个星座中,是否有可能获得所需的渲染统计数据来计算帧率?谢谢
【问题讨论】:
标签: android video surfaceview frame-rate
MediaPlayer 的重点是隐藏视频解码和呈现的细节,所以你根本无法获得所有细节。例如,没有每帧回调。
解决该问题的一种方法是使用 MediaPlayer 将视频播放到 SurfaceTexture 上,并使用 OpenGL ES 将每一帧渲染到 SurfaceView 的 Surface 上。 SurfaceTexture 提供每帧的呈现时间戳。
另一种方法是使用 MediaCodec 代替 MediaPlayer,让您完全控制解码和演示过程。这更复杂,如果视频有音频,就会变得棘手。
您可能还想考虑使用 MediaExtractor 检查视频文件本身,并使用前几帧来检测帧速率。
正如@Mick 所指出的,某些视频具有可变帧速率,您无法为整个流建立单个值。 screenrecord 拍摄的视频就是一个很好的例子。在这种情况下,您能做的最好的事情就是显示“最近的”帧速率,并且您必须动态计算它(因此 MediaExtractor 不会削减它)。
【讨论】:
有报道(我自己没有测试过)VideoView的onDraw方法会在每个视频帧写入的时候被调用。
这允许您覆盖并添加一些代码到 onDraw 方法,以记录每帧的写入时间并计算运行的 fps 值。
要允许调用 onDraw 方法,您必须设置一个标志:
setWillNotDraw(假)
在您的视图构造函数中 - 请参阅:https://stackoverflow.com/a/17595671/334402
顺便说一句,值得注意的是,某些视频的帧速率会发生变化。这通常是因为他们试图在给定的带宽预算内最大限度地提高质量。
【讨论】:
onDraw() 的唯一原因是,如果有人为每一帧发出 View invalidates,这只有在视频在软件中被解码并渲染到 View 本身时才有用。 (这是从哪里来的?)
onDraw() 可用于指示帧速率的唯一方法是 VideoView 是否每帧都在其视图中更新某些内容。浏览android.googlesource.com/platform/frameworks/base/+/…,draw() 的唯一用途是用于字幕。