iOS视频直播:比较详细的IJKPlay集成攻略

前言:刚来公司时,就接手了直播功能版块的开发。推拉流走通了,逻辑框架和UI界面也都搭好了,但是因为资源问题,老板决定放弃这个版块。😑
当时用的是网易云直播的sdk,没有集成IJKPlay,最近空闲时间比较多,就集成了一下IJKPlayer,使用很方便,集成起来会麻烦一点


简述下直播原理:
一个完整的直播程序,包括音视频采集/处理,视频转码,解码拉取等。概括来说,要有下面几个环节进行配合:
推流端:采集主播的音视频信息,进行美颜、变声、信息编码,将媒体流推流至服务器。
服务器端:对媒体流进行转码,录制等处理,分发数据。
拉流端:从服务器拉取媒体流,进行解码、渲染、提供音视频播放环境。
互动系统:聊天室、弹幕、点赞。

其中核心环节无外乎就是 推/拉流 过程,集成IJKPlayer,可以方便我们在这一步骤上所做的处理。

一. 什么是IJKPlayer?
 ijkplayer是B站的一款开源框架,专门用来做视频直播,基于ffmpeg,同时支持 Android 和 iOS 平台。
  对于 App 中的直播功能,如果我们成功集成ijkplayer ,那么只要得到一个拉流 URL,就能实现简单的音视频直播功能了。

二. 下载IJKPlayer
IJKPlayer下载地址

三. 运行demo,编译IJKPlayer
下载IJKPlayer时,在README里面已经告诉了我们应该如何集成IJKPlayer,所以在编译demo前,应当在终端中按照图中步骤进行相应操作,如果没有按照上面的提示步骤,而是直接运行demo,因为缺少文件,编译器就会报错,
readme中提示步骤:

15281511405703_.pic_hd.jpg

  1. 打开终端,cd到IJKPlayer文件夹:


    281511406394_.pic.jpg
  2. 执行./init-ios.sh命令(等待下载···):


    291511406757_.pic_hd.jpg

进程结束后,会发现extra文件夹下会多出这两个文件:


321511406885_.pic_hd.jpg
  1. cd到ios文件夹下:


    331511407052_.pic_hd.jpg
  2. 依次执行:./compile-ffmpeg.sh clean 和 ./compile-ffmpeg.sh all命令(等待编译ffmpeg···),过程比较久,要耐心等待一会


    351511407246_.pic_hd.jpg
  3. 进程结束后,查看是否编译成功:


    361511407709_.pic_hd.jpg
  4. 打开IJKPlayerDemo,进行编译:


    371511408035_.pic_hd.jpg

四. 打包IJKPlayer进行集成
集成IJKPlayer有两种方式:

  1. 按照README中的方法,和demo中一样,将IJKMediaPlayer.xcodeproj导入到我们自己的项目中,直接按照README中的提示进行操作,这里不做多余赘述。
# Demo
#     open ios/IJKMediaDemo/IJKMediaDemo.xcodeproj with Xcode
# 
# Import into Your own Application
#     Select your project in Xcode.
#     File -> Add Files to ... -> Select ios/IJKMediaPlayer/IJKMediaPlayer.xcodeproj
#     Select your Application's target.
#     Build Phases -> Target Dependencies -> Select IJKMediaFramework
#     Build Phases -> Link Binary with Libraries -> Add:
#         IJKMediaFramework.framework
#
#         AudioToolbox.framework
#         AVFoundation.framework
#         CoreGraphics.framework
#         CoreMedia.framework
#         CoreVideo.framework
#         libbz2.tbd
#         libz.tbd
#         MediaPlayer.framework
#         MobileCoreServices.framework
#         OpenGLES.framework
#         QuartzCore.framework
#         UIKit.framework
#         VideoToolbox.framework
#
#         ... (Maybe something else, if you get any link error)
# 
  1. 将IJKPlayer打包成framework,导入到项目中:
  2. 打开IJKMediaPlayer.xcodeproj


    381511408585_.pic_hd.jpg

注:这里有两个target,IJKMediaFramework 和 IJKMediaFrameworkWithSSL,在支持https的情况下,我们选择IJKMediaFrameworkWithSSL进行编译:


391511408751_.pic.jpg
  1. 将编译环境调成release模式:
401511409209_.pic_hd.jpg
411511409311_.pic_hd.jpg
  1. 分别在真机和模拟器上进行编译,机型不限。

    如果编译报错“library not found for -lcrypto”,说明缺少文件
    421511413966_.pic.jpg
431511414031_.pic_hd.jpg

解决方法:我的解决方法是下载libcrypto和libssl文件拷贝到当前项目下。
我在电脑上全局搜这两个文件,发现之前的第三方里有这两个文件,就直接拿来用了:
拷贝到文件夹下


441511414573_.pic_hd.jpg

添加文件:


471511414848_.pic_hd.jpg
461511414831_.pic_hd.jpg

再次编译。

  1. 编译成功后,进入Finder中,查看编译结果:


    481511415200_.pic_hd.jpg
  2. 将真机和模拟器上编译生成的文件进行合并,要合并的文件在图中进行了标记:


    491511415276_.pic_hd.jpg
501511415331_.pic_hd.jpg

在终端执行合成命令:

 lipo -create 真机版本编译后文件路径 模拟器版本编译后文件路径 -output 合成后路径(这里我放在Products文件夹下)

注: 合成后路径指的是:合成后所放的文件夹/合成后的文件名,这里我把合成后文件命名为:“IJKMediaFrameWithSSL”,合成后路径为:/Build/Products/IJKMediaFrameWithSSL

执行完成后,在Products文件夹下看到新的合成文件:


511511416000_.pic_hd.jpg

使用新的合成文件,替换掉真机版本编译后文件路径下的文件:

521511416273_.pic_hd.jpg

五. 将IJKPlayer集成到项目中

  1. 将打包好的IJKPlayer静态库和一些依赖库添加到项目中:


    531511416591_.pic_hd.jpg
  2. 编译查看是否报错:

这里暂时发现的有两个错误:

1、xxx does not contain bitcode:
xcode默认开启了bitcode,如果我们集成的库没有bitcode编译的包,则有可能出现报错。

解决方法:target-->build setting-->enable bitcode-->NO

541511416828_.pic_hd.jpg
  1. 运行时crash,提示:dyld: Library not loaded: @rpath xxx reason: image not found
    出现这种错误,是因为在运行时没有找到framewok对应的包,如果运行到这个包时,就会崩溃。

解决方法:
手动添加framework到项目中:


551511417370_.pic_hd.jpg
561511417418_.pic_hd.jpg
571511417463_.pic_hd.jpg

六. 模仿demo,进行测试:

这里我写了一个tableView,链接到不同的拉流地址:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    NSURL *url = [NSURL URLWithString:_dataArray[indexPath.row]];
    
    NSString *scheme = [[url scheme]lowercaseString];
    
    if ([scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"] || [scheme isEqualToString:@"rtmp"]) {
        
        [XSIJKMediaPlayerViewController presentFromViewController:self withTitle:@"Livestream" URL:_dataArray[indexPath.row] completion:nil];
    }
    
}

放入测试地址:

- (void)requestData{
    
    NSArray *urls = @[@"rtmp://live.hkstv.hk.lxdns.com/live/hks",@"http://wzfree.10043.doftp.com/tvtest/182tv.php/live/id/suntv.m3u8",@"invalidUrl"];
    _dataArray = [[NSMutableArray alloc]initWithArray:urls];
    
    [_tableView reloadData];
    
}

在直播页面的ViewController中进行配置:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    
    self.view.backgroundColor = [UIColor grayColor];
#ifdef DEBUG
    //设置是否打印信息
    [IJKFFMoviePlayerController setLogReport:YES];
    
    [IJKFFMoviePlayerController setLogLevel:k_IJK_LOG_DEBUG];
    
#else
    [IJKFFMoviePlayerController setLogReport:NO];
    [IJKFFMoviePlayerController setLogLevel:k_IJK_LOG_INFO];
#endif
    
    [IJKFFMoviePlayerController checkIfFFmpegVersionMatch:YES];
    
    //配置参数:数据处理、videotoolbox解码、设置音视频属性参数设置
    IJKFFOptions *options = [IJKFFOptions optionsByDefault];
    
    self.player = [[IJKFFMoviePlayerController alloc]initWithContentURL:self.url withOptions:options];
    self.player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
    self.player.view.frame = self.view.bounds;
    self.player.scalingMode = IJKMPMovieScalingModeAspectFit;
    self.player.shouldAutoplay = YES;
    
    self.view.autoresizesSubviews = YES;
    [self.view addSubview:self.player.view];
    
    UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(20, 20, 40, 40)];
    [btn setTitle:@"返回" forState:UIControlStateNormal];
    [btn addTarget:self action:@selector(leftClick) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn];
}

运行效果:

Simulator Screen Shot - iPhone 6 - 2017-11-23 at 14.22.45.png
QQ20171123-143125.gif

这里只写了简单的拉流,代码很简单,就不上demo了,其他相关代码可以看IJKPlayer的demo,里面写的很详细。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容