ffmpeg compile

{

接触FFmpeg,加上为此查找/整理的一些有关在android 手机上使用ffmpeg 的具体方法,作为个人知识点的整理记录如下,当然如果有幸能帮助到某些人自然更好。有不对的地方还希望指点一二。

把查阅的相关资料或者不错的文章分享在前面吧:

雷霄骅博客:http://blog.csdn.net/leixiaohua1020/article/details/15811977
https://stackoverflow.com/questions/4725773/ffmpeg-on-android
FFmpeg下载地址:https://ffmpeg.org/releases/

(之前新闻上得知雷霄骅去世的消息时,还每天路过传媒大学……唉)

一,必要准备
    一般需要在android手机上使用FFmpeg ,首先需要将将FFmpeg 编译为android 能使用的.so 文件(动态库)。所以我们首先需要准备:

1,编译环境——Windows,Mac OS,Linux……不同的系统在具体操作时可能会有所不同。以本文为例,锁使用的编译环境是在阿里云服务上搭建Ubuntu(Linux系统),大致配置如下(仅做学习使用):



2,FFmpeg源码。

源码下载地址
本文以ffmpeg-3.2.1.tar.gz版本为例 。

(以本文为例,登录阿里服务器后)定位到对应的文件目录下使用命令:

wget https://ffmpeg.org/releases/ffmpeg-3.2.1.tar.gz
1
下载源码并使用解压到当前目录,解压命令如下:

unzip ffmpeg-3.2.1.tar.gz
1
3,NDK
本文所使用的NDK版本是:android-ndk-r13b-linux-x86_64.zip。可以同样通过wget 和 unzip 命令下载并解压到对应的目录下(不用配置环境变量)。

注意:如果你想要以本文作为实践参照,请务必将你准备的FFmpeg源码和下载的ndk 版本与本文给出的保持一致,保持一致,保持一致。因为ffmpeg 个版本的改动,以及ndk 的版本改动,导致后续编译动态库时的配置参数会有所不同,加之FFmpeg 的中文学习资料有限(英文的又理解不了),所以的使用其他版本可能很有可能无法编译通过,至少我已经尝试过使用更新的版本进行编译......但最终还是放弃了......
1
二,配置文件
    在具体编译动态库之前你还需要设置相应的编译规则。具体如下:

1,修改.so文件命名规则

默认编译后的.so文件格式为:文件明+.so+三段版本号的格式比如libavformat.so.57.0.101。这样的文件格式不太符合我们的使用要求,而且即便是将这样的文件名称简单粗暴的删除.so后面的版本号,在实际使用时也无法编译。所以修改如下:

定位到下载解压的ffmpeg 根目录下打开configure文件

vim configure
1
在大约3247行左右的地方

替换:

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)'
1
2
3
4
为:

SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'
1
2
3
4
保存并退出。

注意:由于FFmpeg 的不同版本,这里所说的修改行号,以及  原  
命名规则可能会有所部同。

2,编写编译(.sh)脚本

首先在ffmpeg 跟目录下创建build_android.sh(名称随意):

vim build_android.sh
1
(编辑状态下)编入以下内容:

#!/bin/bash
make clean
#填写你具体的ndk解压目录
export NDK=/android/ndk/android-ndk-r13b
export SYSROOT=$NDK/platforms/android-9/arch-arm/
export TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
export CPU=arm
#编译后的文件会放置在 当前路径下的android/arm/下
export PREFIX=$(pwd)/android/$CPU
export ADDI_CFLAGS="-marm"


#./configure 即为ffmpeg 根目录下的可执行文件configure
#你可以在ffmpeg根目录下使用./configure --hellp 查看 ./configure后可填入的参数。

./configure --target-os=linux
        --prefix=$PREFIX --arch=arm
        --disable-doc
        --enable-shared
        --disable-static
        --disable-yasm
        --disable-symver
        --enable-gpl
        --disable-ffmpeg
        --disable-ffplay
        --disable-ffprobe
        --disable-ffserver
        --disable-doc
        --disable-symver
        --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi-
        --enable-cross-compile
        --sysroot=$SYSROOT
        --extra-cflags="-Os -fpic $ADDI_CFLAGS"
        --extra-ldflags="$ADDI_CFLAGS"
        $ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install

保存并退出

注意:
–disable-yasm
1,在下文实际编译时可能会提示你需要安装yasm(在更早期的版本中没有这相关提示)。据说yasm时为了提高ffmpeg编译速度,但我实际感觉好想并没有多快,估计是我打开的方式不对吧。
2,上文中每行的编码结束后不要留空格。
3,确保NDK,SYSROOT,TOOLCHAIN 等相关变量存储的是你自己下载解压的ndk真实目录。并确认你的系统是32位还是64位——必须与ndk的版本保持一致。

三,编译生成.so文件
执行具体编译之前需要为build_android.sh文件添加的可执行权限。操作命令如下:

chmod +x build_android.sh
1
执行编译命令:

./build_android.sh
1
实际编译可能需要几分钟。
编译完成后,在当前目录下的android/arm/下会有inclue 和 lib两文件夹
inclue 存放的是相关模块的.h文件:


lib 存放的就是.so文件


四,验证
1,新建Android 项目。



勾选:Include C++ support



(注意标注)

2,将之前生成的.so文件和头/.h文件如下图拷贝到指定目录



    注意:这里拷贝的.so文件必须是带有版本号的,否则在实际运行时会报错。
    (另外这里只是简单粗暴的吧所有模块都拷贝到项目中,实际项目中可能并不需要,这里只作为学习使用。)
1
2
3,build.gradle配置

在app目录下的build.gradle中如下图添加支持cpu架构模式


(当前内容暂且只考虑这一中cpu)

然后sync

3,CMakeList.txt配置

  a,在默认CMakeList.txt文件内容中导入头文件。

#导入头文件
include_directories(src/main/jniLibs/include)
1
2
  b,添加动态(.so)库。

#声明导入文件更目录变量ARM_DIR ,这使用了相对与系统的更目录,因为使用相对路径似乎不起作用
set(ARM_DIR /Users/填写你自己实际系统盘符绝对路的/demo/FFmpegForAndroidDemo/app/src/main/jniLibs)

#添加一个so 库范例。
add_library(avdevice-57
            SHARED
            IMPORTED)
set_target_properties(avdevice-57
                      PROPERTIES IMPORTED_LOCATION
                      ${ARM_DIR}/armeabi/libavdevice-57.so)

#其他so库与上相同格式添加                      
#链接库
target_link_libraries(
                       native-lib
                       avcodec-57
                       avdevice-57
                       avformat-57
                       avfilter-6
                       avutil-55
                       postproc-54
                       swresample-2
                       swscale-4
                       ${log-lib} )              

然后sync

注意:
不知道生么原因set_target_properties设置相对路径时似乎并
不管用。所以这里需要注意在声明ARM_DIR变量时需要赋值项目源
文件的绝对路径。
并且考虑到实际篇幅这里并没有粘贴完整cmakelist 配置,详细请查看项目代码。

  c,加载静态库。

(本文在默认创建的MainActivity 中加载)

static {
        System.loadLibrary("avcodec-57");
        System.loadLibrary("avdevice-57");
        System.loadLibrary("avfilter-6");
        System.loadLibrary("avformat-57");
        System.loadLibrary("avutil-55");
        System.loadLibrary("postproc-54");
        System.loadLibrary("swresample-2");
        System.loadLibrary("swscale-4");
        System.loadLibrary("native-lib");
    }
1
2
3
4
5
6
7
8
9
10
11
  d,调用方法,编译运行项目。

这里只做简单测试,所以没有详细使用FFmpeg 的相关方法。



注意:
1,上图中引入ffmpeg 的头文件确保写在

extern "C"
{

}
1
2
3
4
中,否则会编译会报错——找不到头文件。
2,

av_register_all()
1
为FFmpeg 库中较常见和重要的注册方法,具体使用不属于本片讲述范围。
————————————————
版权声明:本文为CSDN博主「一点一刻」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/longzw0/java/article/details/78820814

}

原文地址:https://www.cnblogs.com/YZFHKMS-X/p/12670110.html