on-existing SPS 2 referenced in buffering period
这个错误一般是说 ijkplayer 在解码 RTSP 流的时候遇到了与视频编码相关的问题,主要是SPS丢失或者错误引用的,RTSP 流的中断或不连续的数据包可能报这个错,这个错误算是比较常见的,有下面几种情况你可以参考一下:
返回的错误为什么没有被 ijkvideoview.setOnErrorListener() 这个事件监听到?
@Fitz: 这种情况有很多原因,如果错误是来自解码器、RTSP 传输层或网络中断等是监听不到的。
IjkPlayer 的有些错误,尤其是底层 FFmpeg 或解码器抛出的错误,有可能不能通过 OnErrorListener 回调,而是直接输出到日志或控制台。试试启用更多的日志,看看是不是有底层错误信息:
IjkMediaPlayer ijkPlayer = new IjkMediaPlayer();
ijkPlayer.setLogLevel(IjkMediaPlayer.IJK_LOG_DEBUG);
然后检查控制台输出,看看有没有有其他详细错误。
监听 info 回调事件:有时错误会以 OnInfoListener 的形式返回。试试这样:
ijkVideoView.setOnInfoListener((mp, what, extra) -> {
Log.d("IjkPlayer", "Info event: what = " + what + ", extra = " + extra);
return false;
});
然后就是网络问题了,丢包或连接超时,可能会导致解码器卡住,但不会触发 OnErrorListener。可以试试设置 RTSP 传输和超时:
ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_transport", "tcp");
ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "timeout", 3000000); // 设置超时(微秒)
ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "enable-accurate-seek", 1);
使用 TCP 传输可以减少丢包问题,并通过设置超时让播放器在网络不佳时及时返回错误。
也有可能是底层解码器错误未通过 Java 层回调
IjkPlayer 的一些错误发生在 FFmpeg 解码层,是有可能不会冒泡到 Java 层的 OnErrorListener的,试试直接监听底层 FFmpeg 的消息,使用 IjkMediaPlayer.setOnNativeInvokeListener(),捕获更多底层事件:
ijkPlayer.setOnNativeInvokeListener((what, args) -> {
Log.d("IjkPlayer", "Native invoke event: what = " + what);
return false;
});
其他原因有可能是应用被后台杀死或意外中断Android 系统可能因为资源不足或其他原因中断播放,但这些不会触发错误回调。
在 onPause() 和 onResume() 中合理管理播放器,避免意外释放:
@Override
protected void onPause() {
super.onPause();
ijkVideoView.pause();
}
@Override
protected void onResume() {
super.onResume();
ijkVideoView.start();
}
实在找不到也很简单啊,用全局异常捕获来捕获可能未冒泡的错误:
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
Log.e("IjkPlayer", "Uncaught exception: ", throwable);
});
实在找不到就去认真看看日志
@五号位: 没有setLogLevel 这个函数,有这个 native_setLogLevel 可以设置