iOS直播之ijkplayer的集成与简单使用(播放)
前言
下一个项目有一个直播的功能,所以需要提前研究一下,直接集成FFmpeg比较复杂坑也比较多(我是道听途说的自己没有尝试😂),朋友推荐了ijkplayer、七牛和vlc,于是我花了两天时间研究了一下ijkplayer,过程非常坎坷,遇到的问题不下10个,中间曾一度想过放弃然后换其他的,但是看了一些文章之后还是从头到尾做出来了,做事也算是有始有终,给自己一个赞😁。其实集成的过程还是比较简单的,按照教程一步一步来就可以了,如果正常的话可能一两个小时就搞定了,我主要是想把我遇到的问题以及解决方法记录一下与大家共同学习提高!
环境准备
集成ijkplayer需要电脑中安装git
和yasm
,然后好像还需要一个pkg-config
(不确定),安装git
、yasm
和pkg-config
可以使用homebrew
。
检查自己电脑是不是安装了homebrew
、git
、yasm
可以打开终端依次输入:
brew -v
git --version
yasm --version
pkg-config --verison
我的已经安装了
环境配置成功
安装成功可以忽略以下内容直接查看第一章节,如果没有安装成功请继续,首先打开终端
安装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
方式继续执行可能出错⚠️
//克隆仓库到指定位置并重命名为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
仓库clone成功
然后进入文件夹ijkplayer-ios
cd ijkplayer-ios
新建分支latest
并切换到新建的分支上
git checkout -B latest k0.8.8
我们平时开发最好不要在
master
分支上直接开发,所以这里我按照教程新建了分支latest
。但是我们不需要提交代码,所以这里不新建分支也是可以的,新建与否都对后续各步骤没有影响。
可以使用命令查看当前分支
git branch
可以看到当前有了两个分支latest
和master
,并且当前工作在latest
分支上
配置编解码器格式支持
默认为最少支持, 如果足够你使用, 可以跳过这一步. 否则可以改为以下配置:
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 //时间稍长一些
下载`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....
去掉armv7支持 去掉armv7支持 去掉armv7支持最新的 Xcode 已经弱化了对 32 位的支持, 解决方法:
在compile-ffmpeg.sh
中删除armv7
, 修改如:
FF_ALL_ARCHS_IOS8_SDK="arm64 i386 x86_64"
再重新执行出现错误的命令:./compile-ffmpeg.sh all
然后再次执行
./compile-ffmpeg.sh clean
./compile-ffmpeg.sh all //编译
编译成功
打开ios/IJKMediaPlayer
并运行
添加 openssl
相关包以支持https
如果不使用
https
, 可以跳过此步, 直接开始打包framwork
如果使用
https
, 那么需要手动给IJKMediaFramework
添加libcrypto.a
和libssl.a
文件, 默认不会添加
步骤一 步骤二ps: 这两个依赖库的目录为:
ijkplayer-ios/ios/build/universal/lib
, 只有进行了上面跟openssl
相关的操作, 才会在这个目录下有生成libcrypto.a
和libssl.a
然后以此打开build
->universal
->lib
选择libcrypto.a
和libssl.a
打开工程可以看到
编译FFmpeg成功
四、打包 framwork
target
大家会发现除了
IJKMediaFramework
这个target
, 还有一个叫IJKMediaFrameworkWithSSL
, 但是不推荐使用这个, 因为大部分基于ijkplayer
的第三方框架都是使用的前者, 你把后者导入项目还是会报找不到包的错误, 就算你要支持https
也推荐使用前者, 然后按照上一步添加openssl
即可支持
首先将debug
改为release
debug改为release
分别编译模拟器和真机
编译模拟器 编译真机编译的时候可能会遇到两个问题,按照步骤注释掉就可以了
注释代码 注释代码注释掉这两行代码之后再分别选择真机和模拟器进行编译command+b
成功之后可以看到
编译成功了
选中IJKMediaFramework.framework
右键show in finder
可以看到
合并真机和模拟器的framework
,我们要合并的其实是这两个文件
合并
首先我们cd到products
文件夹中
然后执行: lipo -create 真机framework路径 模拟器framework路径 -output 合并的文件路径
lipo -create Release-iphoneos/IJKMediaFramework.framework/IJKMediaFramework Release-iphonesimulator/IJKMediaFramework.framework/IJKMediaFramework -output IJKMediaFramework
可以看到在products
文件夹中生成了一个framework
文件
替换掉Release-iphoneos
中的IJKMediaFramework
,如图
五、集成framwork
并测试
新建工程并导入IJKMediaFramework.framework
以及其他依赖库
新建控制器playerViewController
然后从ViewController.swift
中push
或者模态推出控制器进行测试,如果直接在跟控制器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() //销毁
}
}
大功告成😁
可以直播
demo地址https://github.com/jzglovewjr/ijk
参考地址
homebrew
的安装和使用:
https://blog.csdn.net/sir_coding/article/details/77509602
git
报错:
https://blog.csdn.net/it_liuchengli/article/details/77040806
执行./compile-ffmpeg.sh all
报错 :
https://github.com/Bilibili/ijkplayer/issues/1160
armv7
支持问题以及https
支持问题:
https://www.jianshu.com/p/9743a68c2939