ijkplayer 編譯與使用

題外話:ijkplayer 爲什麼叫 ijk呢? 本人好奇查了一下,ijk應該是「愛 JK」的縮寫 ,而「JK」這個詞是日本的網絡流行語,取自「女子高校生」日語的羅馬音簡寫,也就是女高中生的意思(~( ̄▽ ̄~)(~ ̄▽ ̄)~),哈哈,懂的都懂,B站這個開源播放器取名老二次元了。不廢話了,進入正題。java

編譯環境

系統軟件 版本 功能
macOs 10.15.5 系統
Homebrew 2.4.4 軟件包管理工具
jdk java version "1.8.0_251" Java開發工具
git 2.27.0 版本控制
yasm 1.3.0 彙編編譯器
NDK android-ndk-r14b Android NDK 是一個工具集,可以讓您使用 C 和 C++ 等語言以原生代碼實現應用的各個部分(注意編譯ijkplayer NDK 版本控制在 r10 ~ r14 範圍)
Android Studio 4.0 Android 開發IDE

手機 CPU 架構類型瞭解

  • Android 設備的CPU類型,不一樣的 Android 設備使用不一樣的 CPU,而不一樣的 CPU 支持不一樣的指令集
CPU 架構類型 說明
armeabi/mips / mips64 第5代、第6代的ARM處理器,早期的手機用的比較多,NDK 之前支持 ARMv5 (armeabi) 以及 32 位和 64 位 MIPS,但 NDK r17 已再也不支持
armeabi-v7a 第7代及以上的 ARM,此 ABI 適用於基於 32 位 ARM 的 CPU 處理器。
arm64-v8a 此 ABI 適用於基於 ARMv8-A 的 CPU,第8代、64位ARM處理器,目前市場主流的版本
x86 、x86_64 intel CPU , 平板、模擬器、64位的平板
  • adb 命令查看設備CPU架構
adb -s 設備名稱 shell getprop ro.product.cpu.abi
複製代碼

編譯準備

  • 自行下載git,yasm,Android sdk、ndk、並配置環境變量,下面給出Android sdk、ndk環境變量配置linux

  • git、yasm 安裝android

brew install git 
brew install yasm 
複製代碼
  • Android Studio、sdk 、ndk 下載地址
Android Studio、sdk下載地址
ndk下載地址
export ANDROID_SDK=/Users/{你的路徑XXX}/Library/Android/sdk
export ANDROID_NDK=/Users/{你的路徑XXX}/Library/Android/ndk/android-ndk-r14b
export PATH=$PATH:$ANDROID_SDK/tools
export PATH=$PATH:$ANDROID_SDK/platform-tools
export PATH=$PATH:$ANDROID_NDK
複製代碼

ijk項目下載和拉取fmpeg代碼

# clone項目
git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-android

# 進入ijkplayer-android目錄
cd ijkplayer-android

# 切換到最新代碼分支
git checkout -B latest k0.8.8

# 會檢查下載ffmpeg代碼 
./init-android.sh

#初始化openSSL(使ijk編譯後支持https)
./init-android-openssl.sh
複製代碼

編譯前選擇你的配置

  • 在官方庫說明中提供了三種配置支持,每一個sh腳本里有對應的配置信息,包含支持編碼格式、流媒體協議類型等,以下截取一些decoders,enable標識支持該格式,disable則標識不支持
## 支持解碼格式
# ./configure --list-decoders
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-decoders"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=aac"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=aac_latm"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=flv"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=h264"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=mp3*"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=vp6f"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=flac"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=hevc"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=vp8"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=vp9"
複製代碼
  • 選擇配置文件,ln -s 命令標識軟鏈接,module.sh能夠直接獲取module-default.sh的配置
#If you prefer more codec/format
cd config
rm module.sh
ln -s module-default.sh module.sh

#If you prefer less codec/format for smaller binary size (include hevc function)
cd config
rm module.sh
ln -s module-lite-hevc.sh module.sh

#If you prefer less codec/format for smaller binary size (by default)
cd config
rm module.sh
ln -s module-lite.sh module.sh
複製代碼

編譯

開始編譯

  • 這裏編譯的是Android項目,因此先 cd 到 android/contrib下 執行清除命令,而後編譯對於的 so 庫,all 標識編譯全部架構的 so,想編譯x86架構則將 all 替換成x86
./compile-openssl.sh clean//清除
./compile-ffmpeg.sh clean//清除
./compile-openssl.sh all//編譯
./compile-ffmpeg.sh all//編譯
複製代碼

編譯生成的ffmpeg.so文件

  • 生成ijkplayer 對應架構 so 文件(all 同上輸入對應架構則生成對應架構動態連接庫),動態連接庫生成路徑以下圖所示(路徑示例:ijkplayer-android/android/ijkplayer/ijkplayer-armv7a/src/main/libs/armeabi-v7a)

注意本步驟須要贊成不受信任軟件權限,具體參考地址git

# 注意回到android 路徑下
cd ..
# 執行腳步生成so 文件
./compile-ijk.sh all
複製代碼

ijkplayer編譯成功生成的動態連接庫文件

  • 到此 ijkplayer 編譯完成,若是播放器以前邏輯已經寫好,則直接替換項目中對應的動態連接庫文件就行

使用

  • 實際前面編譯的各個CPU架構的動態連接庫(so)文件生成後幫咱們都對應放到了 ijkplayer 項目中已經預留的建立好的空項目中,也就是路徑 ijkplayer-android/android/ijkplayer 中的項目這是一個能夠直接導入 Android Stuido 的Demo項目,可是平時開發都是將播放器做爲library導入項目的,接下來嘗試新建一個項目將 ijkplayer 做爲library 導入

項目導入

新建項目

  1. 首先新建一個 ijkplayerdemo 工程, 將文件夾的文件ijkplayer-android/android/ijkplayer目錄下的 tool 初始化工程腳本 gradle 文件複製到剛新穿件的項目根目錄,而後在根項目的build.gradle中加入統一版本 ext 配置,至關於一個 map,方便導入library 統一引入配置
ext {

    compileSdkVersion = 30
    buildToolsVersion = "30.0.0"

    targetSdkVersion = 30

    versionCode = 800800
    versionName = "0.8.8"
}
複製代碼

導入 ijkplayer-example

  • 這個項目,他自己是一個可運行的項目,而且依賴前面編譯好的各個版本動態連接庫 library,將其變爲library 則修改該模塊 build.gradle 將 apply plugin: 'com.android.application' 改成 apply plugin: 'com.android.library'。github

  • ijkplayer-example 的清單文件還設置了啓動的 Activity過濾器,將其刪除shell

<intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
複製代碼

各個CPU架構動態連接庫 library 合併,簡化項目依賴

  • 在導入的ijkplayer-java項目中ijkplayer-java\src\main\ 目錄新建 jniLibs 並將咱們各個ijkplayer-armv五、ijkplayer-armv7a、ijkplayer-x8六、ijkplayer-x86_64 目錄中的 \src\main\libs 目錄下的文件夾拷貝到 jniLibs 文件夾中

處理依賴報錯

  • ijkplayer-example依賴的包版本比較低,應該更改成咱們對於版本support包,須要將ijkplayer-example的一些報錯的類正確導包
  • 和ijkplayer-java中同樣,在ijkplayer-example目錄下新建gradle.properties 文件並加入項目配置
POM_NAME=ijkplayer-example
POM_ARTIFACT_ID=ijkplayer-example
POM_PACKAGING=aar
複製代碼
  • ijkplayer-example 的 build.gardle 中productFlavors 配置刪除

將ijkplayer-example依賴到主項目工程

implementation project(':ijkplayer-example')

複製代碼

編譯經過項目結構

改完編譯經過項目配置

測試簡單播放

  • 簡單調用ijkplayer-example中已經寫好的IjkVideoView測試ijkplayer視頻播放,固然若是你以爲它寫得很差則前面步驟能夠不導入ijkplayer-example,只導入 ijkplayer-java 並本身寫一個VideoView都是沒問題的,這裏我就偷懶了,直接測試一下,分別測試了 https、rtmp、http、rtsp等流媒體協議的媒體資源,rtsp播放不了,哈哈哈,能夠參考module-lite-more.sh配置本身編譯動態連接庫,給出簡單實用代碼,佈局文件就不貼了,敢興趣能夠在查看本demo源碼
/**
 * 簡單使用 ijkplayer  demo 提供的  IjkVideoView
 */

class MainActivity : AppCompatActivity() {


    private var setting:Settings? = null
    private var mAndroidMediaController:AndroidMediaController? =null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        setting = Settings(this)

        mAndroidMediaController = AndroidMediaController(this,false)

        IjkMediaPlayer.loadLibrariesOnce(null)
        IjkMediaPlayer.native_profileBegin("libijkplayer.so")

        //https
        val mVideoPath1 = "https://www.apple.com/105/media/us/iphone-x/2017/01df5b43-28e4-4848-bf20-490c34a926a7/films/feature/iphone-x-feature-tpl-cc-us-20170912_1920x1080h.mp4"
        //rtmp
        val mVideoPath2 = "rtmp://58.200.131.2:1935/livetv/hunantv"
        //hls
        val mVideoPath3 = "http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8"
        //rtsp
        val mVideoPath4 = "rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov"

        mVideoView.setMediaController(mAndroidMediaController)
        mVideoView.setHudView(video_msg)

        editVideoPath.setText(mVideoPath3)


        btplay.setOnClickListener{

            if (TextUtils.isEmpty(editVideoPath.text)) {
                Toast.makeText(this, "視頻地址不能爲空", Toast.LENGTH_LONG).show();
            } else {
                mVideoView.setVideoURI(Uri.parse(editVideoPath.text.toString().trim()))
                mVideoView.start()
            }

        }

    }

    override fun onDestroy() {
        super.onDestroy()

        mVideoView.stopPlayback()
        mVideoView.release(true)
        mVideoView.stopBackgroundPlay()
        IjkMediaPlayer.native_profileEnd()
    }
}
複製代碼

播放效果

簡單測試播放功能

demo地址

ijkplayerdemobash

編譯遇到問題

  • 「You must define ANDROID_NDK before starting」,出現該問題說明沒有正確配置ndk環境變量,在.bash_profile 文件配置參照以下
export ANDROID_SDK=/Users/{你的路徑XXX}/Library/Android/sdk
export ANDROID_NDK=/Users/{你的路徑XXX}/Library/Android/ndk/android-ndk-r14b
export PATH=$PATH:$ANDROID_SDK/tools
export PATH=$PATH:$ANDROID_SDK/platform-tools
export PATH=$PATH:$ANDROID_NDK
複製代碼
  • 執行./compile-ffmpeg.sh腳本編譯錯誤提示「fatal error: linux/perf_event.h: No such file or directory」,出現該錯誤是該庫是linux下的,在mac直接禁用就行,修改方式爲 config 目錄下的module-default.sh腳本加入以下配置,再次回到 android/contrib下執行./compile-ffmpeg.sh clean 清除操做而後繼續編譯 ./compile-openssl.sh all
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-linux-perf"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-bzlib"
複製代碼

總結反思

  • 前面弄了一大堆,如今想一想其實已經有許多大佬已經將播放器,各類適配動態連接庫都已經封裝打包好成了開源庫,好比GSY大佬的GSYVideoPlayer,那我這麼費勁搞這些幹嗎。哈哈,我相信多折騰老是沒錯的,實踐出真知,根據本身的需求配置編譯出 so 文件,再站在巨人肩膀結合 GSYVideoPlayer 會不會更香呢?

參考

相關文章
相關標籤/搜索