FFmpeg 有六个常用的功能模块:
- libavformat:多媒体文件或协议的封装和解封装库;
- libavcodec:音视频编解码库;
- libavfilter:音视频、字幕滤镜库;
- libswscale:图像格式转换库;
- libswresample:音频重采样库;
- libavutil:工具库。
编译环境:
ffmpeg-4.2.2
android-ndk-r20b-linux-x86_64
NDK下载
1、NDK下载需要翻墙才能下载
2、解压 NDK
unzip android-ndk-r20b-linux-x86_64.zip
FFmpeg编译
编译前准备:
#1. 下载 ffmpeg-4.2.2
wget https://ffmpeg.org/releases/ffmpeg-4.2.2.tar.bz2
#2. 解压 FFmpeg
tar -jxvf ffmpeg-4.2.2.tar.bz2
#3. 运行 configure 脚本配置项目
./configure --disable-x86asm (运行该命令在Linux下面才有用)
在 FFmpeg 4.2.2 解压目录下创建编译脚本 build_android_ffmpeg_all.sh
#!/bin/bash
export NDK=/home/wangqi/ffmpeng/ndk/android-ndk-r20b #这里配置先你的 NDK 路径
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
function build_android
{
./configure \
--prefix=$PREFIX \
--enable-neon \
--enable-hwaccels \
--enable-gpl \
--disable-postproc \
--disable-debug \
--enable-small \
--enable-jni \
--enable-mediacodec \
--enable-decoder=h264_mediacodec \
--enable-static \
--enable-shared \
--disable-doc \
--enable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-avdevice \
--disable-doc \
--disable-symver \
--cross-prefix=$CROSS_PREFIX \
--target-os=android \
--arch=$ARCH \
--cpu=$CPU \
--cc=$CC \
--cxx=$CXX \
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $OPTIMIZE_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS"
make clean
make -j16
make install
echo "============================ build android arm64-v8a armeabi-v7a success =========================="
}
:<<eof
#arm64-v8a
ARCH=arm64
CPU=arm64
API=21
CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-
PREFIX=$(pwd)/android/arm64-v8a/$CPU
OPTIMIZE_CFLAGS="-march=$CPU"
build_android
eof
#armeabi-v7a
ARCH=arm
CPU=armv7
API=21
CC=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang
CXX=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++
SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
CROSS_PREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-
PREFIX=$(pwd)/android/armeabi-v7a/$CPU
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "
build_android
备注:写脚本的时候最好是用vim去写脚本,不要在window上面去编辑文本
修改脚本的权限以及执行脚本
chmod 777 build_android_ffmpeg_all.sh
./build_android_ffmpeg_all.sh
编译出来的静态库和动态库
FFmpeg集成
1、添加so库和加载头文件include进去
2、CMakeLists.txt文件配置
cmake_minimum_required(VERSION 3.4.1)
add_library(
native-lib
SHARED
native-lib.cpp )
message(“11111111111111111111”)
find_library(
log-lib
log )
set(FF ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs)
add_library(avcodec SHARED IMPORTED)
add_library(avformat SHARED IMPORTED)
add_library(avutil SHARED IMPORTED)
add_library(swscale SHARED IMPORTED)
add_library(swresample SHARED IMPORTED)
set_target_properties(avcodec PROPERTIES IMPORTED_LOCATION ${FF}/${ANDROID_ABI}/libavcodec.so)
set_target_properties(avformat PROPERTIES IMPORTED_LOCATION ${FF}/${ANDROID_ABI}/libavformat.so)
set_target_properties(avutil PROPERTIES IMPORTED_LOCATION ${FF}/${ANDROID_ABI}/libavutil.so)
set_target_properties(swscale PROPERTIES IMPORTED_LOCATION ${FF}/${ANDROID_ABI}/libswscale.so)
set_target_properties(swresample PROPERTIES IMPORTED_LOCATION ${FF}/${ANDROID_ABI}/libswresample.so)
target_include_directories(native-lib PRIVATE
src/main/cpp/include)
target_link_libraries(
native-lib
avcodec avformat avutil swscale swresample
${log-lib} )
3、配置我们的build.gradle文件
apply plugin: 'com.android.application'
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.zqc.ffmpegandroid"
minSdkVersion 14
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags ""
//java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.kylin.ffmpegdemo-kO2geDb3V54S0PSd4hzjqQ==/base.apk"],nativeLibraryDirectories=[/data/app/com.kylin.ffmpegdemo-kO2geDb3V54S0PSd4hzjqQ==/lib/arm64, /system/lib64, /system/product/lib64]]] couldn't find "libnative-lib.so"
abiFilters 'armeabi-v7a'//此处可以不加,但是如果此处加了,下面的没加则会报错,(老师就只加了这里,但是运行正常,我就不行,我也很费劲)
}
}
ndk {
abiFilters "armeabi-v7a"
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
}
//解决More than one file was found with OS independent path 'lib/armeabi-v7a/libavutil.so'.异常
packagingOptions {
pickFirst 'lib/armeabi-v7a/libavcodec.so'
pickFirst 'lib/armeabi-v7a/libavfilter.so'
pickFirst 'lib/armeabi-v7a/libavformat.so'
pickFirst 'lib/armeabi-v7a/libavutil.so'
pickFirst 'lib/armeabi-v7a/libswresample.so'
pickFirst 'lib/armeabi-v7a/libswscale.so'
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "3.10.2"
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
4、验证FFmpeng是否集成成功
extern "C"
{
#include "include/libavutil/avutil.h"
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_wq_ffmpegandroid_MainActivity_stream(JNIEnv *env, jobject thiz, jstring input_jstr,
jstring output_jstr) {
LOGE( "av_version_info. %s ",av_version_info());
return 0;
}
5、日志输出
av_version_info. 4.2.2