原来FFmpeg这么有意思-(二),Android程序员必看

 boolean isFileCopied = FileUtils.copyBinaryFromAssetsToData(App.getInstance(),
                        cpuArchNameFromAssets + File.separator + FileUtils.ffmpegFileName,
                        FileUtils.ffmpegFileName);

                // make file executable
                if (isFileCopied) {
                    if (!ffmpegFile.canExecute()) {
                        Log.d(BuildInfo.TAG, "FFmpeg is not executable, trying to make it executable ...");
                        if (ffmpegFile.setExecutable(true)) {
                            Log.d(BuildInfo.TAG, "FFmpeg is executable");
                        }
                    } else {
                        Log.d(BuildInfo.TAG, "FFmpeg is executable");
                    }
                }

复制代码

上面的代码自己可以编写。我这就不全部贴了。App运行起来后,把这个文件copy到本地,然后调用


ffmpegFile.setExecutable(true)

复制代码

这样就可以执行FFmpeg 了。Android中也提供了执行commend的方法


 public static Process run(String[] commandString) {
        Process process = null;
        try {
            process = Runtime.getRuntime().exec(commandString);
            String output = Util.convertInputStreamToString(process.getErrorStream());
            Log.i("cuieney",output);
        } catch (IOException e) {
            Log.e(BuildInfo.TAG,"Exception while trying to run: " + commandString+e.toString());
        }
        return process;
    }

复制代码

就是通过调用runtime.exec就可以了 把命令写进去就好。

run({"ffmpeg",""})

复制代码

这样就ok了。成功的话可以在logcat 中看到这些,log太多了 我就没复制


 ffmpeg version 4.0.2 Copyright (c) 2000-2018 the FFmpeg developersbuilt with gcc 4.9.x (GCC) 20150123 (prerelease)........

复制代码

我这里根据编译出来的库,完成了一些功能

接下来就是正题了。编译这个东西。

编译Android平台FFmpeg

关于编译Android 平台的库可能网上有一大堆,反正一搜索,肯定有你需要的,这边我主要教大家使用静态库而非动态库,这样你会省了很多很多的麻烦,各种so库的来回粘贴复制,还要写cmakelist文集,配置gradle,对于没怎么玩过FFmpeg的人来说可能需要搞很长时间,这里我将带给大家另一种玩法

动态库

动态库其实就是编译出来的so库,link到我们的项目中然后load library 然后通过jni的方式进行操作c上面的东西,这边就是简单概括一下,那我知道了需要哪些东西了,那我们接下来就是,编译这个so库,大家可以在网上看到FFmpeg编译出来的有很多so 你要一个一个的把他们放进我们的项目中。然后cmakelist里面添加东西。这里我教大家把这几个库编译到一个so里面,可以省了你很多麻烦

  • 以上准备都ok的话,这边就可以执行脚本命令了打开我们下载的FFmpeg压缩包,可以看到这些目录结构,我们编译主要用到的就是configure这个binary。可以在下图中看到

image.png

脚本我这边就把一部分代码贴上去,全部的我放在了github上了(下面这个脚本名称叫做build_ffmpeg_android.sh,可以在我上面的写的地址里找到),我会写一些注释在上面

可以看到下面的 代码中有一个MODULE(主要做一些里面库的enabel 和disable,把需要的库我们编译进去 不需要的当然是不用了) GENERAL(主要作用是一些参数的设置和额外的库添加)和LIB_TYPE(这个就是设置编译shared还是static的了)静态库或者动态库

function build
{
  pushd ffmpeg
  ./configure                           \
  --logfile=config.log                  \
  --target-os=android                   \
  --prefix=$PREFIX         \
  ${MODULE}                             \
  ${GENERAL}                            \
  ${LIB_TYPE}                           \
  --sysroot=$PLATFORM                   \
  --extra-cflags="-fPIE -fPIC -std=c11" \
  --extra-ldflags="$flags $shared_flag" \

  # essencial for dynamic library
  sed -i -E "s/^(#define HAVE_SYSCTL).*/\1 0/" config.h

  make clean
  make -j$NUM_OF_CORE
  make install

  popd
}

build

这个就是GENERAL的参数

GENERAL="                                             \
  --extra-libs="-lgcc"                                \
  --arch=${ARCH}                                      \
  --cc=$PREBUILT/bin/${BIN_PREFIX}-gcc        \
  --cross-prefix=$PREBUILT/bin/${BIN_PREFIX}- \
  --nm=$PREBUILT/bin/${BIN_PREFIX}-nm         \
  --extra-cflags="-I$X264_INCLUDE"    \
  --extra-ldflags="-L$X264_LIB"       \
"

复制代码

这个是module的参数 只放了一部分,用到的可以enable 用不到的disable 不然编译出来的库很大。那我们的apk也会相应的很大,可以到github下载原始文件

MODULE="                 \
  --enable-jni           \
  --enable-pic           \
  --enable-gpl           \
  --enable-zlib          \
  --enable-yasm          \
  --enable-small         \
  --enable-pthreads      \
  --enable-mediacodec    \
   --enable-libx264      \
  --enable-cross-compile \
  --disable-doc          \
  --disable-ffplay       \
  --disable-ffprobe      \
  --disable-network      \
  --enable-neon
  --disable-linux-perf   \
--enable-encoder=libx264 \
--enable-encoder=aac \
--enable-encoder=mpeg4 \
--enable-encoder=mjpeg \
--enable-encoder=png \
--disable-muxers \

复制代码

静态库

这边脚本里写了一些判断,我们可以执行脚本的时候 再加个字段就可以编译出我们需要的静态库,我这边的脚本名字叫做build_ffmpeg_android.sh,所以只要按照下面的命令执行即可

./build_ffmpeg_andori.sh static

如果你想编译动态库 只要把static 改成shared即可。

现在的电脑应该编译的很快,执行成功应该可以看到下面的目录,so已经编译出来了

image.png

静态库已经出来了

把编译出来的库合成一个so库

只要把以下的代码添加到编译脚本里面即可。

$TOOLCHAIN/bin/${BIN_PREFIX}-ld \
      -rpath-link=$PLATFORM/usr/lib \
      -L$PLATFORM/usr/lib \
      -L$PREFIX/lib \
      -L$X264_LIB \
      -soname libffmpeg.so -shared -nostdlib -Bsymbolic --whole-archive --no-undefined -o \
      $PREFIX/libffmpeg.so \
      $PREFIX/lib/libavcodec.a \
      $PREFIX/lib/libavfilter.a \
      $PREFIX/lib/libavformat.a \
      $PREFIX/lib/libavutil.a \
      $PREFIX/lib/libswresample.a \
      $PREFIX/lib/libswscale.a \
      $X264_ALIB/libx264.a \
      -lc -lm -lz -ldl -llog --dynamic-linker=/system/bin/linker \
      $TOOLCHAIN/lib/gcc/${BIN_PREFIX}/4.9.x/libgcc.a

从上面脚本可以看到 相当于把这些库linker到我们上面的libffmpeg.so里面。

成功的话可以看到ffmpeg 目录下的Android中看到这个so库

image.png

可以看到libffmpeg.so已经出来了

编译Lib264库

作用

为什么用这个库呢,如果说你已经以上步骤都成功了,而且已经运行到Android机上面了,你会发现编码出来的视频文件明显质量很差,不应该说很差,反正肯定是自己不满意的结果。说了这么多,大家应该知道这个库的作用了,提高编码质量,为什么我在官网下载的pc库会质量很好呢,那是因为他们已经把这个库编进去了而且已经enable。那么我们这里要做的就是去下载Lib264官方源码,编译出Android平台的 然后把这个库给打进FFmpeg里面。

编译Lib264

这个库编译就比较简单了。参数和代码没有那么多,github上面放的脚本名字叫做(build_x264_andorid.sh)大家下载下来就可以用的

如果想编译不同的版本同样可以通过 后缀shared 或者static 就可以了

最后

我见过很多技术leader在面试的时候,遇到处于迷茫期的大龄程序员,比面试官年龄都大。这些人有一些共同特征:可能工作了5、6年,还是每天重复给业务部门写代码,工作内容的重复性比较高,没有什么技术含量的工作。问到这些人的职业规划时,他们也没有太多想法。

其实30岁到40岁是一个人职业发展的黄金阶段,一定要在业务范围内的扩张,技术广度和深度提升上有自己的计划,才有助于在职业发展上有持续的发展路径,而不至于停滞不前。

不断奔跑,你就知道学习的意义所在!

CodeChina开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》

展路径,而不至于停滞不前。

不断奔跑,你就知道学习的意义所在!

[外链图片转存中…(img-l6uZH9lL-1631093652915)]

CodeChina开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》

[外链图片转存中…(img-Y4rQgjQm-1631093652917)]

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值