前言
關于ffmpeg so庫的編譯,網上存在各種教程。有些基于windows,有些基于linux~而基于linux的:一般會選擇安裝虛拟機,在其上跑ubuntu系統。其實各種方式都是可以的,隻要最後可以編譯出我們需要的so庫,就是正道。
win10開始自帶了linux的子系統,我們可以直接使用該子系統進行編譯工作,而無需安裝虛拟機等繁瑣流程。本章将詳細羅列完整流程,大緻流程會跟網上類似,但也有更新:
- 編譯新版的ffmpeg
- demo中會使用ffmpeg新版的api(注:網上好多教程的demo部分其實無法正常使用,部分api在新版已經廢棄)
開啟linux子系統
啟用子系統服務
打開【啟用或關閉 Windows 功能】,勾選【适用于Linux的Windows子系統】或【Windows Subsystem For Linux】
安裝完成後,重新開機電腦
安裝linux
打開Microsoft store,搜尋linux
這裡選擇安裝Ubuntu 18.04 LTS(當然,版本可以自己選擇适用的)
啟動ubuntu
安裝完成後,即可在開始菜單啟動該ubuntu子系統。該子系統純指令模式,大夥可以在編譯過程中順便熟悉下linux的指令,哈哈~
編譯準備
先安裝和下載下傳需要的檔案,并配置好環境
建立ffmpeg檔案夾(非必須)
隻是為了将所有資源整合到一起,統一管理,可以忽略該流程
下載下傳ffmpeg
- wget ffmpeg.org/releases/ff…
下載下傳ndk
- wget dl.google.com/android/rep…
安裝jdk并解壓ndk
為什麼需要這麼繁瑣,還要安裝jdk呢?本來打算安裝unzip用于解壓ndk的,但是由于檔案過大,unzip解壓會失敗,最後選擇使用jar進行解壓
- sudo apt-get install default-jdk
- jar xvf android.zip
安裝vim
主要用于編輯編譯腳本,當然也可以使用其他的文本編輯器進行
- sudo apt-get install vim
相關學習資料推薦,點選下方連結免費報名,先碼住不迷路~】
【免費分享】音視訊學習資料包、大廠面試題、技術視訊和學習路線圖,資料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以點選加群免費領取~
編譯
調整configure檔案,修改生成生成以lib為字首,.so為字尾的so庫
這裡可以使用vim進行修改。vim的查找快捷鍵為:先按ESC鍵,然後再 / , 輸入需要搜尋的關鍵字
修改前:
SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'
LIB_INSTALL_EXTRA_CMD='$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'
SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)'
修改後:
SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'
編寫編譯腳本:android_build.sh
#!/bin/bash
NDK_DIR=/home/king/ffmpeg/android-ndk-r16b
SYSROOT=${NDK_DIR}/platforms/android-19/arch-arm/
TOOLCHAIN=${NDK_DIR}/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
function android_build
{
./configure \
--prefix=$PREFIX \
--disable-doc \
--enable-shared \
--disable-static \
--disable-symver \
--enable-gpl \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-doc \
--disable-symver
--cross-prefix=${TOOLCHAIN}/bin/arm-linux-androideabi- \
--target-os=android \
--arch=arm \
--enable-cross-compile \
--sysroot=${SYSROOT} \
--extra-cflags="-Os -fpic $ADDI_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
}
CPU=armv7-a
PREFIX=./android/$CPU
ADDI_CFLAGS="-marm"
android_build
給編譯腳本增權重限
- sudo chmod -R 777 android_build.sh
開始編譯
- ./android_build.sh
完成
編譯完成後,會在目前目錄/android/armv7-a/目錄下看到生成的so庫
so庫的使用
使用新版的android studio可以很友善的給現有項目增加c++,直接在對應的module右鍵,選擇Add C++ to Module,即可生成需要的檔案。這裡不使用這種便捷方式,而是使用最原始的流程,一步一步的建構整個流程。
建立FFmpegUtil類并聲明本地方法
public class FFmpegUtil {
static {
System.loadLibrary("ffmpegdemo");
}
//JNI
public native String avformatinfo();
public native String avcodecinfo();
public native String protocols();
public native String bsf();
}
使用javac編譯源檔案FFmpegUtil.java,生成FFmpegUtil.class
執行javac FFmpegUtil.java即可(該步驟在所在源檔案目錄執行)
使用javah -jni生成C頭檔案
javah用法:
javah [options] <classes>
其中, [options] 包括:
-o <file> 輸出檔案 (隻能使用 -d 或 -o 之一)
-d <dir> 輸出目錄
-v -verbose 啟用詳細輸出
-h --help -? 輸出此消息
-version 輸出版本資訊
-jni 生成 JNI 樣式的标頭檔案 (預設值)
-force 始終寫入輸出檔案
-classpath <path> 從中加載類的路徑
-cp <path> 從中加載類的路徑
-bootclasspath <path> 從中加載引導類的路徑
<classes> 是使用其全限定名稱指定的
(例如, java.lang.Object)。
根據說明,執行的指令應該為:
javah -jni com.example.ffmpegdemo.FFmpegUtil
這裡有一點需要注意的是,執行目錄不是在FFmpegUtil.class所在的路徑,而應該是在app\src\main\java\路徑下
執行成功後,可以在該目錄下看到生成了com_example_ffmpegdemo_FFmpegUtil.h檔案
用C代碼或CPP代碼寫函數原型的實作
- 在app\src\main\下增加cpp檔案夾
- 建立可以在該目錄下看到生成了com_example_ffmpegdemo_FFmpegUtil.cpp檔案,實作具體的函數
添加ffmpeg so庫的引用
- 在app\路徑下添加libs檔案夾
- 将幾個平台的so庫添加到libs目錄下
- 将相應的頭檔案添加到libs目錄下,統一放在include下
- 在module的build.gradle配置相關資訊
android {
defaultConfig {
...
externalNativeBuild {
cmake {
cppFlags "-std=c++11"
abiFilters "armeabi-v7a"
}
}
ndk {
//我們隻有armeabi-v7a就隻配置這個就行了
abiFilters 'armeabi-v7a'
}
}
}
編寫CMakeLists.txt檔案
CMake檔案的編寫,官方有詳細的教程:配置CMake。主要工作就是配置引用的so庫和相應的頭檔案等消息,具體内容可看demo。
在module的build.gradle配置CMakeLists.txt
android {
...
externalNativeBuild {
cmake {
// 要注意相對路徑,我這裡直接放在app\路徑下
path file('CMakeLists.txt')
}
}
}
使用
基本配置完成,可以正常的在module中使用FFmpegUtil提供的native方法啦~上圖兩張:
總結
總的流程下來,主要包含兩方面:
- 如何不安裝虛拟機編譯新版ffmpeg的so庫
- 如何使用編譯出來的so庫,即一般ndk的開發流程 當然,就像上邊提及的,android studio對于ndk開發支援越來越好,也越來越簡便。那為什麼上邊沒有使用簡便的方法呢?有時候你需要自己一步一步進行開發才能了解ADT在背後為我們做了哪些事情,假如脫離ADT我們可以怎麼去完成相應的事情。
最後附上demo位址:gitee-demo
原文 ffmpeg源碼編譯詳細過程與使用(含demo) - 掘金