ijkplayer对rtsp的支持是很弱的,所以需要修改一些代码;
- Config
首先要开启rtsp的一些config选项,不知道最新的版本是否已经添加,不过我用的是0.7.2还没加上。
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-demuxer=rtsp"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-demuxer=sdp"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-demuxer=rtp"
- Code
很多人一拿到编好的库,发现播不了,其实是因为下面这句代码
因为av_read_frame读到了数据,到这里又不处理,导致缓冲区一直不满,
所以rtsp不要设置缓冲区;
#if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
if (is->paused &&
(!strcmp(ic->iformat->name, "rtsp") ||
(ic->pb && !strncmp(ffp->input_filename, "mmsh:", 5)))) {
/* wait 10 ms to avoid trying to get another packet */
/* XXX: horrible */
SDL_Delay(10);
continue;
}
#endif
把这段代码注释了吧!
另外,不设置缓冲区,在应用层添加(以android为例):
// 最大缓冲cache是3s, 有时候网络波动,会突然在短时间内收到好几秒的数据
// 因此需要播放器丢包,才不会累积延时
// 这个和第三个参数packet-buffering无关。
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max_cached_duration", 3000);
// 无限制收流
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "infbuf", 1);
// 设置无缓冲,这是播放器的缓冲区,有数据就播放
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 0);
// 可选,有时候tcp模式出画面更快,因为rtsp是先udp,不成功再切到tcp的
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_transport", "tcp");
// 设置在解析的 url 之前 (这里设置超时为5秒)
// 如果没有设置stimeout,在解析时(也就是avformat_open_input)把网线拔掉,av_read_frame会阻塞(时间单位是微妙)
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "stimeout", "5000000");
3.讲的差不多了,代码面前,了无秘密,
需要rtsp的优化后代码,请私信我QQ:307509256。
- 前两天听群里人说,抓包看ijk播放rtsp不会发TEARDOWN,断开时通过tcp read的timeout,大概也就30s左右吧,如果是这样,那确实是ijk对rtsp支持的一个bug,vlc抓包是有发的,我没去查原因,知情者可以讨论下;
后记:
如果代码有bug或好的建议,请不吝赐教;
如果觉得有用,并加颗星;
Ai时代,写作是一种新竞争力,自勉之~