Android/NDK環境下FFmpeg及AAC,MP3,X264的編譯
本篇介紹在Android/Ndk環境下FFmpeg的編譯及使用, FFmpeg自帶了H264、AAC、MP3的解碼器,但卻沒有(或沒有好的)相應的編碼器。相應的編碼器需要使用第三方庫。推薦使用的第三方庫為x264(H264編碼) 、FDK_AAC(AAC編碼),lame(MP3編碼)。
在順序上,應該先編譯好第三方庫,最後再編譯FFmpeg庫。
【本書說明:本文作者:邵發,本文選自《FFmpeg視音訊程式設計指南》。有關本書的詳細資訊請訪問官網:http://www.afanihao.cn 】
【權利宣告:作者保留本文的全部權利。作者授權任何人都可以自由轉載本文,但轉載時必須遵守以下限制:①轉載時必須全文轉載,不得有任何修改,包括“權利宣告”和“本書說明”部分 ② 僅限於網路轉載,即最終結果公佈於網路上。凡是不遵守以上兩條的轉載行為視為侵權行為。除非本人允許,任何人不得將本文內容用於任何的其他用途。】
1.1 NDK環境的準備
本篇的演示示例使用的是android-ndk-r8e版本,但理論上也適用於更新的NDK版本。為了讓你的編譯過程極其順利,應該對NDK作以下改動:
進入目錄 platforms/android-14/arch-arm/usr/lib
應該可以看到一些檔案,例如 crtbegin_dynamic.o ,crtbegin_static.o crtend_so.o , crtbegin_so.o ,crtend_android.o,等等。
把這個目錄下的所有檔案拷貝到
\toolchains\arm-linux-androideabi-4.6\prebuilt\linux-x86\lib\gcc\arm-linux-androideabi\4.6
否則在連結的時候ld會提示“找不到crtbegin_so.o和crtend_so.o”的錯誤。
應該把NDK的相關工具都把加PATH環境變數中,例如,
#!/bin/sh export PATH=$PATH:/opt/ndk/android-ndk-r8e/ export PATH=$PATH: /opt/ndk/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/ |
1.2 FDK_AAC庫的編譯
如果你不打算使用AAC編碼的功能,則可以略過本節。目前(2015年3月),fdk_aac的官方釋出地址是在source_forge上,也許以後會變,作者可以自行搜尋。目前地址為:
http://sourceforge.net/projects/opencore-amr/files/fdk-aac/
本文使用的版本是fdk-aac-0.1.3,為減少不必要的麻煩,讀者也請下載這個包。
1.2.1 修改configure指令碼
修改指令碼的目的是去除目標庫的版本號,以適應Android/NDK的對庫的載入要求。簡單地講,這是因為在Android/NDK專案的java程式碼中,使用System.loadLibrary()函式來載入so檔案時,動態庫是不能加版本號的。
在fdk_aac的configure腳本里找到如下的行:
# This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${shared_ext} ${libname}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${shared_ext}' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no |
把粗體字部分替換為:
library_names_spec='$libname${shared_ext} $libname.a' |
1.2.2 新建配置指令碼
在原始碼的根目錄下建議一個myconfig.sh指令碼。這是一個SHELL指令碼,要求讀者自己稍微瞭解一些SHELL指令碼的寫法。在這裡只強調一點:SHELL指令碼是以\n結尾的,如果你是在windows下面編輯的,那麼應該用dos2unix來把文字的換行符轉成unix格式。
為了避免不必要的麻煩,把NDK解壓縮在/opt/ndk/android-ndk-r8e目錄,並將FDK的輸出目錄--prefix設定在/opt/ndk/openlib目錄下。讀者第一遍操作時,不要擅自修改目錄,必須在熟練掌握之後再自行修改目錄。
myconfig.sh裡面內容為:
#!/bin/sh export CC=arm-linux-androideabi-gcc export CXX=arm-linux-androideabi-g++ export AR=arm-linux-androideabi-ar export LD=arm-linux-androideabi-ld export AS=arm-linux-androideabi-gcc export CFLAGS=" --sysroot=/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 " export CXXFLAGS=" --sysroot=/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 " export LDFLAGS=" -L/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm/usr/lib -march=armv7-a -Wl,--fix-cortex-a8 " ./configure --enable-static --prefix=/opt/ndk/openlib --host=arm-linux |
1.2.3 編譯
如果你嚴格按照以上的操作進行,那麼編譯過程會非常簡單。Linux下的開源軟體一般都是分為三步編譯 configure , make,make install,而fdk_aac也不例外。
1) ./myconfig.sh
執行上述配置指令碼,開始配置
2) make
3) make install
一切正常,將在/opt/ndk/openlib下存放輸出庫及標頭檔案,注意這個庫是去掉版本號的libfdk-aac。顯然,Android/NDK的程式設計師會更喜歡不帶版本號的庫。
1.3 LAME-MP3的編譯
如果你不打算在專案中使用mp3編碼,則略過本節。
本節介紹lame的編譯,但遺憾的是,其動態庫沒有辦法去掉版本號。所以本方法生成的目標動態庫是帶版本號的。
1.3.1 新建配置指令碼
新建配置檔案myconfig.sh,內容如下,
#!/bin/sh export CC=arm-linux-androideabi-gcc export CXX=arm-linux-androideabi-g++ export AR=arm-linux-androideabi-ar export LD=arm-linux-androideabi-ld export CFLAGS=" --sysroot=/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm " export LDFLAGS=" -L/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm/usr/lib " ./configure --enable-static --prefix=/opt/ndk/openlib --host=arm-linux |
1.3.2 編譯
1) ./myconfig.sh
執行上述配置指令碼,開始配置
2) make
3) make install
一切正常,將在/opt/ndk/openlib下存放輸出庫及標頭檔案。
1.4 x264的編譯
x264屬於VLC的一部分,當前的原始碼位置為:
ftp://ftp.videolan.org/pub/videolan/x264/snapshots/
本篇使用的原始碼版本為x264-snapshot-20140723-2245-stable.tar.bz2
1.4.1 修改configure指令碼
這一步的目的是使輸出的庫檔案不帶版本號。如果你堅持認為版本號不影響你的開發,則忽略本小節。
找到這一位置:
else echo "SOSUFFIX=so" >> config.mak echo "SONAME=libx264.so.$API" >> config.mak echo "SOFLAGS=-shared -Wl,-soname,\$(SONAME) $SOFLAGS" >> config.mak fi |
將粗體字修改為:(即去掉$API字尾)
echo "SONAME=libx264.so" >> config.mak |
1.4.2 新建配置指令碼
新建myconfig.sh配置指令碼,
#!/bin/sh export CC=arm-linux-androideabi-gcc export CXX=arm-linux-androideabi-g++ export AR=arm-linux-androideabi-ar export LD=arm-linux-androideabi-ld export AS=arm-linux-androideabi-gcc export CFLAGS=" --sysroot=/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16" export LDFLAGS=" -L/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm/usr/lib -march=armv7-a -Wl,--fix-cortex-a8 " ./configure --enable-static --enable-shared --prefix=/opt/ndk/openlib --host=arm-linux |
1.4.3 編譯
1) ./myconfig.sh
執行上述配置指令碼,開始配置
2) make
3) make install
1.5 FFmpeg的編譯
本示例使用的是FFmpeg2.1.3版本,可以從其官網ffmpeg.org上下載。如果不需要x264/aac/lame,可以直接進行本節的編譯。
1.5.1 修改configure指令碼
本節的目的是讓輸出的庫不含有版本號。
先找到configure的如下位置:
SHFLAGS='-shared -Wl,-soname,$$(@F)' LIBPREF="lib" LIBSUF=".a" FULLNAME='$(NAME)$(BUILDSUF)' LIBNAME='$(LIBPREF)$(FULLNAME)$(LIBSUF)' SLIBPREF="lib" SLIBSUF=".so" SLIBNAME='$(SLIBPREF)$(FULLNAME)$(SLIBSUF)' SLIBNAME_WITH_VERSION='$(SLIBNAME).$(LIBVERSION)' 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_VERSION='$(SLIBNAME)' SLIBNAME_WITH_MAJOR='$(SLIBNAME)' LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"' SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)' SLIB_INSTALL_LINKS= |
1.5.2 修改配置指令碼
新建myconfig.sh
export NDK_ROOT=/opt/ndk export TMPDIR=/tmp ./configure --prefix=$NDK_ROOT/ffmpeg --sysroot=$NDK_ROOT/android-ndk-r8e/platforms/android-14/arch-arm --cross-prefix=arm-linux-androideabi- --target-os=linux --arch=arm --extra-cflags="-I$NDK_ROOT/openlib/include -fPIC " --extra-ldflags=-L$NDK_ROOT/openlib/lib --disable-programs --disable-doc --enable-shared --enable-cross-compile --enable-gpl --enable-nonfree --enable-libx264 --enable-libmp3lame --enable-libfdk-aac |
這個指令碼中是把x264, fdk-aac, lame全部編譯上了,你可以視自己的情況來修改。
1.5.3 編譯
1) ./myconfig.sh
執行上述配置指令碼,開始配置
2) make
3) make install
1.6 在Android.mk中引用FFmpeg庫
1.6.1 使用靜態庫
推薦使用靜態庫。需要注意,FFmpeg庫的靜態庫引用順序是不能隨便寫的,為了避免不必要的麻煩,請照抄以下配置。
在你的Android.mk中新增以下幾行(見黑體字部分)
LOCAL_LDLIBS += -llog -lz # ffmpeg FFMPEG=/opt/ndk LOCAL_CFLAGS += -I$(FFMPEG)/include LOCAL_LDLIBS += -l$(FFMPEG)/lib/libavformat.a LOCAL_LDLIBS += -l$(FFMPEG)/lib/libavcodec.a LOCAL_LDLIBS += -l$(FFMPEG)/lib/libavdevice.a LOCAL_LDLIBS += -l$(FFMPEG)/lib/libswresample.a LOCAL_LDLIBS += -l$(FFMPEG)/lib/libavdevice.a LOCAL_LDLIBS += -l$(FFMPEG)/lib/libswscale.a LOCAL_LDLIBS += -l$(FFMPEG)/lib/libpostproc.a LOCAL_LDLIBS += -l$(FFMPEG)/lib/libavutil.a # fdk_aac LOCAL_LDLIBS += -l/opt/ndk/lib/libfdk-aac.a LOCAL_LDLIBS += -l/opt/ndk/lib/libmp3lame.a LOCAL_LDLIBS += -l/opt/ndk/lib/ libx264.a include $(BUILD_SHARED_LIBRARY) |
1.6.2 使用動態庫
不推薦使用動態庫,此過程過於複雜。要注意的有兩點:①編譯的時候,必須去除庫的版本號 ② 在Java程式碼中載入的時候,要注意載入的順序。
以下可以加在Android.mk中,但是僅供參考,遇到自己問題需要自己除錯
# ffmpeg FFMPEG=f:/Ndk/ffmpeg LOCAL_CFLAGS += -I$(FFMPEG)/include LOCAL_LDLIBS += -L$(FFMPEG)/lib LOCAL_LDLIBS += -lavformat -lavcodec -lswresample -lswscale -lavutil -lavfilter include $(BUILD_SHARED_LIBRARY) |
1.6.3 在C++中使用ffmpeg
ffmpeg的庫是按C編譯的,裡面的符號都是C格式,因此,若在C++中使用,還是要使用extern "C"這種技術。相關語法請參考《C/C++語法指南》(作者:邵發,官網http://www.afanihao.cn)。
為了大家的方便,在/opt/ndk/ffmpeg/include下新建一個ffmpeg.h,內容為:
#ifndef _FFMPEG_H #define _FFMPEG_H #ifdef __cplusplus extern "C" { #define INT64_C(val) val##LL #define UINT64_C(val) val##ULL #endif #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libswscale/swscale.h> #include <libavutil/avutil.h> #include <libavutil/opt.h> #include <libavutil/imgutils.h> #include <libswresample/swresample.h> #include <libavutil/error.h> #include <libavfilter/avfiltergraph.h> #include <libavfilter/avcodec.h> #include <libavfilter/buffersink.h> #include <libavfilter/buffersrc.h> #ifdef __cplusplus } #endif #endif |
然後在C++程式碼中直接#include "ffmpeg.h"就可以了。
相關推薦
Android/NDK環境下FFmpeg及AAC,MP3,X264的編譯
本篇介紹在Android/Ndk環境下FFmpeg的編譯及使用, FFmpeg自帶了H264、AAC、MP3的解碼器,但卻沒有(或沒有好的)相應的編碼器。相應的編碼器需要使用第三方庫。推薦使用的第三方庫為x264(H264編碼) 、FDK_AAC(AAC編碼),lame(M
Linux下Android NDK環境配置以及配合eclipse使用NDK
轉自:http://blog.csdn.net/zhouyuanjing/article/details/7553706 ,感謝作者! 一.下載NDK 二.配置環境 從r7版本開始,Linux下直接解壓就可以使用,在windows下cygwin也已經整合在NDK
Android開發——Android Studio下使用Cmake在NDK環境下移植Dlib庫
環境要求 使用AS2015平臺,SDK Manager中已經安裝了Cmake(編譯工具),NDK(環境),LLDB(偵錯程式)。沒有裝的話,開啟SDK Manager選中安裝重啟AS就可以了。 AS專案結構: 我從不勾選C++ Support的專案開始
eclipse開發android-ndk環境所需工具包及安裝配置方法
一、準備工具包 到網盤下載android相關工具包; 地址:https://pan.baidu.com/s/1kUSRu31 二、安裝 1、安裝eclipse、adt、sdk; 解壓adt-bu
Windows環境下Android NDK環境搭建
前面介紹Windows下Android 開發環境配置,主要是面向JAVA開發環境,對只做APK上層應用開發人員來講,基本夠用了,由於Linux系統的許可權限制和Android封裝架構限制,很多涉及底層裝置、介面、驅動控制的應用開發,不得不使用到本文的NDK開發環境(基於A
Android NDK 環境搭建
pad str 還要 ndk路徑 不出 tar evel 例如 command 使用最新ndk,直接拋棄cygwin,曾經做Android的項目要用到NDK就必需要下載NDK,下載安裝Cygwin(模擬Linux環境用的),下載CDT(Eclipse C/C++開發插件
在Windows環境下安裝及配置gcc編譯器
我們都知道,gcc是GNU作業系統的編譯套件,那麼在Windows系統下可以使用gcc嗎?答案是可以的。 介紹MinGW 首先我們先介紹下MinGW,MinGM是指只用自由軟體來生成純粹的Win32可執行檔案的編譯環境,它是Minimalist GNU on Windows的略稱,見名知意,
Redis學習(一):Linux系統環境下安裝及編譯Redis
一、簡介 Redis(Remote Dictionary Server)是由義大利人Salvatore Sanfilippo(網名:antirez)開發的一款記憶體快取記憶體資料庫。它是一個key-value儲存系統,它支援豐富的資料型別,如:String
JAVA(JDK)在linux環境下部署及配置環境變數
1.首先在網上下載一個jdk的壓縮檔案,以gz為結尾的 2.開啟機器。cd /usr/local 到這個目錄下,rz上傳檔案 3.等待檔案上傳好後,ll檢視一下,然後建立一個資料夾mkdir -p /usr/java。之後把jdk檔案移動到java目錄下。mv
一定能成功的Android NDK環境配置教程
前言 ● 在Android開發中,使用 NDK開發的需求正逐漸增大 ● 但在Android使用NDK前需要進行 相關環境配置 ● 本文主要講解 在Mac情況下的Android NDK配置,希望你們會喜歡 1. 步驟說明 下面,我將一步步講解如何進行NDK環境配置。
Android NDK環境編譯新增第三方動態庫
我們在使用ndk編譯時,直接用ndk-build的方式,經常有可能用到其他人的so庫 我們需要通過Android.mk中配置,才能通過編譯,不然會出現編譯錯誤,如下 Android NDK: Module demo depends on undefined module
解決OPPO手機在Android studio 環境下安裝錯誤執行失敗的問題
崩潰日誌重現: 今天遇到個令人煩躁的問題,通過as除錯apk時,在OPPO上安裝執行會出現apk icon錯誤label錯誤,以及不能正常啟動的問題。 2018-12-26 10:44:35.028 6795-6795/cn.xxx.xxx E/AndroidRuntime: FATAL
Android root環境下的一些可用操作(關機命令,系統時間,重啟命令)
近期正在做一些需要root許可權的功能,比如關機,重啟等,下面總結一下用過的root嚇得linux命令使用 1.重啟操作 Runtime.getRuntime().exec("su -c rebo
深度學習筆記整理-pycharm環境下開發及執行
1. 關於軟體安裝: Anaconda---->>>安裝python3.6 package---->>>安裝pycharm IDE------->>>配置interpretation
Linux環境下ffmpeg的配置步驟以及簡單的使用命令
資源連結:http://download.csdn.net/detail/hlj_include/9599667 第一步:建議安裝目錄:usr/local/目錄下 lame-3.99.5.tar.gz(1)、tar -zxvf lame-3.99.5.tar.gz (2)
window環境下安裝及使用composer[初體驗篇]
目前在很多開源專案中 總能看到 composer 命令,就像下面一樣 composer require league/oauth2-server 然而我卻不懂這是幹嘛的,尷尬了。 所以我就來看看這是什麼玩兒意。 先來兩個參考地址: composer
Android Studio環境下搭建ReactNative
1.安裝Android Studio首先肯定是 安裝Android Studio(包含SDK)(國內推薦)ps:這裡有一點要注意,需要為SDK配置環境變數,名稱必須為ANDROID_HOME2.安裝Nodo.js(自帶npm)從官網下載node.js的官方4.1版本或更高版本
學徒淺析Android開發——windows64下FFmpeg編譯問題彙總
最近在編譯FFmpeg的過程中著實遇到了一堆問題,FFmpeg其實更適合在LINUX環境下進行開發和封裝,因為它所依賴的編譯工具和功能擴充套件外掛在LINUX環境下更容易配置。而自己是在windows64環境下進行的編譯工作,著實給自己找了不少事幹。下面分享下自己在win
Android ndk呼叫STL庫及OpenSSL庫
在Android.mk需要加上: # 標頭檔案路徑 LOCAL_C_INCLUDES += $(LOCAL_PATH) LOCAL_C_INCLUDES += $(NDK_ROOT)\sources\cxx-stl\stlport\stlport LOCAL_C_IN
Linux環境下FFMPEG的安裝與配置
首先,安裝相關編碼器 lame-3.100.tar.gz tar -zxvf lame-3.100.tar.gz cd lame-3.100 ./configure make make install make clean libogg-1.3.3.tar.gz