手把手图文并茂教你用Android Studio编译FFmpeg库并移植

vrfn8150 7年前
   <p>今天就用 Android Studio编译FFmpeg库并移植,并附上调用ffmpeg简单示例,看下Agenda如下:</p>    <ul>     <li>下载FFmpeg 3.1.3</li>     <li>下载NDK</li>     <li>配置ndk环境</li>     <li>编译FFmpeg</li>     <li>移植到Android平台</li>     <li>调用编译的so示例</li>    </ul>    <h3>下载FFmpeg 3.1.3</h3>    <p>网址: <a href="/misc/goto?guid=4959729972032531444" rel="nofollow,noindex">https://ffmpeg.org/download.html#build-mac</a></p>    <p><br> <img src="https://simg.open-open.com/show/1d2999cc01e21aed5f58227218983c23.png"></p>    <p>双击解压如下,得到一个文件夹:</p>    <p style="text-align:center"><br> <img src="https://simg.open-open.com/show/e9f9621ee3643da23a4978a5d4573314.png"></p>    <p> </p>    <h3>下载NDK</h3>    <ul>     <li>供参考下载地址见本文最下面,也可自行下载。</li>     <li>双击解压如下,同样得到一个文件夹: <p style="text-align:center"><img src="https://simg.open-open.com/show/9854c6de9110884293e14bc78ad2a42e.png"></p> </li>    </ul>    <h3>配置ndk环境</h3>    <ul>     <li>启动终端Terminal</li>     <li>进入当前用户的home目录      <ul>       <li>输入cd ~ 或 /Users/YourUserName</li>      </ul> </li>     <li>创建.bash_profile      <ul>       <li>输入touch .bash_profile</li>      </ul> </li>     <li> <p>编辑.bash_profile文件</p>      <ul>       <li>输入open -e .bash_profile</li>      </ul> <p>因为是为了配置NDK开发环境,输入Android NDK下目录,前面是android sdk的,可以不用动它,最终.bash_profile文件如下:</p> <pre>  <code class="language-java">export PATH=$(PATH):/Users/hejunlin/android-sdks/platform-tools      export NDK_ROOT=/Users/hejunlin/Downloads/android-ndk-r10e                      export PATH=$PATH:$NDK_ROOT</code></pre> </li>    </ul>    <ul>     <li>保存文件,关闭.bash_profile</li>     <li>更新刚配置的环境变量<br> 输入source .bash_profile</li>     <li>看看刚刚设置的环境变量</li>    </ul>    <p>离开了编辑器后,在终端输入 $PATH 并且按enter键来确认是否编辑成功,此时应该会出现所有的环境变量(以:号相分隔)</p>    <p> </p>    <p><br> <img src="https://simg.open-open.com/show/cf567b44cb503201b77829c2661fc4a3.png"></p>    <p>表明配置成功</p>    <p> </p>    <p>接下来·开始进行测试ndk是否能正常编译jni</p>    <p>(1) 终端进入到 NDK下面的 samples 目录下。</p>    <p>(2) 输入 cd hello-jni/ ,回车,然后执行 ndk-build</p>    <p>出现以下界面代表配置成功。</p>    <p style="text-align:center"><br> <img src="https://simg.open-open.com/show/e1ba5ca0dfc7bfd2ca0647767420d49f.png"></p>    <p> </p>    <h3>编译FFmpeg</h3>    <ul>     <li>在编译前,在源码中,修改FFmpeg的configure</li>     <li>下载FFmpeg源代码之后,首先需要对源代码中的configure文件进行修改。由于编译出来的动态库文件名的版本号在.so之后(例如“libavcodec.so.5.100.1”),而android平台不能识别这样文件名,所以需要修改这种文件名。在configure文件中找到下面几行代码(在3209-3212行):</li>    </ul>    <pre>  <code class="language-java">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)'</code></pre>    <p>替换为下面内容:</p>    <pre>  <code class="language-java">SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'    LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'    SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'    SLIB_INSTALL_LINKS='$(SLIBNAME)'</code></pre>    <p>接下来开始写shell脚本</p>    <p>这里有一个坑:我用记事本写了个sh脚本,一直报如下错误:</p>    <p><img src="https://simg.open-open.com/show/b936e717fb8dfb58ac1d666ea3cc7a90.png"></p>    <p>这种情况应该有两种原因:</p>    <p> </p>    <ul>     <li>1.在WIN底下用文本编辑工具修改过参数变量,在保存的时候没注意编码格式造成的,</li>     <li>2.也有可能是在VIM里修改,第一行末尾按到ctrl+v<br> 这里避开这个弯,我找到FFmpeg下一个version.sh的shell脚本,复制了一份<br> 重命名为build_android.sh。脚本如下:</li>    </ul>    <pre>  <code class="language-java">#!/bin/sh  NDK=/Users/hejunlin/Downloads/android-ndk-r10e  SYSROOT=$NDK/platforms/android-21/arch-arm  TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64  function build_one  {  ./configure \  --prefix=$PREFIX \  --enable-shared \  --disable-static \  --disable-doc \  --disable-ffmpeg \  --disable-ffplay \  --disable-ffprobe \  --disable-ffserver \  --disable-avdevice \  --disable-doc \  --disable-symver \  --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  }  CPU=arm  PREFIX=$(pwd)/android/$CPU  ADDI_CFLAGS="-marm"  build_one</code></pre>    <p>如果大家要编译,记得改下前三行,对应自己机器上的环境</p>    <p>接着开始执行这个shell脚本,在终端输入 ./ build_android.sh , 如图:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/b2b61640c653246ce1c0a7242220ded7.png"></p>    <p>开始进行自动编译:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/fda0330cf9b87c68f7f71533910de287.png"></p>    <p>中间过程:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/ef16bf6cb1d6620104a45289a2c819d2.png"></p>    <p>喝杯咖啡时间,就编译好了,结果如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/3a7a44ba4cbb054efd138a63cf3ac130.png"></p>    <p>这时会发现 FFmpeg下多了一个文件夹android:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/b6ae16e78555c5d20f4ae2db3f400329.png"></p>    <p>打开如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/a320bee3574d00b070d2412009049173.png"></p>    <p>这样我们要的so就有了,当然,这只是基本的。</p>    <p>本文出自逆流的鱼yuiop: <a href="/misc/goto?guid=4959729972119250466" rel="nofollow,noindex">http://blog.csdn.net/hejjunlin/article/details/52661331</a></p>    <h3>移植到Android平台</h3>    <p>接下来写在Android studio写一个示例,调用ffmpeg中方法</p>    <p>建一个工程:在src/main下建一个jni目录</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/d089bd9af809a05e32de7b70be5862e9.png"></p>    <p>把前面编译好的android目录移植过来</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/bce296142af985e01285a61cc7cf3ff6.png"></p>    <p>simplest_ffmpeg_helloworld.c代码如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/6382b2cca71b75e073c30b1625381f3f.png"></p>    <p>Android.mk文件内容如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/2823dc61b920683f17c9d10f3a41eee3.png"></p>    <p>本文出自逆流的鱼yuiop: <a href="/misc/goto?guid=4959729972119250466" rel="nofollow,noindex">http://blog.csdn.net/hejjunlin/article/details/52661331</a></p>    <p>开始编译目标so,在Studio中的Terminal面板中:执行ndk-build</p>    <p>(在此之前记得要在local.properties下配置ndk目录)</p>    <p><img src="https://simg.open-open.com/show/51ffa5a5c3803c82093e9510c7c8ea24.png"></p>    <p>会在libs下面生成一些so,也可以看到我们目标so:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/7e4eca0e5056fdc153ec8f5d50077a51.png"></p>    <p>然后建立一个jniLibs文件夹,把这些so拷贝进去</p>    <p>调用编译的so示例</p>    <p>接着写MainActivity代码,如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/21bb492c8cbd5fbca278539c163d9c48.png"></p>    <p>最终效果如图:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/67159d08fda82cee1e5abdd60c810f56.gif"></p>    <p> </p>    <p>来自:http://www.androidchina.net/5772.html</p>    <p> </p>