FFmpeg是一套能夠用來記錄、轉換數字音頻、視頻,並能將其轉化爲流的開源計算機程序。它提供了錄製、轉換以及流化音視頻的完整解決方案。html
操做系統:Ubuntu 16.04 64bitlinux
NDK版本:android-ndk-r14b-linux-x86_64android
FFmpeg版本:3.4.2git
NDK 下載地址github
FFmpeg 下載地址bash
將NDK和FFmpeg源碼解壓至指定目錄,文中解壓在了Home > ffmpeg目錄下,注意NDK的版本必定要選擇Linux版的,在編譯的時候我就犯了這個錯誤,使用了Windows版的NDK,一直報錯也找不到緣由,切記切記!架構
在ffmpeg-3.4.2目錄下建立build_android.sh編譯腳本,文件名能夠隨便取,這個腳本是本文中最關鍵的內容,一塊兒來看下:ide
#!/bin/bash
# 設置臨時文件夾,須要提早手動建立
export TMPDIR="/home/yangle/ffmpeg/ffmpeg-3.4.2/ffmpegtemp"
# 設置NDK路徑
NDK=~/ffmpeg/android-ndk-r14b
# 設置編譯針對的平臺,能夠根據實際需求進行設置
# 當前設置爲最低支持android-14版本,arm架構
SYSROOT=$NDK/platforms/android-14/arch-arm
# 設置編譯工具鏈,4.9爲版本號
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
function build_one
{
./configure \
--enable-cross-compile \
--enable-shared \
--disable-static \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-avdevice \
--disable-doc \
--disable-symver \
--prefix=$PREFIX \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--target-os=android \
--arch=arm \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $ADDI_CFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
}
# 設置編譯後文件的輸出目錄
CPU=arm
PREFIX=$(pwd)/android/$CPU
ADDI_CFLAGS="-marm"
build_one
複製代碼
前四項配置按照你本機的實際路徑修改就能夠了,注意ffmpegtemp這個臨時文件夾須要提早手動建立,【~/】 在Linux上表明 【/home/用戶名/】,看下build_one這個方法,enable、disable分別表明打開和關閉一些功能,重點看下下面幾個配置:函數
--enable-shared
--disable-static
複製代碼
編譯動態庫,shared和static的開關是相對的。工具
--prefix=$PREFIX
CPU=arm
PREFIX=$(pwd)/android/$CPU
複製代碼
設置編譯後文件的輸出目錄,$(pwd)表明當前目錄,因此文件的輸出路徑爲:ffmpeg-3.4.2/android/arm
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi-
複製代碼
設置交叉編譯器,按照實際路徑修改就能夠了。
--target-os=android
複製代碼
設置編譯針對的系統,網上查到不少資料說編譯前須要修改configure文件,設置這項後就不用修改了,系統會自動爲咱們修改,效果同樣。
--arch=arm
複製代碼
設置編譯so庫的架構,當前設置爲arm,能夠根據實際需求修改。
--sysroot=$SYSROOT
複製代碼
設置編譯針對的平臺,能夠根據實際需求進行設置,當前設置爲最低支持android-14版本,arm架構。
--extra-cflags="-Os -fpic $ADDI_CFLAGS"
ADDI_CFLAGS="-marm"
複製代碼
尚未徹底理解這幾個參數的做用,有知道的同窗能夠給我留言啊,謝謝!
到這裏,編譯腳本就寫完了,在當前目錄下打開終端窗口,執行腳本,加上管理員權限,以防權限不足:
$ sudo ./build_android.sh
複製代碼
回車提示輸入密碼,密碼不會顯示出來或者顯示成*號,直接輸完而後回車就能夠了,看下執行效果:
編譯中:
若是一切順利的話,大概十多分鐘就能夠編譯完成:
編譯完成後,在當前目錄下(ffmpeg-3.4.2)會生成一個android目錄,so文件就在android > arm > lib目錄下:
看下生成的so包是作什麼用的:
libavcodec:用於各類類型聲音、圖像編解碼。
libavformat:用於各類音視頻封裝格式的生成和解析,讀取音視頻幀等功能。
libavutil:包含一些公共的工具函數。
libavfilter:提供了各類音視頻過濾器。
libswresample:用於音頻重採樣,採樣格式轉換和混合。
libswscale:用於視頻場景比例縮放、色彩映射轉換。
在上文中咱們成功的編譯了FFmpeg,可是編譯出來的so文件一共有6個,若是覺的使用起來比較麻煩,能夠編譯成一個so文件,下面咱們來修改下腳本:
#!/bin/bash
# 設置臨時文件夾,須要提早手動建立
export TMPDIR="/home/yangle/ffmpeg/ffmpeg-3.4.2/ffmpegtemp"
# 設置NDK路徑
NDK=~/ffmpeg/android-ndk-r14b
# 設置編譯針對的平臺,能夠根據本身的需求進行設置
# 當前設置爲最低支持android-14版本,arm架構
SYSROOT=$NDK/platforms/android-14/arch-arm
# 設置編譯工具鏈,4.9爲版本號
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
function build_one
{
./configure \
--enable-cross-compile \
--enable-static \
--disable-shared \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-avdevice \
--disable-doc \
--disable-symver \
--prefix=$PREFIX \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--target-os=android \
--arch=arm \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $ADDI_CFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
# 合併生成的靜態庫
$TOOLCHAIN/bin/arm-linux-androideabi-ld \
-rpath-link=$SYSROOT/usr/lib \
-L$SYSROOT/usr/lib \
-L$PREFIX/lib \
-soname libffmpeg.so -shared -nostdlib -Bsymbolic --whole-archive --no-undefined -o \
$PREFIX/libffmpeg.so \
libavcodec/libavcodec.a \
libavfilter/libavfilter.a \
libswresample/libswresample.a \
libavformat/libavformat.a \
libavutil/libavutil.a \
libswscale/libswscale.a \
-lc -lm -lz -ldl -llog --dynamic-linker=/system/bin/linker \
$TOOLCHAIN/lib/gcc/arm-linux-androideabi/4.9.x/libgcc.a
}
# 設置編譯後的文件輸出目錄
CPU=arm
PREFIX=$(pwd)/android/$CPU
ADDI_CFLAGS="-marm"
build_one
複製代碼
看下和編譯單個so文件的腳本有什麼區別:
生成靜態庫:
--disable-static
--enable-shared
修改成:
--enable-static
--disable-shared
複製代碼
增長下面的指令,將生成的靜態庫合併成一個動態庫:
$TOOLCHAIN/bin/arm-linux-androideabi-ld \
-rpath-link=$SYSROOT/usr/lib \
-L$SYSROOT/usr/lib \
-L$PREFIX/lib \
-soname libffmpeg.so -shared -nostdlib -Bsymbolic --whole-archive --no-undefined -o \
$PREFIX/libffmpeg.so \
libavcodec/libavcodec.a \
libavfilter/libavfilter.a \
libswresample/libswresample.a \
libavformat/libavformat.a \
libavutil/libavutil.a \
libswscale/libswscale.a \
-lc -lm -lz -ldl -llog --dynamic-linker=/system/bin/linker \
$TOOLCHAIN/lib/gcc/arm-linux-androideabi/4.9.x/libgcc.a
複製代碼
重點看下下面兩個配置:
-soname libffmpeg.so
複製代碼
指定動態庫,也就是so文件的名稱。
$TOOLCHAIN/lib/gcc/arm-linux-androideabi/4.9.x/libgcc.a
複製代碼
設置編譯器的路徑,根據實際路徑進行修改,編譯前必定要檢查一遍路徑是否正確!
腳本中還涉及到一些編譯指令,均可以在網上查到做用,在這裏就再也不一一說明了,OK,開始執行編譯腳本:
$ sudo ./build_android_all.sh
複製代碼
編譯完成後,生成的libffmpeg.so就在android > arm目錄下:
NDK路徑錯誤
遇到這個錯誤仔細檢查一遍設置的路徑有沒有問題,我就栽在了這個坑裏:
android文件夾帶鎖
編譯成功後,android文件夾是帶鎖的,執行下面的命令就能夠解鎖:
sudo chown 用戶名 android/ -R
複製代碼
第一次使用Linux系統和編譯FFmpeg,一直在網上查命令和各類報錯的解決方案,這篇文章前先後後寫了一個多月,若有錯誤的地方,能夠給我留言指正,多謝!
文中用到的FFmpeg源碼、編譯腳本以及編譯生成的so文件已經上傳至GitHub,後續還會更新,歡迎Start、Fork!
本篇文章到這裏就結束了,下一篇文章將會繼續介紹如何在Android項目中使用FFmepg,敬請期待!