FFmepg編譯及集成到 Android
- 編譯文件修改
- 打包so 執行
- 集成到Android
準備編譯
- 採用ubuntu系統編譯, 系統版本不影響
apt-get update
apt-get install yasm
apt-get install pkg-config
- 安裝 NDK 本文采用
ndk r15c 或 ndk r19
經測試,NDK版本影響不大,只要不是太低就好
ndk r15下載
ndk 最新版 - 下載FFmpeg 版本 本文采用 ffmpeg3.4.5
曾採用4.1.3版本,但是腳本文件有些問題,網上查閱的並不好用,文章末尾提供4.1.3版本sh(不一定好用,需要修改)
-
修改 configure
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)'
-
x264腳本 如果不需要,你需要將下方 ffmepg 腳本用的x264的地方加 # 下載 x264
#!/bin/bash NDK=/home/oblvion/Desktop/ffmpeg/android-ndk-r15c configure() { CPU=$1 PREFIX=$(pwd)/android/$CPU HOST="" CROSS_PREFIX="" SYSROOT="" if [ "$CPU" == "armv7-a" ] then HOST=arm-linux SYSROOT=$NDK/platforms/android-21/arch-arm/ CROSS_PREFIX=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi- else HOST=aarch64-linux SYSROOT=$NDK/platforms/android-21/arch-arm64/ CROSS_PREFIX=$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android- fi ./configure \ --prefix=$PREFIX \ --host=$HOST \ --enable-pic \ --enable-static \ --enalbe-neon \ --extra-cflags="-fPIE -pie" \ --extra-ldflags="-fPIE -pie" \ --cross-prefix=$CROSS_PREFIX \ --sysroot=$SYSROOT } build() { make clean cpu=$1 echo "build $cpu" configure $cpu #-j<CPU核心數> make -j4 make install } #build arm64 build armv7-a
-
ffmpeg 腳本
#!/bin/bash NDK=/home/oblvion/Desktop/ffmpeg/android-ndk-r15c ADDI_CFLAGS="-fPIE -pie" ADDI_LDFLAGS="-fPIE -pie" configure() { CPU=$1 PREFIX=$(pwd)/android/$CPU x264=$(pwd)/x264/android/$CPU HOST="" CROSS_PREFIX="" SYSROOT="" ARCH="" if [ "$CPU" == "armv7-a" ] then ARCH="arm" HOST=arm-linux SYSROOT=$NDK/platforms/android-21/arch-arm/ CROSS_PREFIX=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi- else ARCH="aarch64" HOST=aarch64-linux SYSROOT=$NDK/platforms/android-21/arch-arm64/ CROSS_PREFIX=$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android- fi ./configure \ --prefix=$PREFIX \ --disable-encoders \ --disable-decoders \ --disable-avdevice \ --disable-static \ --disable-doc \ --disable-ffplay \ --disable-network \ --disable-doc \ --disable-symver \ --enable-neon \ --enable-shared \ --enable-libx264 \ --enable-gpl \ --enable-pic \ --enable-jni \ --enable-pthreads \ --enable-mediacodec \ --enable-encoder=aac \ --enable-encoder=gif \ --enable-encoder=libopenjpeg \ --enable-encoder=libmp3lame \ --enable-encoder=libwavpack \ --enable-encoder=libx264 \ --enable-encoder=mpeg4 \ --enable-encoder=pcm_s16le \ --enable-encoder=png \ --enable-encoder=srt \ --enable-encoder=subrip \ --enable-encoder=yuv4 \ --enable-encoder=text \ --enable-decoder=aac \ --enable-decoder=aac_latm \ --enable-decoder=libopenjpeg \ --enable-decoder=mp3 \ --enable-decoder=mpeg4_mediacodec \ --enable-decoder=pcm_s16le \ --enable-decoder=flac \ --enable-decoder=flv \ --enable-decoder=gif \ --enable-decoder=png \ --enable-decoder=srt \ --enable-decoder=xsub \ --enable-decoder=yuv4 \ --enable-decoder=vp8_mediacodec \ --enable-decoder=h264_mediacodec \ --enable-decoder=hevc_mediacodec \ --enable-hwaccel=h264_mediacodec \ --enable-hwaccel=mpeg4_mediacodec \ --enable-ffmpeg \ --enable-bsf=aac_adtstoasc \ --enable-bsf=h264_mp4toannexb \ --enable-bsf=hevc_mp4toannexb \ --enable-bsf=mpeg4_unpack_bframes \ --enable-cross-compile \ --cross-prefix=$CROSS_PREFIX \ --target-os=android \ --arch=$ARCH \ --sysroot=$SYSROOT \ --extra-cflags="-I$x264/include $ADDI_CFLAGS" \ --extra-ldflags="-L$x264/lib" } build() { make clean cpu=$1 echo "build $cpu" configure $cpu make -j4 make install } #build arm64 build armv7-a
注意 腳本需要 chmod +x build.sh ,然後 sudo ./腳本執行
- 這個時候 你執行完腳本,如果幸運 ,能拿到 so文件了
準備集成到 ndk android 源碼中
- 創建 NDK 項目
- 源碼libs 目錄下導入 so
- 導入include文件
- 修改 build.gradle 文件
- 編輯CMake文件
cmake_minimum_required(VERSION 3.4.1)
set(lib_src_DIR ${CMAKE_SOURCE_DIR}/../../../libs/${ANDROID_ABI})
add_library(
native-lib
SHARED
native-lib.cpp)
add_library(
avcodec
SHARED
IMPORTED)
set_target_properties(
avcodec
PROPERTIES IMPORTED_LOCATION
${lib_src_DIR}/libavcodec.so)
add_library(
avfilter
SHARED
IMPORTED)
set_target_properties(
avfilter
PROPERTIES IMPORTED_LOCATION
${lib_src_DIR}/libavfilter.so)
add_library(
avformat
SHARED
IMPORTED)
set_target_properties(
avformat
PROPERTIES IMPORTED_LOCATION
${lib_src_DIR}/libavformat.so)
add_library(
avutil
SHARED
IMPORTED)
set_target_properties(
avutil
PROPERTIES IMPORTED_LOCATION
${lib_src_DIR}/libavutil.so)
add_library(
postproc
SHARED
IMPORTED)
set_target_properties(
postproc
PROPERTIES IMPORTED_LOCATION
${lib_src_DIR}/libpostproc.so)
add_library(
swresample
SHARED
IMPORTED)
set_target_properties(
swresample
PROPERTIES IMPORTED_LOCATION
${lib_src_DIR}/libswresample.so)
add_library(
swscale
SHARED
IMPORTED)
set_target_properties(
swscale
PROPERTIES IMPORTED_LOCATION
${lib_src_DIR}/libswscale.so)
find_library(
log-lib
log)
include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include)
target_link_libraries(
native-lib
avcodec
avfilter
avformat
avutil
postproc
swresample
swscale
${log-lib})
- 修改原來的 natice-lib.cpp 文件
#include <jni.h>
#include <string>
#include <android/log.h>
extern "C" {
#include "include/libavcodec/avcodec.h"
#include "include/libavfilter/avfilter.h"
#include "include/libavformat/avformat.h"
#include "include/libavutil/imgutils.h"
#include "include/libswresample/swresample.h"
#include "include/libswscale/swscale.h"
#include "include/libx264/x264.h"
}
extern "C"
JNIEXPORT jstring JNICALL
Java_com_wmtc_ndktest_MainActivity_stringFromFFmpeg(
JNIEnv *env,
jobject /* this */) {
char info[10000] = {0};
sprintf(info, "%s\n", avcodec_configuration());
return env->NewStringUTF(info);
}
OK。調用,執行,不出意外看到如下:
遇到的問題
ninja: error: xxxxxx missing and no known rule to make it
因爲你的 CMake文件錯誤,檢查一下undefined reference to 'avcodec_configuration()'
看看是否extern "C"
是這樣導入的 源碼文件extern "C" { #include "include/libavcodec/avcodec.h" #include "include/libavfilter/avfilter.h" #include "include/libavformat/avformat.h" #include "include/libavutil/imgutils.h" #include "include/libswresample/swresample.h" #include "include/libswscale/swscale.h" #include "include/libx264/x264.h" }