環(huán)境
- mac版本:MacBook Pro(Apple M1 Pro) M1芯片
- Xcode版本:15.4
拉取代碼
按照 blibili官方開源庫ijkplayer README中iOS配置步驟進行配置。
# 先切到一個文件夾下
cd Desktop/
# 克隆ijkplayer的代碼
git clone https://github.com/Bilibili/ijkplayer.git
# cd到拉下來的ijkplayer中
cd ijkplayer
# 切到最新版本k0.8.8(可在官方tags中查看最新版本)
git checkout -B latest k0.8.8
項目拉下來后文件結(jié)構(gòu)如下:
配置解碼器類型
- module-default.sh 更多的編解碼器/格式
- module-lite-hevc.sh 較少的編解碼器/格式(包括hevc)
- module-lite.sh 較少的編解碼器/格式(默認(rèn)情況)
cd config
# 刪除默認(rèn)的解碼器
rm module.sh
# 創(chuàng)建一個軟連接指向 module-lite-hevc.sh,這個可根據(jù)自己需求進行選擇
ln -s module-lite-hevc.sh module.sh
# 回到上一層目錄
cd ..
# 進入ios目錄
cd ios
# 將compile-ffmpeg.sh腳本清空空凸,等待后期重新執(zhí)行新的腳本
sh compile-ffmpeg.sh clean
注:sh compile-ffmpeg.sh clean
同./compile-ffmpeg.sh clean
一樣澜倦,都是在當(dāng)前文件夾下執(zhí)行腳本命令
配置ffmpeg內(nèi)核版本
回到上一目錄ijkplayer
找到init-ios.sh
文件進行編輯捉蚤,可通過終端使用vi
命令進入編輯環(huán)境,再輸入i
開始編輯看尼,編輯結(jié)束后按鍵盤左上角上的esc
鍵退出編輯坦报,然后在終端中輸入:wq
進行保存并退出編輯環(huán)境, 或者找到該文件直接通過xcode
打開開始修改。
# 回到上一目錄ijkplayer
cd ..
# 編輯init-ios.sh文件
vi init-ios.sh
打開文件后可以看到如下內(nèi)容休玩,需要注意IJK_FFMPEG_COMMIT
字段著淆,該字段配置ffmpeg
版本,如果不修改哥捕,則默認(rèn)使用ff3.4--ijk0.8.7--20180103--001
版本牧抽,我們需要將其修改為ff4.0--ijk0.8.25--20200221--001
。
原本bilibili
的ffmpeg庫支持查看版本的遥赚,可惜現(xiàn)在看不到了扬舒。
#! /usr/bin/env bash
#
# Copyright (C) 2013-2015 Bilibili
# Copyright (C) 2013-2015 Zhang Rui <bbcallen@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# IJK_FFMPEG_UPSTREAM=git://git.videolan.org/ffmpeg.git
IJK_FFMPEG_UPSTREAM=https://github.com/Bilibili/FFmpeg.git
IJK_FFMPEG_FORK=https://github.com/Bilibili/FFmpeg.git
IJK_FFMPEG_COMMIT=ff4.0--ijk0.8.25--20200221--001
IJK_FFMPEG_LOCAL_REPO=extra/ffmpeg
IJK_GASP_UPSTREAM=https://github.com/Bilibili/gas-preprocessor.git
配置ffmpeg所依賴的環(huán)境
# 獲取依賴的文件,這個會久一點凫佛,中途有失敗再執(zhí)行一下就可以了
./init-ios.sh
配置支持https協(xié)議(如果不需要支持https可以跳過)
編輯ijkplayer
文件夾下的init-ios-openssl.sh
文件
vi init-ios-openssl.sh
和升級ffmpeg
類似讲坎,找到IJK_OPENSSL_COMMIT
字段,將其默認(rèn)值OpenSSL_1_0_2n
替換成OpenSSL_1_0_2u
愧薛。
配置https所需的openssl環(huán)境
# 比較耗時晨炕,耐心等待
./init-ios-openssl.sh
成功后終端輸出如下:
編輯config文件夾下的module.sh文件
vi config/module.sh
在文件的末尾加上如下兩行:
# 支持https
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-openssl"
# ffmpeg4.0 需要
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-bsf=eac3_core"
同時將以下兩行注釋掉:
#export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-ffserver"
#export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-vda"
更改最低支持的版本到8.0
因為ffmpeg4.0
使用的部分API是iOS8.0
以上的,因此需要更改最低支持的版本超過8.0
毫炉,否則編譯ffmpeg
時會出現(xiàn)如下錯誤:
libavcodec/videotoolbox.c:862:9: error: 'VTDecompressionSessionInvalidate' is only available on iOS 8.0 or newer
[-Werror,-Wunguarded-availability]
VTDecompressionSessionInvalidate(videotoolbox->session);
依次找到ios/tools
目錄下的do-compile-ffmpeg.sh
和do-compile-openssl.sh
文件瓮栗,打開文件并找到有關(guān)version-min小于8.0
的統(tǒng)一改為8.0
。
取消支持armv7編譯環(huán)境
因為使用Xcode15.4
編譯瞄勾,已經(jīng)弱化了對32位
的支持费奸,因此需要移除掉armv7
環(huán)境。如果想支持armv7
进陡,請使用低版本Xcode 例:Xcode9
編譯打包愿阐。
找到ios目錄下的compile-ffmpeg.sh
和compile-openssl.sh
文件,打開文件并將FF_ALL_ARCHS_IOS8_SDK="armv7 arm64 i386 x86_64"
修改為FF_ALL_ARCHS_IOS8_SDK="arm64 i386 x86_64"
,否則可能會在編譯ffmpeg的時候出現(xiàn)以下報錯:
./libavutil/arm/asm.S:50:9: error: unknown directive
.arch armv7-a
^
make: *** [libavcodec/arm/aacpsdsp_neon.o] Error 1
編譯openssl
cd ios
# 先編譯OpenSSL,如果不需要支持https可以跳過
./compile-openssl.sh all
編譯openssl
成功后終端輸出如下:
編譯openssl
成功后項目在ios/build
文件夾下多出了openssl-arm64
揪罕、openssl-i386
、openssl-x86_64
辛孵、universal
四個文件夾,并在universal
文件夾下的lib
文件夾中多出了libcrypto.a
和libssl.a
兩個文件
編譯ffmpeg
在編譯ffmpeg
之前需要在ios/tools
目錄中的do-compile-ffmpeg.sh
文件中增加一行FFMPEG_CFLAGS="$FFMPEG_CFLAGS -Wno-error=incompatible-function-pointer-types"
赡磅,否則會在編譯的時候提示指針問題魄缚。
# 編譯ffmpeg遇到的error問題
libavcodec/aarch64/h264dsp_init_aarch64.c:84:38: error: incompatible function pointer types assigning to 'h264_weight_func' (aka 'void (*)(unsigned char *, long, int, int, int, int)') from 'void (uint8_t *, int, int, int, int, int)' (aka 'void (unsigned char *, int, int, int, int, int)') [-Wincompatible-function-pointer-types]
c->weight_h264_pixels_tab[0] = ff_weight_h264_pixels_16_neon;
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
開始編譯ffmpeg
# 編譯ffmpeg
./compile-ffmpeg.sh all
編譯ffmpeg
成功后終端輸出如下:
編譯ffmpeg
成功后項目在ios/build
文件夾下多出了ffmpeg-arm64
、ffmpeg-i386
仆邓、ffmpeg-x86_64
鲜滩、universal
四個文件夾,并在universal
文件夾下的lib
文件夾中多出了libavcodec.a
节值、libavfilter.a
徙硅、libavformat.a
、libavutil.a
搞疗、libswresample.a
嗓蘑、libswscale.a
六個文件。
檢查項目
至此為止已經(jīng)編譯通過了匿乃,然后打開IJKMediaPlayer.xcodeproj
文件查看ffmpeg
所需要的庫是否已正確引用上
如果lib文件夾下各庫文件為紅色則表示未正確引用上
桩皿,有可能是配置ffmpeg
的步驟沒弄好,需要清空openssl
及ffmpeg
腳本重新加載幢炸。
# 清空openssl.sh腳本
./compile-openssl.sh clean
# 清空ffmpeg.sh腳本
./compile-ffmpeg.sh clean
# 重新加載openssl腳本
./compile-openssl.sh all
# 重新加載ffmpeg腳本
./compile-ffmpeg.sh all
檢查通過后運行項目處理錯誤
IJKMediaFramework
一運行發(fā)現(xiàn)demo中有一處方法沒返回值編譯不過去泄隔,添加上返回值。
如需支持https協(xié)議需在IJKMediaPlayer中增加上編譯完openssl后生成的兩個庫文件
如果不增加這兩個庫文件宛徊,在運行IJKMediaDemo
的時候會報錯佛嬉。
運行IJKMediaDemo
運行之后報錯如下:
發(fā)現(xiàn)之前配置
openssl
及ffmpeg
的時候設(shè)置最低8.0
,由于demo中Minimum Deployments
值是7.0
闸天,版本太低需將其提高(不知道為什么8.0不行暖呕,改為9.0正常了)
打包framework
配置為Release
模式,使的編譯狀態(tài)即可打包出framework苞氮。
分別選擇真機環(huán)境及模擬器環(huán)境編譯一遍湾揽,然后在設(shè)置中的Locations分欄
中點擊箭頭跳到編譯后的目錄,找到真機包和模擬器包笼吟。
lipo命令查看包支持的環(huán)境及合并包
-
lipo命令查看包支持的環(huán)境
在終端中輸入lipo -info framework地址
獲取該包支持的環(huán)境
lipo -info /Users/***/Library/Developer/Xcode/DerivedData/IJKMediaPlayer-flteyzdokpvvjrggfniynketqxrr/Build/Products/Release-iphonesimulator/IJKMediaFramework.framework/IJKMediaFramework
Architectures in the fat file: /Users/***/Library/Developer/Xcode/DerivedData/IJKMediaPlayer-flteyzdokpvvjrggfniynketqxrr/Build/Products/Release-iphonesimulator/IJKMediaFramework.framework/IJKMediaFramework are: arm64 x86_64
可以看到該模擬器包支持arm64
和x86_64
指令集
-
lipo命令合并真機與模擬器包
在終端中輸入lipo -create 真機包地址 模擬器包地址 -output 包名稱
將真機包與模擬器包合并為一個新的包同時支持兩種編譯環(huán)境库物。
值得注意的是:
在Apple
發(fā)布M1芯片
之前,一直使用Intel
的芯片赞厕,沒有出現(xiàn)什么問題艳狐。發(fā)布 M1芯片
后,由于兩者架構(gòu)的不同(M1
是arm64
架構(gòu)皿桑,Intel
是x86_64
的架構(gòu))毫目,導(dǎo)致lipo -create
命令在執(zhí)行的時候會出現(xiàn)如下錯誤:
lipo -create /Users/***/Library/Developer/Xcode/DerivedData/IJKMediaPlayer-flteyzdokpvvjrggfniynketqxrr/Build/Products/Release-iphonesimulator/IJKMediaFramework.framework/IJKMediaFramework /Users/***/Library/Developer/Xcode/DerivedData/IJKMediaPlayer-flteyzdokpvvjrggfniynketqxrr/Build/Products/Release-iphoneos/IJKMediaFramework.framework/IJKMediaFramework -output IJKMediaFramework
fatal error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: /Users/***/Library/Developer/Xcode/DerivedData/IJKMediaPlayer-flteyzdokpvvjrggfniynketqxrr/Build/Products/Release-iphonesimulator/IJKMediaFramework.framework/IJKMediaFramework and /Users/***/Library/Developer/Xcode/DerivedData/IJKMediaPlayer-flteyzdokpvvjrggfniynketqxrr/Build/Products/Release-iphoneos/IJKMediaFramework.framework/IJKMediaFramework have the same architectures (arm64) and can't be in the same fat output file
在我們創(chuàng)建framework
時,選擇真機編譯出來的包只包含arm64
指令诲侮,選擇模擬器編譯出來的包會同時包含arm64
和x86_64
指令镀虐。有網(wǎng)上教程說將模擬器部分的arm64
指令移除,但是要支持M1
機器正常跑模擬器環(huán)境沟绪,必須同時包含arm64
和x86_64
指令刮便。
解決方案:
2019年的WWDC
,蘋果提供了一種新的框架封裝格式XCFramework
绽慈,簡單理解就是之前用lipo
命令合并不同指令集的包恨旱,現(xiàn)在改為使用心得指令合并成XCFramework
格式的包辈毯。
xcodebuild指令
實驗過很多次,仍舊無法解決在M1
機器上編譯出的arm64+x86_64
指令同時存在的framework
改為xcframework
搜贤。