使用TextureView和MediaPlayer播放视频黑屏问题
背景
使用TextureView和MediaPlayer播放视频,recycleView滑动显示,滑动到对应的视频页面,会先黑屏再播放视频,用户体验不好。
原因
TextureView 出现黑闪现象通常是因为在视频开始播放前,它的内容是空的。当视频开始渲染时,TextureView 从无内容状态切换到有内容状态,这个过程可能会导致短暂的黑屏。
解决方案
使用占位图:
在视频加载并准备播放前,使用一个静态的占位图。当视频开始播放的时候,再移除占位图。这可以通过在TextureView上层放置一个ImageView并在视频准备好时将其隐藏来实现。
// 设置OnInfoListener
holder.videoView.setOnInfoListener { mp, what, extra ->if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {// 视频开始渲染// 这里可以执行一些操作,例如隐藏加载指示器holder.imageView.visibility = View.GONEtrue} else {false}
}
media的监听方法源码:
/*** Interface definition of a callback to be invoked to communicate some* info and/or warning about the media or its playback.*/
public interface OnInfoListener
{/*** Called to indicate an info or a warning.** @param mp the MediaPlayer the info pertains to.* @param what the type of info or warning.* <ul>* <li>{@link #MEDIA_INFO_UNKNOWN}* <li>{@link #MEDIA_INFO_VIDEO_TRACK_LAGGING}* <li>{@link #MEDIA_INFO_VIDEO_RENDERING_START}* <li>{@link #MEDIA_INFO_BUFFERING_START}* <li>{@link #MEDIA_INFO_BUFFERING_END}* <li><code>MEDIA_INFO_NETWORK_BANDWIDTH (703)</code> -* bandwidth information is available (as <code>extra</code> kbps)* <li>{@link #MEDIA_INFO_BAD_INTERLEAVING}* <li>{@link #MEDIA_INFO_NOT_SEEKABLE}* <li>{@link #MEDIA_INFO_METADATA_UPDATE}* <li>{@link #MEDIA_INFO_UNSUPPORTED_SUBTITLE}* <li>{@link #MEDIA_INFO_SUBTITLE_TIMED_OUT}* </ul>* @param extra an extra code, specific to the info. Typically* implementation dependent.* @return True if the method handled the info, false if it didn't.* Returning false, or not having an OnInfoListener at all, will* cause the info to be discarded.*/boolean onInfo(MediaPlayer mp, int what, int extra);
}
这段代码定义了一个名为 OnInfoListener 的接口,它是一个回调接口,用于在媒体播放过程中传达一些信息或警告。这个接口通常在Android的 MediaPlayer 类中使用。当播放媒体时,MediaPlayer 可能会遇到各种事件和状态变化,OnInfoListener 允许开发者在这些情况发生时得到通知。
接口中的 onInfo 方法会在有信息或警告时被调用。这个方法有三个参数:
- mp:MediaPlayer 对象,它是触发信息事件的媒体播放器。
- what:信息或警告的类型。这是一个整数值,代表不同的信息或警告。例如,MEDIA_INFO_VIDEO_RENDERING_START 表示视频开始渲染。
- extra:附加的整数值,提供有关信息的额外数据。这通常依赖于实现,不同的 what 类型可能会有不同的 extra 值。
onInfo 方法返回一个布尔值,表示是否处理了这个信息。如果返回 true,表示应用处理了这个信息。如果返回 false 或者没有设置 OnInfoListener,那么这个信息就会被丢弃。
下面是 what 参数可能包含的一些值的解释:
- MEDIA_INFO_UNKNOWN:未知的信息或警告。
- MEDIA_INFO_VIDEO_TRACK_LAGGING:视频跟踪落后,可能是因为处理不过来。
- MEDIA_INFO_VIDEO_RENDERING_START:视频开始渲染,这可以用来处理视频播放开始的黑屏问题。
- MEDIA_INFO_BUFFERING_START:开始缓冲,媒体播放器需要填充缓冲区。
- MEDIA_INFO_BUFFERING_END:缓冲结束,缓冲区已填满,播放可以继续。
- MEDIA_INFO_NETWORK_BANDWIDTH (703):网络带宽信息可用,extra 表示以kbps为单位的带宽。
- MEDIA_INFO_BAD_INTERLEAVING:媒体文件的交错格式不佳,可能影响播放。
- MEDIA_INFO_NOT_SEEKABLE:媒体不可寻址,不能跳转到指定的播放位置。
- MEDIA_INFO_METADATA_UPDATE:元数据更新了。
- MEDIA_INFO_UNSUPPORTED_SUBTITLE:不支持的字幕格式。
- MEDIA_INFO_SUBTITLE_TIMED_OUT:字幕超时。