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中提示步骤:

iOS视频直播:比较详细的IJKPlay集成攻略_第1张图片
15281511405703_.pic_hd.jpg

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


    iOS视频直播:比较详细的IJKPlay集成攻略_第2张图片
    281511406394_.pic.jpg
  2. 执行./init-ios.sh命令(等待下载···):


    iOS视频直播:比较详细的IJKPlay集成攻略_第3张图片
    291511406757_.pic_hd.jpg

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


iOS视频直播:比较详细的IJKPlay集成攻略_第4张图片
321511406885_.pic_hd.jpg
  1. cd到ios文件夹下:


    iOS视频直播:比较详细的IJKPlay集成攻略_第5张图片
    331511407052_.pic_hd.jpg
  2. 依次执行:./compile-ffmpeg.sh clean 和 ./compile-ffmpeg.sh all命令(等待编译ffmpeg···),过程比较久,要耐心等待一会


    iOS视频直播:比较详细的IJKPlay集成攻略_第6张图片
    351511407246_.pic_hd.jpg
  3. 进程结束后,查看是否编译成功:


    iOS视频直播:比较详细的IJKPlay集成攻略_第7张图片
    361511407709_.pic_hd.jpg
  4. 打开IJKPlayerDemo,进行编译:


    iOS视频直播:比较详细的IJKPlay集成攻略_第8张图片
    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


    iOS视频直播:比较详细的IJKPlay集成攻略_第9张图片
    381511408585_.pic_hd.jpg

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


iOS视频直播:比较详细的IJKPlay集成攻略_第10张图片
391511408751_.pic.jpg
  1. 将编译环境调成release模式:
iOS视频直播:比较详细的IJKPlay集成攻略_第11张图片
401511409209_.pic_hd.jpg
iOS视频直播:比较详细的IJKPlay集成攻略_第12张图片
411511409311_.pic_hd.jpg
  1. 分别在真机和模拟器上进行编译,机型不限。

    如果编译报错“library not found for -lcrypto”,说明缺少文件
    421511413966_.pic.jpg
iOS视频直播:比较详细的IJKPlay集成攻略_第13张图片
431511414031_.pic_hd.jpg

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


iOS视频直播:比较详细的IJKPlay集成攻略_第14张图片
441511414573_.pic_hd.jpg

添加文件:


iOS视频直播:比较详细的IJKPlay集成攻略_第15张图片
471511414848_.pic_hd.jpg
iOS视频直播:比较详细的IJKPlay集成攻略_第16张图片
461511414831_.pic_hd.jpg

再次编译。

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


    iOS视频直播:比较详细的IJKPlay集成攻略_第17张图片
    481511415200_.pic_hd.jpg
  2. 将真机和模拟器上编译生成的文件进行合并,要合并的文件在图中进行了标记:


    iOS视频直播:比较详细的IJKPlay集成攻略_第18张图片
    491511415276_.pic_hd.jpg
iOS视频直播:比较详细的IJKPlay集成攻略_第19张图片
501511415331_.pic_hd.jpg

在终端执行合成命令:

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

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

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


iOS视频直播:比较详细的IJKPlay集成攻略_第20张图片
511511416000_.pic_hd.jpg

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

iOS视频直播:比较详细的IJKPlay集成攻略_第21张图片
521511416273_.pic_hd.jpg

五. 将IJKPlayer集成到项目中

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


    iOS视频直播:比较详细的IJKPlay集成攻略_第22张图片
    531511416591_.pic_hd.jpg
  2. 编译查看是否报错:

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

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

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

iOS视频直播:比较详细的IJKPlay集成攻略_第23张图片
541511416828_.pic_hd.jpg
  1. 运行时crash,提示:dyld: Library not loaded: @rpath xxx reason: image not found
    出现这种错误,是因为在运行时没有找到framewok对应的包,如果运行到这个包时,就会崩溃。

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


iOS视频直播:比较详细的IJKPlay集成攻略_第24张图片
551511417370_.pic_hd.jpg
iOS视频直播:比较详细的IJKPlay集成攻略_第25张图片
561511417418_.pic_hd.jpg
iOS视频直播:比较详细的IJKPlay集成攻略_第26张图片
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];
}

运行效果:

iOS视频直播:比较详细的IJKPlay集成攻略_第27张图片
Simulator Screen Shot - iPhone 6 - 2017-11-23 at 14.22.45.png
QQ20171123-143125.gif

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

你可能感兴趣的:(iOS视频直播:比较详细的IJKPlay集成攻略)