美文网首页OC音视频程序员
iOS视频直播:比较详细的IJKPlay集成攻略

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

作者: Samson_Xu | 来源:发表于2017-11-23 14:35 被阅读466次

    前言:刚来公司时,就接手了直播功能版块的开发。推拉流走通了,逻辑框架和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,里面写的很详细。

    相关文章

      网友评论

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

        本文链接:https://www.haomeiwen.com/subject/cuoavxtx.html