ijkplayer直播项目总结:

一:ijkplayer接入进坑和出坑;

1,首先是加密过程,如果通过修改ijkplayer底层代码,对ios这这边,如果修改完代码需要动态传参到修改过的源码中,同时又要可以通过打包后的framework调用,那就需要通过建立java和c以及oc之间的桥接引出,说的这么高端,通俗点说,就是要一层层引出调用函数具体做法:
比如:在libavformat/avformat.h中声明了:

int avformat_hls_set_abc_efg(unsigned char* key,int key_size);

在 libavformat/hls.c中实现了

int avformat_hls_set_abc_efg(unsigned char* key,int key_size){
    }

这个时候如何引出呢:
首先在:ff_ffplay.h中添加:

void ffp_hls_abc_efg(const unsigned char* buf,int buf_size);

这个函数名可以自己随便起:
在:ff_ffplay.c中添加实现:

void ffp_hls_abc_efg(const unsigned char* buf,int buf_size){
    avformat_hls_set_abc_efg(buf,buf_size);
}

这里必须对应;
接着:ijkplayer.h和ijkplayer.c中添加方法,
这里都是自定义的方法:可以自己写,目的就是往外倒出源码中的方法和对其传值:
.h中:

void ijkmp_hls_abc_efg(const unsigned char* buf,int buf_size);

.m中:

void ijkmp_hls_abc_efg(const unsigned char* buf,int buf_size){
    ffp_hls_abc_efg(buf, buf_size);//这个方法就是ff_ffplay中的方法
}

再接着接可以在oc代码中引出了:
IJKFFOptions.h和IJKFFOptions.m中添加方法,这里就是OC代码了:
.h中声明:

- (void)setAbckd..Key:(const unsigned char *)key bitAbcLenth:(int)bit;

.m

- (void)setAbckd..Key:(const unsigned char *)key bitAbcLenth:(int)bit{
    ijkmp_hls_abc_efg(key, bit);//这里就是ijkplayer.h中定义的方法
}

到此,就可以通过framework 进行调用了。

2,编译过程中,如果需要支持https或者需要支持加解密对话,在module.sh中:需要添加:

export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-openssl"

但是,很重要,如果报错,可以替换成:

#export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-protocol=crypto" 

本人就是报错,经过多出查找,换了这句话,编译通过,视频可以加解密

如果用的是ffmpeg4.0 需要添加:

#export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-bsf=eac3_core"

额外说一下:这两句话,一般不用管:

#export·COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-protocol=rtp"
#export·COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-demuxer=rtsp"

加上容易出错,如果不出错的话,可以加上,没太大影响;

3,如果遇见如:之前用ip地址加解密都可以拉流,但是换成域名就拉流失败,很可能是重定向,再例如当视频地址相同,只有端口不同时,视频重复或拉流失败等,可以考虑升级ffmpng4.0,(具体做法,自己百度这里只说一点:就是修改init-ios.sh中:IJK_FFMPEG_COMMIT=ff4.0--ijk0.8.8--20210426--001,你自己百度,估计ijk这个库)或者先麻烦的话,可以先考虑下载最新的ffmpng替换一下文件:

ios/ffmpeg-arm64/libavformat/tcp.c

ios/ffmpeg-arm64/libavutil/dns_cache.c  

ios/ffmpeg-arm64/libavutil/dns_cache.h。

如果还不行,只能替换4.0试试;

3,平台支持:

修改init-ios.sh中

FF_ALL_ARCHS_IOS8_SDK="arm64 x86_64"

FF_ALL_ARCHS=$FF_ALL_ARCHS_IOS8_SDK

可以自行添加删除

4,ijkplayer编译后找不到framework,

路径:Xcode/DerivedData/IJKMediaPlayer/Build/Products/Release-iphoneos/IJKMediaFrameworkWithSSL.framework

二:开发过程中

1,拉流或播放url包含字符串播放不了的问题,需要进行字符串编码,但是如果正常的字符串,进行编码,很可能正常的也不行了,这个需要进行判断,具体代码:

+ (NSString *)isEncodingChinese:(NSString *)str {

 NSString *newString = str;

 //遍历字符串中的字符

 for(int i=0; i< [str length];i++){

 int a = [str characterAtIndex:i];

 //汉字的处理

 if( a > 0x4e00 && a < 0x9fff)

 {

 NSString *oldString = [str substringWithRange:NSMakeRange(i, 1)];

 NSString *string = [oldString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

 newString = [newString stringByReplacingOccurrencesOfString:oldString withString:string];

 }

 //空格处理

 if ([newString containsString:@" "]) {

 newString = [newString stringByReplacingOccurrencesOfString:@" " withString:@"%20"];

 }

 //如果需要处理其它特殊字符,在这里继续判断处理即可.

 }

 return newString;

}

2,推流过程:如果不限制,预览可能会横屏,比较难看:解决办法:

 [self.engine startPreview:self.renderView];

 [self.engine setDeviceOrientationMode:AliLiveOrientationModePortrait];

切记顺序不能变,顺序不能变,否则不起作用

3,阿里推流SDK遇见在直播预览界面内存泄漏问题:进过查找,发现是项目中使用了数组和Object分类的runtime,导致了不释放问题,排查过程:自己先去下载了一个官方sdk,里边的demo运行正常;然后自己惊醒sdk升级,还是泄漏,排除了sdk问题,接下来,要排除是否是自己开播界面的VC写的问题,然后自己简单按照demo重新写一个简单的开播VC,在自己项目中和demo中分别使用,发现进入这个新的vc中,自己项目已久内存泄漏,放入sdkdemo中,正常使用,说明自己写的vc没问题,感觉经验,锁定在了runtime造成的,估计也只能是runtime成造成这种问题。排除方法,就是找类似数组,字典,Object的分类,切使用了+(void)load方法的分类,然后把这些先去掉,运行,最终果然不出意料,找到了,因为添加了数组安全函数造成的。

4,SJVideoPlayer:

 _player.rotationManager.disabledAutorotation = YES;

禁止自动转屏

5,如果用SJVideoPlayer,且使用的是ijkplayerssl内核的话:

如果视频需要解密,重播的时候会出错:原因:由于第一次进入,你设置了播放密钥,但是重播过程中:说白了,他的内部还是调用的播放,此时只是播放,你在之前设置的密钥配置在第二次播放的时候如果不再重新设置密钥,ijkplayer是拿不到密钥的,他会按照默认状态进行播放,没有了密钥设置,因此失败,这也是我个人遇见的问题,发现,有的视频可以重播,有的不能,最后发现了问题,在重播的时候需要重新设置密钥才能正常重播;

6,如何拿到SJVideoPlayer按钮的点击事件:

例如拿到上边的重播按钮点击事件如下:

SJEdgeControlButtonItem *playItemTT = [weakSelf.player.defaultEdgeControlLayer.centerAdapter itemForTag:SJEdgeControlLayerCenterItem_Replay];

 [playItemTT addTarget:self.action:@selector(myReplay)];

其他按钮事件,只需要更换tag就ok了,

如有错误还请大家指出,我也是菜鸟一个,只是自己进的坑,和自己一点点踩出来的,也感谢社区的其他朋友让我一点点爬出了这么多坑。

你可能感兴趣的:(ijkplayer直播项目总结:)