1. 程式人生 > >Android/NDK環境下FFmpeg及AAC,MP3,X264的編譯

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環境FFmpegAAC,MP3,X264編譯

本篇介紹在Android/Ndk環境下FFmpeg的編譯及使用, FFmpeg自帶了H264、AAC、MP3的解碼器,但卻沒有(或沒有好的)相應的編碼器。相應的編碼器需要使用第三方庫。推薦使用的第三方庫為x264(H264編碼) 、FDK_AAC(AAC編碼),lame(M

LinuxAndroid 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開發——windows64FFmpeg編譯問題彙總

最近在編譯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