* author:conowen@大钟
* E-mail:conowen@hotmail.com
1、编译ijkplayer
由于iOS原生不支持rtsp协议的视频流播放,所以只能使用FFmpeg,但是直接使用原生FFmpeg,还要对它进行二次封装,这个工作量太大,所以使用了现在github 上最热门的FFmpeg封装库ijkplayer,这个库是bilibili出品,现在主流的直播APP和视频播放器大部分都是基于ijkplayer开发的,功能十分强大,并且同时支持iOS与Android,地址为
以下是iOS版本的编译步骤
git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-ios
cd ijkplayer-ios
git checkout -B latest k0.7.6
./init-ios.sh
cd ios
./compile-ffmpeg.sh clean
./compile-ffmpeg.sh all
编译完成后,打开iOS目录下的IJKMediaPlayer工程,选择“building setting”的编译选项“�Build Active Architecture Only”的Release 和Debug都为NO,要不然最后导入编译出来的Framework打包不了。
编译出Framework之后,就要导入到Focus项目中,导入ijkplayer还要引入以下Framework,如下图所示
2、使用ijkplayer
构建工程,使用IJKMediaFramework对rtsp视频流播放的时候,通过Xcode的console窗口看到了一个错误信息
rtsp://192.168.0.1:8554/MJPEG_unicast: Protocol not found
这是由于FFmpeg的config文件没有开启对rtsp协议的支持,来到ijkplayer/config目录下,找到module-lite.sh文件,该文件是编译FFmpeg的配置文件,配置打开那个模块,关闭那些模块。
打开该文件,找到
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-protocol=rtp"
修改为以下,就可以打开rtsp协议了。
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-protocol=rtp"
然后继续添加以下一行,打开rtsp音视频分离器
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-demuxer=rtsp""
然后执行以下命令,连接配置文件
cd config
rm module.sh
ln -s module-lite.sh module.sh
cd ios
sh compole-ffmpeg clean
sh compile-ffmpeg all
重新编译后,发现rstp协议已经支持,但是还是播放不了,通过Xcode的console窗口看到了一个错误信息
No codec could be found with id 8
缺少ID为8的codec,我们找到FFmpeg里面的avcodec.h头文件,找到以下定义
enum AVCodecID {
AV_CODEC_ID_NONE,
/* video codecs */
AV_CODEC_ID_MPEG1VIDEO,
AV_CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding
#if FF_API_XVMC
AV_CODEC_ID_MPEG2VIDEO_XVMC,
#endif /* FF_API_XVMC */
AV_CODEC_ID_H261,
AV_CODEC_ID_H263,
AV_CODEC_ID_RV10,
AV_CODEC_ID_RV20,
AV_CODEC_ID_MJPEG,
AV_CODEC_ID_MJPEGB,
AV_CODEC_ID_LJPEG,
。。。。。。。
ID为8的codec正是MJPEG解码器,重新打开module-lite.sh文件,添加以下两行
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=mjpeg"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-demuxer=mjpeg"
继续重新编译,然后重新打包Framework,就可以正常播放了。但是实际播放效果非常不理想,卡顿非常严重,延迟至少1000ms!!!!1
3、优化ijkplayer
新建player的时候,并没有配置player,添加以下配置代码,就可以达到较佳的播放效果了。
代码如下
IJKFFOptions *options = [IJKFFOptions optionsByDefault];
[options setPlayerOptionIntValue:30 forKey:@"max-fps"];
[options setPlayerOptionIntValue:1 forKey:@"framedrop"];
[options setPlayerOptionIntValue:0 forKey:@"start-on-prepared"];
[options setPlayerOptionIntValue:0 forKey:@"http-detect-range-support"];
[options setPlayerOptionIntValue:48 forKey:@"skip_loop_filter"];
[options setPlayerOptionIntValue:0 forKey:@"packet-buffering"];
[options setPlayerOptionIntValue:2000000 forKey:@"analyzeduration"];
[options setPlayerOptionIntValue:25 forKey:@"min-frames"];
[options setPlayerOptionIntValue:1 forKey:@"start-on-prepared"];
[options setCodecOptionIntValue:8 forKey:@"skip_frame"];
[options setFormatOptionValue:@"nobuffer" forKey:@"fflags"];
[options setFormatOptionValue:@"8192" forKey:@"probsize"];
[options setFormatOptionIntValue:0 forKey:@"auto_convert"];
[options setFormatOptionIntValue:1 forKey:@"reconnect"];
[options setPlayerOptionIntValue:1 forKey:@"videotoolbox"];
// 帧速率(fps) (可以改,确认非标准桢率会导致音画不同步,所以只能设定为15或者29.97)
[options setPlayerOptionIntValue:29.97 forKey:@"r"];
// -vol——设置音量大小,256为标准音量。(要设置成两倍音量时则输入512,依此类推
[options setPlayerOptionIntValue:512 forKey:@"vol"];
_player = [[IJKFFMoviePlayerController alloc] initWithContentURL:self.url withOptions:options];
4、对FFmpeg瘦身
优化完ijkplayer之后,发现了编译出来的Framework接近100M!,由于Camera的视频流编码格式为MJPEG,而且只使用rtsp,并且没有音频,那我们可以关闭没有用到的编码器和协议,还有,我们直接关闭音频的支持,最后优化过的module-lite.sh文件如下,编译出来的Framework只有23M,简直完美。
#! /usr/bin/env bash
#--------------------
# Standard options:
export COMMON_FF_CFG_FLAGS=
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --prefix=PREFIX"
# Licensing options:
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-gpl"
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-version3"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-nonfree"
# Configuration options:
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-static"
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-shared"
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-small"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-runtime-cpudetect"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-gray"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-swscale-alpha"
# Program options:
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-programs"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-ffmpeg"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-ffplay"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-ffprobe"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-ffserver"
# Documentation options:
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-doc"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-htmlpages"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-manpages"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-podpages"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-txtpages"
# Component options:
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-avdevice"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-avcodec"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-avformat"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-avutil"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-swresample"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-swscale"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-postproc"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-avfilter"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-avresample"
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-pthreads"
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-w32threads"
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-os2threads"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-network"
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-dct"
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-dwt"
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-lsp"
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-lzo"
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-mdct"
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-rdft"
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-fft"
# Hardware accelerators:
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-d3d11va"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-dxva2"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-vaapi"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-vda"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-vdpau"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-videotoolbox"
# Individual component options:
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-everything"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-encoders"
# ./configure --list-decoders
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-decoders"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=mjpeg"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-hwaccels"
# ./configure --list-muxers
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-muxers"
# ./configure --list-demuxers
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-demuxers"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-demuxer=mjpeg"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-demuxer=rtsp"
# ./configure --list-parsers 字幕
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-parsers"
# ./configure --list-bsf 比特流滤镜(过滤器)
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-bsfs"
# ./configure --list-protocols
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-protocols"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-protocol=async"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-protocol=rtp"
#
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-devices"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-filters"
# External library support:
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-iconv"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-audiotoolbox"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-videotoolbox"