android ffmpeg4.0.2編譯過程記錄

這裏記錄一下ffmpeg的編譯過程而且在Andorid中使用的過程。java

編譯ffmpeg

這裏拿的當前日期最新的release版本ffmpeg4.0.2,編譯環境mac,下載mac版本的ffmepg後進行編譯,編譯腳本build.sh以下:linux

#!/bin/bash
export NDK=/Users/linchen/Library/Android/sdk/ndk-bundle
export SYSROOT=$NDK/platforms/android-19/arch-arm/
export TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
export CPU=arm
export PREFIX=/Users/linchen/Desktop/arm #最終編譯後的頭文件以及so包的位置
export ADDI_CFLAGS="-marm"
function build_one
{
./configure \
    --prefix=$PREFIX \
    --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
    --arch=arm \
    --sysroot=$SYSROOT \
    --extra-cflags="-Os -fpic $ADDI_CFLAGS" \
    --extra-ldflags="$ADDI_LDFLAGS" \
    --cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \
    --nm=$TOOLCHAIN/bin/arm-linux-androideabi-nm \
    --enable-shared \
    --enable-runtime-cpudetect \
    --enable-gpl \
    --enable-small \
    --target-os=android \
    --enable-cross-compile \
    --disable-debug \
    --disable-static \
    --disable-doc \
    --disable-asm \
    --disable-ffmpeg \
    --disable-ffplay \
    --disable-ffprobe \
    --enable-postproc \
    --enable-avdevice \
    --disable-symver \
    --disable-stripping \
$ADDITIONAL_CONFIGURE_FLAG
sed -i '' 's/HAVE_LRINT 0/HAVE_LRINT 1/g' config.h
sed -i '' 's/HAVE_LRINTF 0/HAVE_LRINTF 1/g' config.h
sed -i '' 's/HAVE_ROUND 0/HAVE_ROUND 1/g' config.h
sed -i '' 's/HAVE_ROUNDF 0/HAVE_ROUNDF 1/g' config.h
sed -i '' 's/HAVE_TRUNC 0/HAVE_TRUNC 1/g' config.h
sed -i '' 's/HAVE_TRUNCF 0/HAVE_TRUNCF 1/g' config.h
sed -i '' 's/HAVE_CBRT 0/HAVE_CBRT 1/g' config.h
sed -i '' 's/HAVE_RINT 0/HAVE_RINT 1/g' config.h
make clean
# 這裏是定義用幾個CPU編譯
make -j4
make install
}
build_one

build.sh在ffmpeg4.0.2的根目錄下,首先須要安裝一些須要的編譯環境如gcc等,因爲個人機子中之前已經安裝了,因此直接運行bash build.sh命令就能夠了,編譯後在個人桌面上會出現arm文件夾:android

其中include文件夾是導出的頭文件文件夾,lib中的so包是須要使用的,接下來新建一個支持c++的Android項目,在新建的時候選擇support c++,Android Studio會自動幫咱們配置好,接下添加編譯好的文件到Android Studio中: c++

因爲個人手機是arm64-v8a的cpu架構,又因爲編譯ffmpeg選擇的架構,因此這裏使用armeabi通用架構支持,所以文件夾就建立了armeabi,若是手機cpu架構不一樣,能夠再編譯ffmpeg的時候指定對應的架構,具體參考這篇文章git

接下來編寫一下Cmake代碼:github

cmake_minimum_required(VERSION 3.4.1)


add_library( # Sets the name of the library.
        native-lib

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        src/main/cpp/native-lib.cpp)



find_library( # Sets the name of the path variable.
        log-lib

        # Specifies the name of the NDK library that
        # you want CMake to locate.
        log)


set(distribution_DIR ${CMAKE_SOURCE_DIR}/src/main/jni/armeabi)
add_library( avutil
             SHARED
             IMPORTED )
set_target_properties( avutil
                       PROPERTIES IMPORTED_LOCATION
                       ${distribution_DIR}/libavutil.so)
add_library( swresample
             SHARED
             IMPORTED )
set_target_properties( swresample
                       PROPERTIES IMPORTED_LOCATION
                       ${distribution_DIR}/libswresample.so)
add_library( avcodec
             SHARED
             IMPORTED )
set_target_properties( avcodec
                       PROPERTIES IMPORTED_LOCATION
                       ${distribution_DIR}/libavcodec.so)
add_library( avfilter
             SHARED
             IMPORTED )
set_target_properties( avfilter
                       PROPERTIES IMPORTED_LOCATION
                       ${distribution_DIR}/libavfilter.so)
add_library( swscale
             SHARED
             IMPORTED )
set_target_properties( swscale
                       PROPERTIES IMPORTED_LOCATION
                       ${distribution_DIR}/libswscale.so)
add_library( avdevice
             SHARED
             IMPORTED )
set_target_properties( avdevice
                       PROPERTIES IMPORTED_LOCATION
                       ${distribution_DIR}/libavdevice.so)
add_library( avformat
             SHARED
             IMPORTED )
set_target_properties( avformat
                       PROPERTIES IMPORTED_LOCATION
                       ${distribution_DIR}/libavformat.so)
add_library( postproc
             SHARED
             IMPORTED )
set_target_properties( postproc
                       PROPERTIES IMPORTED_LOCATION
                       ${distribution_DIR}/libpostproc.so)
set(CMAKE_VERBOSE_MAKEFILE on)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
include_directories(src/main/cpp)
include_directories(src/main/jni/include)

target_link_libraries( # Specifies the target library.
        native-lib
        avutil       #工具庫(大部分須要)
        swresample    #音頻採樣數據格式轉換
        avcodec      #編解碼(重要)
        avfilter      #濾鏡特效處理
        swscale       #視頻像素數據格式轉換
        avdevice     #各類設備的輸入輸出
        avformat     #封裝格式處理
        postproc     #後加工


        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})

而後再MainActivity中使用so庫:bash

public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
	//加載so包是有序的必定要那麼寫,不過這裏我是複製過來的,因此沒出現問題
        System.loadLibrary("avutil");
        System.loadLibrary("swresample");
        System.loadLibrary("avcodec");
        System.loadLibrary("avfilter");
        System.loadLibrary("swscale");
        System.loadLibrary("avdevice");
        System.loadLibrary("avformat");
        System.loadLibrary("postproc");
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();
}

這裏編譯過程當中遇到一個問題:架構

Build command failed. Error while executing process /Users/linchen/Library/Android/sdk/cmake/3.6.4111459/bin/cmake with arguments {--app

...ide

../../../../src/main/jni/armeabi/libavutil.so: error adding symbols: File in wrong format clang++: error: linker command failed with exit code 1 (use -v to see invocation) ninja: build stopped: subcommand failed.

問題是jni文件夾下的架構包缺失,使用ndk abi過濾器過濾便可:

ndk {
            abiFilters 'armeabi'
        }

編譯完成後運行項目發現直接奔潰了,說ffmpeg的so包找不到,解壓apk一看還真是,最終發現設置sourceSets的路徑不對,修改以下:

sourceSets{
        main{
            jniLibs.srcDirs = ['src/main/jni']
        }
    }

最終編譯成功,項目正常啓動,不過還沒寫代碼驗證,這裏主要先記錄一下配置的過程。

項目地址以下:

https://github.com/JerryChan123/FFmpegDemo

參考資料

https://www.jianshu.com/p/da64059799d5

https://www.jianshu.com/p/3b58174e89f1

相關文章
相關標籤/搜索