iOS集成ijkplayer

原链接

前言

下一个项目有一个直播的功能,所以需要提前研究一下,直接集成FFmpeg比较复杂坑也比较多(我是道听途说的自己没有尝试😂),朋友推荐了ijkplayer、七牛和vlc,于是我花了两天时间研究了一下ijkplayer,过程非常坎坷,遇到的问题不下10个,中间曾一度想过放弃然后换其他的,但是看了一些文章之后还是从头到尾做出来了,做事也算是有始有终,给自己一个赞😁。其实集成的过程还是比较简单的,按照教程一步一步来就可以了,如果正常的话可能一两个小时就搞定了,我主要是想把我遇到的问题以及解决方法记录一下与大家共同学习提高!

环境准备

集成ijkplayer需要电脑中安装gityasm,然后好像还需要一个pkg-config(不确定),安装gityasmpkg-config可以使用homebrew

检查自己电脑是不是安装了homebrewgityasm可以打开终端依次输入:

brew -v
git --version
yasm --version
pkg-config --verison 

我的已经安装了

img

环境配置成功

安装成功可以忽略以下内容直接查看第一章节,如果没有安装成功请继续,首先打开终端

安装homebrew:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

如果想卸载homebrew

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)"

homebrew的用法:

安装软件,如:brew install oclint
卸载软件,如:brew uninstall oclint
搜索软件,如:brew search oclint
更新软件,如:brew upgrade oclint
查看安装列表, 如:brew list
更新Homebrew,如:brew update

使用homebrew安装git
brew install git
使用homebrew安装yasm
brew install yasm
使用homebrew安装pkg-config
brew install pkg-config

一、使用git克隆仓库到本地

ijkplayer是bilibili的一个开源项目https://github.com/Bilibili/ijkplayer
在合适的位置新建文件夹(不想新建也可以的😂),我是在桌面上新建文件夹命名为showcase,然后进入对应文件夹

cd /Users/jizhigang/Desktop/showcase //这是我的路径啊看准喽

clone一个仓库有两种方式,使用https方式和SSH方式,我们选择https方式,使用SSH方式继续执行可能出错⚠️

img

使用https地址

//克隆仓库到指定位置并重命名为ijkplayer-ios
git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-ios

有时候clone仓库时会出现问题

error: RPC failed; curl 18 transfer closed with outstanding read data remaining
    fatal: The remote end hung up unexpectedly
    fatal: early EOF
    fatal: index-pack failed

这个错误是因为项目太久,tag资源文件太大,我们clone时可以这样

//克隆仓库到指定位置并重命名为ijkplayer-ios,深度为1的代码,具体什么意思我不是特别清楚就不乱解释了啊,免得误导别人
git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-ios --depth=1

img

仓库clone成功

然后进入文件夹ijkplayer-ios

cd ijkplayer-ios

新建分支latest并切换到新建的分支上

git checkout -B latest k0.8.8

我们平时开发最好不要在master分支上直接开发,所以这里我按照教程新建了分支latest。但是我们不需要提交代码,所以这里不新建分支也是可以的,新建与否都对后续各步骤没有影响。

可以使用命令查看当前分支

git branch

可以看到当前有了两个分支latestmaster,并且当前工作在latest分支上

img

分支创建并切换成功

配置编解码器格式支持

默认为最少支持, 如果足够你使用, 可以跳过这一步. 否则可以改为以下配置:

module-default.sh 更多的编解码器/格式
module-lite-hevc.sh 较少的编解码器/格式(包括hevc)
module-lite.sh 较少的编解码器/格式(默认情况)

# 进入 config 目录
cd config

# 删除当前的 module.sh 文件
rm module.sh

# 可根据需要替换为`module-default.sh`, `module-lite-hevc.sh`, `module-lite.sh`
# 创建软链接 module.sh 指向 module-lite-hevc.sh
ln -s module-lite-hevc.sh module.sh

cd ..
cd ios
sh compile-ffmpeg.sh clean

二、下载ffmpeg

./init-ios.sh //时间稍长一些

img

下载ffmpeg成功

添加 https 支持

最后会生成支持 https 的静态文件 libcrypto.a 和 libssl.a, 如果不需要可以跳过这一步

# 获取 openssl 并初始化
./init-ios-openssl.sh

cd ios

# 在模块文件中添加一行配置 以启用 openssl 组件
echo 'export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-openssl"' >> ../config/module.sh

./compile-ffmpeg.sh clean

然后进入ios文件夹中

cd ios

三、 编译ffmpeg

# 如果下一步提示错误`xcrun: error: SDK "iphoneos" cannot be located`, 请执行`sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer/`, 再重新执行下一步

# 编译openssl, 如果不需要https可以跳过这一步
./compile-openssl.sh all

./compile-ffmpeg.sh clean
./compile-ffmpeg.sh all //编译

这里有可能遇到错误

xcrun -sdk iphoneos clang is unable to create an executable file.
C compiler test failed.

造成这个问题的原因有很多,这里我是因为xcode路径问题引起的,解决方法:

sudo /usr/bin/xcode-select -switch /Applications/Xcode.app/Contents/Developer

这里还遇到了另一个问题

AS  libavcodec/arm/aacpsdsp_neon.o
./libavutil/arm/asm.S:50:9: error: unknown directive
        .arch armv7-a
        ^
make: *** [libavcodec/arm/aacpsdsp_neon.o] Error 1
make: *** Waiting for unfinished jobs....

最新的 Xcode 已经弱化了对 32 位的支持, 解决方法:
compile-ffmpeg.sh 中删除 armv7 , 修改如:
FF_ALL_ARCHS_IOS8_SDK="arm64 i386 x86_64"
再重新执行出现错误的命令: ./compile-ffmpeg.sh all

img

去掉armv7支持

img

去掉armv7支持

img

去掉armv7支持

然后再次执行

./compile-ffmpeg.sh clean
./compile-ffmpeg.sh all //编译

img

编译成功

打开ios/IJKMediaPlayer并运行

添加 openssl相关包以支持https

如果不使用 https, 可以跳过此步, 直接开始打包 framwork

如果使用 https, 那么需要手动给IJKMediaFramework添加 libcrypto.alibssl.a 文件, 默认不会添加

ps: 这两个依赖库的目录为:ijkplayer-ios/ios/build/universal/lib, 只有进行了上面跟 openssl 相关的操作, 才会在这个目录下有生成libcrypto.alibssl.a

img

步骤一

img

步骤二

然后以此打开build->universal->lib选择libcrypto.alibssl.a

img

步骤三

打开工程可以看到

img

编译FFmpeg成功

四、打包 framwork

img

target

大家会发现除了 IJKMediaFramework这个target, 还有一个叫 IJKMediaFrameworkWithSSL, 但是不推荐使用这个, 因为大部分基于 ijkplayer 的第三方框架都是使用的前者, 你把后者导入项目还是会报找不到包的错误, 就算你要支持 https 也推荐使用前者, 然后按照上一步添加 openssl即可支持

首先将debug改为release

img

debug改为release

分别编译模拟器和真机

img

编译模拟器

img

编译真机

编译的时候可能会遇到两个问题,按照步骤注释掉就可以了

img

注释代码

img

注释代码

注释掉这两行代码之后再分别选择真机和模拟器进行编译command+b

成功之后可以看到

img

编译成功了

选中IJKMediaFramework.framework右键show in finder可以看到

img

编译成功了

合并真机和模拟器的framework,我们要合并的其实是这两个文件

img

合并

首先我们cd到products文件夹中

img

进入products文件夹

然后执行: lipo -create 真机framework路径 模拟器framework路径 -output 合并的文件路径

lipo -create Release-iphoneos/IJKMediaFramework.framework/IJKMediaFramework Release-iphonesimulator/IJKMediaFramework.framework/IJKMediaFramework -output IJKMediaFramework

可以看到在products文件夹中生成了一个framework文件

img

合并

替换掉Release-iphoneos中的IJKMediaFramework,如图

img

替换IJKMediaFramework

五、集成framwork并测试

新建工程并导入IJKMediaFramework.framework以及其他依赖库(注意加上:libc++.tdb)

img

集成

新建控制器playerViewController然后从ViewController.swiftpush或者模态推出控制器进行测试,如果直接在跟控制器ViewController.swift中测试可能会有只出声音没有影像的问题

import UIKit

class playerViewController: UIViewController {

    var iPlayer:IJKFFMoviePlayerController? 
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let options:IJKFFOptions = IJKFFOptions.byDefault()
        let url:URL = URL.init(string: "rtmp://live.hkstv.hk.lxdns.com/live/hks")!
 
        
        self.iPlayer = IJKFFMoviePlayerController.init(contentURL: url, with: options)
        var arm1 = UIViewAutoresizing.init(rawValue: 0)
        arm1.insert(UIViewAutoresizing.flexibleWidth)
        arm1.insert(UIViewAutoresizing.flexibleHeight) 
        self.iPlayer?.view.autoresizingMask = arm1
        self.iPlayer?.view.backgroundColor = UIColor.white
        self.iPlayer?.view.frame = CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 300)
        self.iPlayer?.scalingMode = .aspectFit
        self.iPlayer?.shouldAutoplay = true
        self.view.autoresizesSubviews = true
        self.view.addSubview((self.iPlayer?.view)!)
        
        // Do any additional setup after loading the view, typically from a nib.
    }
    
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.iPlayer?.prepareToPlay() //准备
        self.iPlayer?.play() //播放
    }
    
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        self.iPlayer?.pause()//暂停
//        self.iPlayer?.shutdown() //销毁
    }

}

大功告成😁

img

可以直播

posted @ 2020-05-19 15:07  mustard22  阅读(644)  评论(0)    收藏  举报