## 音視頻學習 (六) 一鍵編譯 32/64 位 FFmpeg 4.2.2
## 前言
> 2020/5/20
>
> * 增加了硬件解碼編譯腳本
> * 編譯環境 Centos + NDK20b + FFmpeg4.2.2 + Android-21/16
> 2020/4/26
>
> * 更新了編譯 64 位腳本
> * 編譯環境 Centos + NDK17C + FFmpeg4.2.2 + Android-21
? 該篇文章起就正式進入音視頻學習了,在進入音視頻學習之前我們必須要先學習 FFmpeg 這個庫,這個庫非常強大,強大到什么地步呢 ?可以說只要做音視頻的沒有人不了解它,包括國內外一些比較出名的播放器也用到了 FFmpeg 這個庫。
## FFmpeg 定義
? FFmpeg 既是一款音視頻編解碼工具,同時也是一組音視頻編解碼開發套件,作為編解碼開發套件,他為開發者提供了豐富的音視頻處理的調用接口。
? FFmpeg 提供了多種媒體格式的封裝和解封裝,包括多種音視頻編碼、多種協議的流媒體、多種色彩格式轉換、多種采樣率轉換、多種碼率轉換等; FFmpeg 框架提供了多種豐富的插件模塊,包含封裝與解封轉的插件、編碼與解碼的插件等。
## FFmpeg 歷史
? FFmpeg 由法國天才程序員**Fabrice Bellard**在 2000 年的時開發出初版;后來發展到 2004 年,**Fabrice Bellard**找到了接手人,這個人至今還在維護 FFmpeg 的 Michael Niedermayer 。Michael Niedermayer 對 FFmpeg 的貢獻非常大,其將濾鏡子系統 libavfilter 加入 FFmpeg 項目中,使得 FFmpeg 的多媒體處理更加多樣、更加方便。在 FFmpeg 發布了 0.5 版本之后,很長一段時間沒有進行新版本的發布,直到后來 FFmpeg 采用了 Git 作為版本控制服務器以后才開始繼續進行代碼更新、版本發布,當然也是時隔多年之后了;2011 年 3 月,在 FFmpeg 項目中有一些提交者對 FFmpeg的項目管理方式并不滿意,因而重新創建了一個新的項目,命名為 Libav, 該項目盡管至今并沒有 FFmpeg 發展這么迅速,但是提交權限相對 FFmpeg 更加開放;2015 年 8 月,Michael Niedermayer 主動辭去 FFmpeg 項目負責人的職務。Michael Niedermayter 從 Libav 中移植了大量的代碼和功能到 FFmpeg 中,Michael Niedermayter 辭職的主要目的是希望兩個項目最終能夠一起發展,若能夠合并則更好。時至今日,在大多數的 Linux 發行版本系統中已經使用 FFmpeg 來進行多媒體處理。
FFmpeg 可以通過以下方式自由獲取源代碼,具體方式如下:
* [官方網站](https://www.ffmpeg.org/)
* [git.videolan.org/?p=ffmpeg.g…](http://git.videolan.org/?p=ffmpeg.git)
* [GitHub](https://github.com/FFmpeg/FFmpeg)
## FFmpeg 模塊介紹

? FFmpeg 框架的基本組成包含 libavcodec 、libavformat、libavfilter、libavdevice 、libavutil 等模塊。
下面針對這些模塊做一個大概的介紹。
* **libavcodec:**
編解碼庫,封裝了 Codec 層,但是有一些 codec 是具備自己的 License 的,FFmpeg 不會默認添加像 libx264、FDK-AAC、Lame 等庫,但是 FFmpeg 像一個平臺,可以將其他的第三方codec以插件的方式添加進來,為開發者提供統一接口
* **libavformat:**
文件格式和協議庫,封裝了 Protocol 層和 Demuxer、Muxer 層,使得協議和格式對于開發者來說是透明的
* **libavfilter:**
音視頻濾鏡庫,該模塊包含了音頻特效和視頻特效的處理,在使用 FFmpeg 的 API 進行編解碼的過程中,可以使用該模塊高效的為音視頻數據做特效處理
* **libavdevice:**
輸入輸出設備庫,比如需要編譯出播放聲音或者視頻的工具 ffplay,就需要確保該模塊是打開的,同事也需要 libsdl 的預先編譯,該設備模塊播放聲音和視頻都又是使用libsdl 庫
* **libavutil:**
核心工具庫,最基礎模塊之一,其他模塊都會依賴該庫做一些基本的音視頻處理操作
* **libswresample:**
用于音頻重采樣,可以對數字音頻進行聲道數、數據格式、采樣率等多種基本信息的轉換
* **libswscale**
該模塊用于圖像格式轉換,可以將 YUV 的數據轉換為 RGB 的數據
* **libpostproc**
該模塊用于進行后期處理,當我們使用filter的時候,需要打開這個模塊,filter會用到這個模塊的一些基礎函數
比較老的 ffmpeg 還會編譯出 avresamle 模塊,也是用于對音頻原始出具進行重采樣的,但是已經被廢棄,推薦使用 libswresample 替代
另外,庫里還可以包含對 H.264/MPEG-4 AVC 視頻編碼的 X264 庫,是最常用的有損視頻編碼器,支持 CBR、VBR 模式,可以在編碼的過程中直接改變碼率的設置,在直播的場景中非常適用!可以做碼率自適應的功能。
## 下載 FFmpeg
[FFmpeg 官網](https://www.ffmpeg.org/download.html)直接下載源碼方式

在 linux 環境中,命令下載:
~~~
//1. 命令下載
wget https://ffmpeg.org/releases/ffmpeg-4.2.2.tar.bz2
//2. 安裝解壓縮工具
yum -y install bzip2
//3. 解壓 FFmpeg
tar -jxvf ffmpeg-4.2.2.tar.bz2
復制代碼
~~~
## 編譯 FFmpeg
### 編譯環境
* ffmpeg-4.2.2
* Centos 7
* android-ndk-r17c-linux-x86\_64.zip
### configure 腳本介紹
~~~shell
#!/bin/sh
...
#幫組選項
Help options:
--help print this message
--quiet Suppress showing informative output
--list-decoders show all available decoders
--list-encoders show all available encoders
--list-hwaccels show all available hardware accelerators
--list-demuxers show all available demuxers
--list-muxers show all available muxers
--list-parsers show all available parsers
--list-protocols show all available protocols
--list-bsfs show all available bitstream filters
--list-indevs show all available input devices
--list-outdevs show all available output devices
--list-filters show all available filters
#標準選項
#--disable 代表關閉狀態 ;--enable 代表開啟狀態
Standard options:
--logfile=FILE log tests and output to FILE [ffbuild/config.log]
--disable-logging do not log configure debug information
--fatal-warnings fail if any configure warning is generated
#我們最終編譯好的動態靜態庫位置,必須設置
--prefix=PREFIX install in PREFIX [$prefix_default]
--bindir=DIR install binaries in DIR [PREFIX/bin]
--datadir=DIR install data files in DIR [PREFIX/share/ffmpeg]
--docdir=DIR install documentation in DIR [PREFIX/share/doc/ffmpeg]
--libdir=DIR install libs in DIR [PREFIX/lib]
--shlibdir=DIR install shared libs in DIR [LIBDIR]
--incdir=DIR install includes in DIR [PREFIX/include]
--mandir=DIR install man page in DIR [PREFIX/share/man]
--pkgconfigdir=DIR install pkg-config files in DIR [LIBDIR/pkgconfig]
--enable-rpath use rpath to allow installing libraries in paths
not part of the dynamic linker search path
use rpath when linking programs (USE WITH CARE)
--install-name-dir=DIR Darwin directory name for installed targets
Licensing options:
--enable-gpl allow use of GPL code, the resulting libs
and binaries will be under GPL [no]
--enable-version3 upgrade (L)GPL to version 3 [no]
--enable-nonfree allow use of nonfree code, the resulting libs
and binaries will be unredistributable [no]
Configuration options:
#開啟靜態庫
--disable-static do not build static libraries [no]
#關閉動態庫
--enable-shared build shared libraries [no
#可以優化庫的大小
--enable-small optimize for size instead of speed
--disable-runtime-cpudetect disable detecting CPU capabilities at runtime (smaller binary)
--enable-gray enable full grayscale support (slower color)
--disable-swscale-alpha disable alpha channel support in swscale
--disable-all disable building components, libraries and programs
--disable-autodetect disable automatically detected external libraries [no]
Program options:
#我們不需要使用程序,不需要在Windows中執行,某.exe程序,我們只需要在代碼中使用 [此命令操作的是下面三項]
--disable-programs do not build command line programs
#使用FFmpeg命令
--disable-ffmpeg disable ffmpeg build
#播放器
--disable-ffplay disable ffplay build
--disable-ffprobe disable ffprobe build
Documentation options:
--disable-doc do not build documentation
--disable-htmlpages do not build HTML documentation pages
--disable-manpages do not build man documentation pages
--disable-podpages do not build POD documentation pages
--disable-txtpages do not build text documentation pages
#模塊選項
Component options:
#可以操控我們的攝像頭-(Android中是不支持))
--disable-avdevice disable libavdevice build
#audio video codec(編碼 和 解碼)
--disable-avcodec disable libavcodec build
#音視頻格式生成和解析相關
--disable-avformat disable libavformat build
#音頻重采樣(如果想把單聲道,變成雙聲道)
--disable-swresample disable libswresample build
#對視頻顯示相關(對視頻的縮放,放大 縮小)
--disable-swscale disable libswscale build
#后期處理,很少用,可以關閉掉
--disable-postproc disable libpostproc build
#給視頻加水印,加字幕,特殊效果
--disable-avfilter disable libavfilter build
--enable-avresample enable libavresample build (deprecated) [no]
--disable-pthreads disable pthreads [autodetect]
--disable-w32threads disable Win32 threads [autodetect]
--disable-os2threads disable OS/2 threads [autodetect]
--disable-network disable network support [no]
--disable-dct disable DCT code
--disable-dwt disable DWT code
--disable-error-resilience disable error resilience code
--disable-lsp disable LSP code
--disable-lzo disable LZO decoder code
--disable-mdct disable MDCT code
--disable-rdft disable RDFT code
--disable-fft disable FFT code
--disable-faan disable floating point AAN (I)DCT code
--disable-pixelutils disable pixel utils in libavutil
Individual component options:
--disable-everything disable all components listed below
--disable-encoder=NAME disable encoder NAME
--enable-encoder=NAME enable encoder NAME
#編碼可以去關閉掉
--disable-encoders disable all encoders
--disable-decoder=NAME disable decoder NAME
--enable-decoder=NAME enable decoder NAME
--disable-decoders disable all decoders
--disable-hwaccel=NAME disable hwaccel NAME
--enable-hwaccel=NAME enable hwaccel NAME
--disable-hwaccels disable all hwaccels
--disable-muxer=NAME disable muxer NAME
--enable-muxer=NAME enable muxer NAME
#混合封裝(音視頻等于 一段音頻 一段視頻 合并在一起 就是.mp4,不想這樣就可以關閉)
--disable-muxers disable all muxers
--disable-demuxer=NAME disable demuxer NAME
--enable-demuxer=NAME enable demuxer NAME
--disable-demuxers disable all demuxers
--enable-parser=NAME enable parser NAME
--disable-parser=NAME disable parser NAME
--disable-parsers disable all parsers
--enable-bsf=NAME enable bitstream filter NAME
--disable-bsf=NAME disable bitstream filter NAME
--disable-bsfs disable all bitstream filters
--enable-protocol=NAME enable protocol NAME
--disable-protocol=NAME disable protocol NAME
--disable-protocols disable all protocols
--enable-indev=NAME enable input device NAME
--disable-indev=NAME disable input device NAME
--disable-indevs disable input devices
--enable-outdev=NAME enable output device NAME
--disable-outdev=NAME disable output device NAME
--disable-outdevs disable output devices
--disable-devices disable all devices
--enable-filter=NAME enable filter NAME
--disable-filter=NAME disable filter NAME
--disable-filters disable all filters
...
復制代碼
~~~
### 編寫 32/64 位 FFmpeg4.2.2 shell 腳本
#### ndk20b+ffmpeg4.2.2 clang 編譯腳本
~~~shell
#!/bin/bash
echo ">>>>>>>>> 編譯硬件解碼版本 <<<<<<<<"
echo ">>>>>>>>> 注意:該編譯環境目前只在 NDK20b + ffmpeg4.2.2 測試過 <<<<<<<<"
echo ">>>>>>>>> 注意:該編譯環境目前只在 NDK20b + ffmpeg4.2.2 測試過 <<<<<<<<"
#你自己的NDK路徑.
export NDK=/root/android/ndk/android-ndk-r20b
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
function build_android
{
echo "開始編譯 $CPU"
./configure \
--prefix=$PREFIX \
--enable-neon \
--enable-hwaccels \
--enable-gpl \
--enable-postproc \
--enable-shared \
--disable-debug \
--enable-small \
--enable-jni \
--enable-mediacodec \
--enable-decoder=h264_mediacodec \
--disable-static \
--disable-doc \
--enable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-avdevice \
--disable-doc \
--disable-symver \
--cross-prefix=$CROSS_PREFIX \
--target-os=android \
--arch=$ARCH \
--cpu=$CPU \
--cc=$CC \
--cxx=$CXX \
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $OPTIMIZE_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS"
make clean
make
make install
echo "編譯成功 $CPU"
}
#armv8-a
ARCH=arm64
CPU=armv8-a
API=21
CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-
PREFIX=$(pwd)/android/$CPU
OPTIMIZE_CFLAGS="-march=$CPU"
build_android
#armv7-a
ARCH=arm
CPU=armv7-a
API=16
CC=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang
CXX=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++
SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
CROSS_PREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-
PREFIX=$(pwd)/android/$CPU
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "
build_android
復制代碼
~~~
#### ndk17c + ffmpeg4.2.2 gcc編譯腳本
~~~shell
#!/bin/bash
echo ">>>>>>>>> 注意:該編譯環境目前只在 NDK17c + ffmpeg4.2.2 測試過 <<<<<<<<"
echo ">>>>>>>>> 注意:該編譯環境目前只在 NDK17c + ffmpeg4.2.2 測試過 <<<<<<<<"
echo ">>>>>>>>> 注意:該編譯環境目前只在 NDK17c + ffmpeg4.2.2 測試過 <<<<<<<<"
#NDK_ROOT 變量指向 ndk 目錄
NDK_ROOT=$NDK_HOME
#指定android api版本
ANDROID_API=21
#開始編譯 在下面調用傳入參數即可
function build_ffmpeg()
{
echo "開始編譯 $PREFIX_CPU"
echo "開始編譯 $PREFIX"
echo "開始編譯 $TOOLCHAIN"
./configure \
--prefix=$PREFIX \
--enable-small \
--disable-programs \
--disable-avdevice \
--disable-encoders \
--disable-muxers \
--disable-filters \
--enable-cross-compile \
--cross-prefix=$CROSS_PREFIX \
--disable-shared \
--enable-static \
--sysroot=$NDK_ROOT/platforms/android-$ANDROID_API/arch-$ARCH \
--extra-cflags="$CFLAGES" \
--arch=$ARCH \
--target-os=android
#上面運行腳本生成makefile之后,使用make執行腳本
make clean
make
make install
echo "$PREFIX_CPU 編譯完成"
echo "$PREFIX_CPU 編譯完成"
echo "$PREFIX_CPU 編譯完成"
}
#armeabi-v7a
PREFIX=./result/armeabi-v7a
TOOLCHAIN=$NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
ARCH=arm
CROSS_PREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-
CFLAGES="-isysroot $NDK_ROOT/sysroot -isystem $NDK_ROOT/sysroot/usr/include/arm-linux-androideabi -D__ANDROID_API__=$ANDROID_API -U_FILE_OFFSET_BITS -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -O0 -fPIC"
build_ffmpeg
#arm64-v8a
PREFIX=./result/arm64-v8a
TOOLCHAIN=$NDK_ROOT/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64
ARCH=arm64
CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-
CFLAGES="-isysroot $NDK_ROOT/sysroot -isystem $NDK_ROOT/sysroot/usr/include/aarch64-linux-android -D__ANDROID_API__=$ANDROID_API -U_FILE_OFFSET_BITS -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -Wa,--noexecstack -Wformat -Werror=format-security -O0 -fPIC"
build_ffmpeg
#直接跳轉到編譯完成的路徑
cd /result
復制代碼
~~~
**編譯遇見的坑:**
1. arm-linux-androideabi-gcc is unable to create an executable file

原因 1: FFmpeg 4.2.2 版本默認使用了 clang 進行編譯
解決:
~~~shell
//1. 修改 configure 文件
vim configure
//2. 把 默認的 clang 修改為 gcc
if test "$target_os" = android; then
# cc_default="clang"
cc_default="gcc"
fi
復制代碼
~~~
原因 2:
檢查路徑是否正確
2. nasm/yasm not found or too old. Use --disable-x86asm for a crippled build.
分析:yasm 是匯編編譯器,ffmpeg 為了提高效率使用了匯編指令,如 MMX 和 SSE等。
所以系統中未安裝yasm時,就會報上面錯誤。
~~~shell
解決錯誤:安裝yasm編譯器。安裝方法如下:
1)下載:[yasm的下載鏈接]
wget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz
2)解壓:把下載下來的壓縮包進行解壓
tar -zxvf yasm-1.3.0.tar.gz
3)切換路徑:
cd yasm-1.3.0
4)執行配置:
./configure
5)編譯:
make
6)安裝:
make install
復制代碼
~~~
3. 解決 " lib64 libc so 6 version `GLIBC\_2 18' not found (required by lib...
~~~shell
curl -O http://ftp.gnu.org/gnu/glibc/glibc-2.18.tar.gz
tar zxf glibc-2.18.tar.gz
cd glibc-2.18/
mkdir build
cd build/
../configure --prefix=/usr --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin
make
make install
安裝完成后,查看是否成功
ll /lib64/libc*
然后可以繼續查看 glibc 支持的版本
strings /lib64/libc.so.6 | grep GLIBC
//------------------------------------------------------------
//下面可以不用參考,這個是我在升級 glibc 的時候把 libc-2.17.so 給誤刪除了,導致基本上癱瘓了,可以使用以下命令恢復
//ll cp 等命令失效請用以下進行軟連接
LD_PRELOAD=/lib64/libc-2.17.so ln -s /lib64/libc-2.17.so /lib64/libc.so.6
//如果不小心定義了錯誤環境變量可以通過以下命令刪除
unset LD_LIBRARY_PATH
復制代碼
~~~
4. config.mak 文件沒有生成

解決: 執行`./configure --disable-x86asm`生成 config.mak 文件
[更多坑錯誤請點擊此處查看](https://www.laoyuyu.me/2019/05/23/android/clang_compile_ffmpeg/)
錯誤解決完之后,按下回車鍵,如果出現如下輸出,就開始在編譯了:

大概等 10 分鐘左右就會編譯完成,如下所示就代表編譯靜態庫成功了:

5. 如果添加了第三方庫 openssl ,報 openssl not found
* [www.jianshu.com/p/5b3cf2054…](https://www.jianshu.com/p/5b3cf2054da3)
如果想編譯動態庫,僅僅修改下參數就行了,如下所示:
~~~shell
#開啟動態庫
--enable-shared \
#關閉靜態庫
--disable-static \
復制代碼
~~~
壓縮:
~~~
tar -zcvf ffmpeg_android.tar.gz android
復制代碼
~~~
利用**FileZill 工具**從服務器端把編譯好的靜態文件導出到電腦本地,導出完之后我們就在 AS 中測試編譯的 .a 文件是否有誤。
## Android 集成交叉編譯之后的 FFmpeg 靜態庫
1. 創建一個 C/C++ 項目的 Android 工程,并把編譯好的靜態庫導入項目中,如下結構:

2. 編寫 JNI 代碼
~~~c++
#include <jni.h>
// 有坑,會報錯,必須混合編譯
//#include <libavutil/avutil.h>
extern "C" {
#include <libavutil/avutil.h>
}
/**
* 拿到 ffmpeg 當前版本
* @return
*/
const char *getFFmpegVer() {
return av_version_info();
}
extern "C"
JNIEXPORT jstring JNICALL
Java_com_devyk_ffmpeg_MainActivity_getFFmpegVersion(JNIEnv *env, jclass type) {
return env->NewStringUTF(getFFmpegVer());
}
復制代碼
~~~
3. 編寫 CMakeLists.txt 腳本
~~~cmake
#指定 Cmake 最低版本
cmake_minimum_required(VERSION 3.4.1)
#找到包含所有的cpp文件
file(GLOB allCpp *.cpp)
#打印當前 cmakeLists 的路徑
message("當前cmakel路徑: ${CMAKE_SOURCE_DIR} \n cpu架構:${CMAKE_ANDROID_ARCH_ABI}")
add_library(
ffmpeg_lib
SHARED
${allCpp})
find_library(
log-lib
log)
# 引入FFmpeg的頭文件
include_directories(${CMAKE_SOURCE_DIR}/include)
# 引入FFmpeg的庫文件,設置內部的方式引入,指定庫的目錄是 -L 指定具體的庫-l
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/${CMAKE_ANDROID_ARCH_ABI}")
target_link_libraries(
ffmpeg_lib
# 具體的庫文件,鏈接到總庫
# 這樣寫會報錯,有坑
# avcodec avfilter avformat avutil swresample swscale
# 先把有依賴的庫,先依賴進來
avformat avcodec avfilter avutil swresample swscale
${log-lib})
復制代碼
~~~
4. app/build.gradle 配置
~~~groovy
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
...
defaultConfig {
...
externalNativeBuild(){
cmake{
abiFilters "armeabi-v7a" //指定編譯為 armeabi-v7a
}
}
}
...
externalNativeBuild(){
cmake{
//指定構建 C++ 代碼腳本
path 'src/main/cpp/CMakeLists.txt'
}
}
}
...
復制代碼
~~~
5. MainActivity 測試代碼
~~~Java
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("ffmpeg_lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView ffmpegVer = findViewById(R.id.ffmpeg_ver);
ffmpegVer.setText("當前 FFmpeg 版本為:" + getFFmpegVersion());
}
/**
* @return 返回當前
*/
public native static String getFFmpegVersion();
}
復制代碼
~~~
效果:

到這里 FFmpeg 編譯及導入 AS 使用已經全部介紹完了,動態庫編譯及使用需要自己動手去實踐了,使用方式都大同小異。
## 總結
在編譯 FFmpeg 的時候會出現很多坑,基本上每個版本的 shell 腳本編寫都不一樣,所以如果對 Shell 不太了解的,建議先去復習一下。
該篇文章下來咱們用到了交叉編譯、 Shell 腳本、 JNI 、Cmake 的知識,如果對這些基礎還不了解的一定要先去把基礎學好。也可以看我之前系列基礎文章。
[文章中的代碼](https://github.com/yangkun19921001/NDK_AV_SAMPLE)
## 感謝
* [FFmpeg](https://www.ffmpeg.org/download.html)
- 前言
- JNI基礎知識
- C語言知識點總結
- ①基本語法
- ②數據類型
- 枚舉類型
- 自定義類型(類型定義)
- ③格式化輸入輸出
- printf函數
- scanf函數
- 編程規范
- ④變量和常量
- 局部變量和外部變量
- ⑤類型轉換
- ⑥運算符
- ⑦結構語句
- 1、分支結構(選擇語句)
- 2、循環結構
- 退出循環
- break語句
- continue語句
- goto語句
- ⑧函數
- 函數的定義和調用
- 參數
- 函數的返回值
- 遞歸函數
- 零起點學通C語言摘要
- 內部函數和外部函數
- 變量存儲類別
- ⑨數組
- 指針
- 結構體
- 聯合體(共用體)
- 預處理器
- 預處理器的工作原理
- 預處理指令
- 宏定義
- 簡單的宏
- 帶參數的宏
- 預定義宏
- 文件包含
- 條件編譯
- 內存中的數據
- C語言讀文件和寫文件
- JNI知識點總結
- 前情回顧
- JNI規范
- jni開發
- jni開發中常見的錯誤
- JNI實戰演練
- C++(CPP)在Android開發中的應用
- 掘金網友總結的音視頻開發知識
- 音視頻學習一、C 語言入門
- 1.程序結構
- 2. 基本語法
- 3. 數據類型
- 4. 變量
- 5. 常量
- 6. 存儲類型關鍵字
- 7. 運算符
- 8. 判斷
- 9. 循環
- 10. 函數
- 11. 作用域規則
- 12. 數組
- 13. 枚舉
- 14. 指針
- 15. 函數指針與回調函數
- 16. 字符串
- 17. 結構體
- 18. 共用體
- 19. typedef
- 20. 輸入 & 輸出
- 21.文件讀寫
- 22. 預處理器
- 23.頭文件
- 24. 強制類型轉換
- 25. 錯誤處理
- 26. 遞歸
- 27. 可變參數
- 28. 內存管理
- 29. 命令行參數
- 總結
- 音視頻學習二 、C++ 語言入門
- 1. 基本語法
- 2. C++ 關鍵字
- 3. 數據類型
- 4. 變量類型
- 5. 變量作用域
- 6. 常量
- 7. 修飾符類型
- 8. 存儲類
- 9. 運算符
- 10. 循環
- 11. 判斷
- 12. 函數
- 13. 數學運算
- 14. 數組
- 15. 字符串
- 16. 指針
- 17. 引用
- 18. 日期 & 時間
- 19. 輸入輸出
- 20. 數據結構
- 21. 類 & 對象
- 22. 繼承
- 23. 重載運算符和重載函數
- 24. 多態
- 25. 數據封裝
- 26. 接口(抽象類)
- 27. 文件和流
- 28. 異常處理
- 29. 動態內存
- 30. 命名空間
- 31. 預處理器
- 32. 多線程
- 總結
- 音視頻學習 (三) JNI 從入門到掌握
- 音視頻學習 (四) 交叉編譯動態庫、靜態庫的入門學習
- 音視頻學習 (五) Shell 腳本入門
- 音視頻學習 (六) 一鍵編譯 32/64 位 FFmpeg 4.2.2
- 音視頻學習 (七) 掌握音頻基礎知識并使用 AudioTrack、OpenSL ES 渲染 PCM 數據
- 音視頻學習 (八) 掌握視頻基礎知識并使用 OpenGL ES 2.0 渲染 YUV 數據
- 音視頻學習 (九) 從 0 ~ 1 開發一款 Android 端播放器(支持多協議網絡拉流/本地文件)
- 音視頻學習 (十) 基于 Nginx 搭建(rtmp、http)直播服務器
- 音視頻學習 (十一) Android 端實現 rtmp 推流
- 音視頻學習 (十二) 基于 FFmpeg + OpenSLES 實現音頻萬能播放器
- 音視頻學習 (十三) Android 中通過 FFmpeg 命令對音視頻編輯處理(已開源)