您的位置:首页 > 其它

基于最新版本ffmpeg3.2.x的编译和集成

2017-03-27 17:31 411 查看
前面用了大概6篇和大家分享了关于JNI的一系列内容,相信大家看过后肯定对JNI有了大致的了解。其实JNI的主要内容基本都是API的一些使用操作。

最近在研究Android音视频的一些内容,今天就和大家分享一下如何编译ffmpeg并集成到Android Studio环境下使用。

提示:

1. 编译ffmpeg基于window10环境

2. Android Studio版本为2.2+

3. ffmpeg版本为3.x

一、编译ffmpeg

ffmpeg在linux操作系统下编译要方便的多,在window下需要我们做一些额外的工作,我们使用MinGw工具来编译。

1.安装MinGw

  MinGw的exe文件和源码开源在SourceForge,点击即可下载

2. 安装完成后,下载msys-base和mingw-32-gcc-ada两个库文件即可。这里我们主要是使用gcc来完成编译工作。

3. 将bin目录配置到系统Path环境变量:

  


4. 因为ffmpeg编译出来的so文件后缀不能直接在Android环境下使用,所以需要我们找到ffmpeg文件夹下的configure文件并打开,搜索SLIBNAME_WITH_MAJOR定位到该行,将原来的:

    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_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'  

    LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'  

    SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'  

    SLIB_INSTALL_LINKS='$(SLIBNAME)'

也就是修改编译出来的so文件后缀为.so形式。

5. 在ffmpeg目录下创建一个build_android.sh文件,拷贝如下代码:

#!/bin/bash

export TMPDIR=C:/Users/Song/Desktop/ffmpeg-3.2.4/tmpdir

NDK=D:/Android/android_studio/sdk/ndk-bundle

SYSROOT=$NDK/platforms/android-23/arch-arm/

TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64

CPU=arm

PREFIX=C:/Users/Song/Desktop/ffmpeg-3.2.4/install

ADDI_CFLAGS="-marm"

function build_one

{

./configure \

--prefix=$PREFIX \

--enable-shared \

--disable-static \

--disable-doc \

--disable-ffmpeg \

--disable-ffplay \

--disable-ffprobe \

--disable-ffserver \

--disable-doc \

--disable-symver \

--enable-small \

--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \

--target-os=linux \

--arch=arm \

--enable-cross-compile \

--sysroot=$SYSROOT \

--extra-cflags="-Os -fpic $ADDI_CFLAGS" \

--extra-ldflags="$ADDI_LDFLAGS" \

$ADDITIONAL_CONFIGURE_FLAG

make clean

make

make install

}

build_one

read -p "Press any key to continue." var

上面需要我们注意的地方有以下几点:

(1)TMPDIR :该字段指向一个文件夹目录,该文件夹路径可任意指定。作用是在编译ffmpeg期间,会生成一些临时文件用于存放在该目录,编译完成后,临时文件会自动清除。

(2)NDK:即你本地电脑NDK目录

(3)SYSROOT:根据你目前的NDK中platforms文件夹下的版本来设置。

(4)PREFIX:ffmpeg编译完成的so文件存放路径,可随意指定。

其它保持不变即可。

6. 执行gcc命令编译

 打开MinGW目录下的msys文件夹,找到msys.bat,打开:

 

 


cd切换到ffmpeg根目录,执行./build_android.sh开始编译,这时,你可以先去泡杯咖啡喝上一口等待它编译完成。经锅一段时间后,当ffmpeg编译完成,打开第5步中我们配置的PREFIX所指向的目录。可以发现多了两个文件夹:

 


其中,include就是编译出来的头文件,lib中就是so文件了:

 

  

    


此时,对于ffmpeg的编译工作就搞定啦~,接下来我们就要将编译出来的文件集成到Android Studio中进行校验是否正确,如何集成呢?继续来看~

二、ffmpeg集成到Android Studio

Android Studio 2.2以上版本采用了cmake来代替老版本的ndk-build方式。在NDK的开发上也越来越方便。我们也使用cmake的方式来编译ffmpeg。

1. 将编译好的头文件和so库添加到cpp目录下

 


2. 在main目录下创建jniLibs目录存放so文件:

 


2. 配置CMakeLists文件

#添加ffmpeg对应的头文件目录
include_directories(src/main/cpp/ffmpeg3/include)

#添加库文件,实际上就是引入so文件,IMPORT代表从第三方引入
add_library(avcodec-lib SHARED IMPORTED)
#这句话是ffmpeg对应的so文件,so文件是放到JNILibs这个文件夹中
set_target_properties(avcodec-lib PROPERTIES IMPORTED_LOCATION
${CMAKE_CURRENT_SOURCE_DIR}/src/main/jniLibs/armeabi/libavcodec-57.so)

add_library(avdevic-lib SHARED IMPORTED)
set_target_properties(avdevic-lib PROPERTIES IMPORTED_LOCATION
${CMAKE_CURRENT_SOURCE_DIR}/src/main/jniLibs/armeabi/libavdevice-57.so)

add_library(avfilter-lib SHARED IMPORTED)
set_target_properties(avfilter-lib PROPERTIES IMPORTED_LOCATION
${CMAKE_CURRENT_SOURCE_DIR}/src/main/jniLibs/armeabi/libavfilter-6.so)

add_library(avformat-lib SHARED IMPORTED)
set_target_properties(avformat-lib PROPERTIES IMPORTED_LOCATION
${CMAKE_CURRENT_SOURCE_DIR}/src/main/jniLibs/armeabi/libavformat-57.so)

add_library(avutil-lib SHARED IMPORTED)
set_target_properties(avutil-lib PROPERTIES IMPORTED_LOCATION
${CMAKE_CURRENT_SOURCE_DIR}/src/main/jniLibs/armeabi/libavutil-55.so)

add_library(swresample-lib SHARED IMPORTED)
set_target_properties(swresample-lib PROPERTIES IMPORTED_LOCATION
${CMAKE_CURRENT_SOURCE_DIR}/src/main/jniLibs/armeabi/libswresample-2.so)

add_library(swscale-lib SHARED IMPORTED)
set_target_properties(swscale-lib PROPERTIES IMPORTED_LOCATION
${CMAKE_CURRENT_SOURCE_DIR}/src/main/jniLibs/armeabi/libswscale-4.so)

# 指定库CMake链接到您的目标库。 您可以链接多个库,例如你在中定义的库构建脚本,预构建的第三方库或系统库.
target_link_libraries( # 指定目标库.
native-l

# 为native-lib加载ffmpeg库
avcodec-lib
avdevic-lib
avfilter-lib
avformat-lib
avutil-lib
swresample-lib
swscale-lib

# 将目标库链接到日志库包括在NDK中.
${log-lib} )

在CmakeList文件中:

(1)首先使用include_directories配置了ffmpeg的头文件路径。将ffmpeg的头文件包含进来。

(2)将JniLibs目录下的so文件引入。

(3)将目标库和引入的so文件链接。

经过以上几步,ffmpeg就集成到了我们的工程下。接下来就是测试啦~

1. 打开app.gradle,在defaultConfig下配置:

externalNativeBuild {
cmake {
cppFlags "-frtti -fexceptions"
arguments '-DANDROID_TOOLCHAIN=clang','-DANDROID_STL=gnustl_static'
}
}

ndk {
abiFilters 'armeabi' //arm64-v8a','x86', 'x86_64', 'armeabi-v7a'
}


2. 在cpp目录下创建cpp文件,首先包含头文件

extern "C"{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
}


3. 调用ffmpeg的API函数,例如:

 


如果程序没有提示错误,证明ffmpeg已经成功的集成啦~

ok,以上就是关于ffmpeg的编译和使用内容,有问题的朋友可以给我留言哈~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: