前言
公司项目,iOS端说Android端拍的视频,码率不对,他无法播放。图片和视频的选择或拍摄一直用的PictureSelector,问了开源作者才知道录制的没做任何处理,直接调用的系统拍摄,只提供了设置拍摄的质量为0还是1的方法,无奈,只能想着自己压缩了。说到视频的处理,现在最火的肯定还是FFmpeg。FFmpeg的移植,不难,就是太坑了。既然移植比较麻烦,我想着能不能将FFpemg移植后封装成一个lib,以后其他项目使用直接引用,不需要再移植了,经过三天的各种折腾和测试,终于成功了。。。。
正文
源码下载
首先把ffmpeg-3.2.4的源码下载下来,源码最好就下载我这个,我最开始用的官网的最新版本,build的时候老是报错,最后换成3.2.4,就不再报错了!ffmpeg-3.2.4地址:
http://download.csdn.net/download/moushao/10139387
下载下来后解压放到纯英文路径下,然后将源码路径添加到环境变量中
编译FFmpeg生成.so文件
- 在main目录下新建jni文件夹
![9f86c2acbd9535811317760c8b90a8f4.png](https://i-blog.csdnimg.cn/blog_migrate/000e62863e883e339efcd9a37b47e2ca.jpeg)
- 直接点击finish自动生成
copy FFmpeg的源码和.mk文件到jni
将Demo中jni里的这些文件拷贝到你model中的jni,图中红色选中的三个不要复制,这个是根据项目生成的(如果你直接引用这个model,就不用管)。
![dbc71107ddbd00bff5a29ee7b610279f.png](https://i-blog.csdnimg.cn/blog_migrate/e8a495931716db7ca6596908d6238a8c.jpeg)
- 如图将FFmpegKit的代码copy到java工程中
![4a4dff6c306f3f51c796337c490e3171.png](https://i-blog.csdnimg.cn/blog_migrate/bc05fcedcce1aac59f7231687d30e25d.jpeg)
- 编译FFmpegKit
控制台中切到java文件夹目录下,输入javah com.ffmpegtest.xxx.utils.FFmpegKit (FFmpegKit的引用路径),只有在java目录下执行这行命令才能成功,直接进到Utils目录执行会报找不到.so文件,编译成功后会生成图中黑框中的两个c++文件,剪贴这两个文件到jni文件夹中
![509f1e289c9ed0d636b0bcc94cfe6218.png](https://i-blog.csdnimg.cn/blog_migrate/67691a0cad3c4572543cb13d4ea42e55.jpeg)
- 创建com_ffmpegtest_www_utils_FFmpegKit.c文件
![c3ab05d162a53877bbc0723b22fa6ee8.png](https://i-blog.csdnimg.cn/blog_migrate/447b24c1cf43058b55b8e50fcb64f035.jpeg)
你或许会注意到新建的文件和生成的哪个.h文件名称一致,只是格式不同。对,没错,必须一致,这是按照项目包名生成的,不能随便更改!
- 修改Android.mk和Application.mk
更改Android.mk中LOCAL_SRC_FILES值和FFmpeg源码路径
![1e713791667ecb22102711bca0064a3d.png](https://i-blog.csdnimg.cn/blog_migrate/dfc9d51d04d70416a6d66ec06503b552.jpeg)
Application.mk中,设置生成so库,这里我们只设置生成armeabi-v7a下的(其他库空格添加生成,考虑到生成的so文件都是10M+,就没设置其他的)
![6a397dade4b5030baadb7e728b64429a.png](https://i-blog.csdnimg.cn/blog_migrate/62597e1918f72a854fccff374ec868c3.jpeg)
- 其他配置
在app下的gradle中设置so库支持和路径读取:
![234d0c1af6ac701c720a3e9607841859.png](https://i-blog.csdnimg.cn/blog_migrate/bc5c85fa747f8b8e942a87f047f379ea.jpeg)
Manifest中添加版本设置(别忘了添加读写和摄像头权限)
![be8c110e6f8306182891e2b67f0c248e.png](https://i-blog.csdnimg.cn/blog_migrate/4c92797b5ace223786a2e72a77b33370.jpeg)
gradle.properties中添加 android.useDeprecatedNdk=true,不添加可能会爆xxx.so" is 32-bit instead of 64-bit的错误
![e2ce86aed659e2035d8119a460ae1cee.png](https://i-blog.csdnimg.cn/blog_migrate/b6e2ab2e12a25c8bd30c9834ca9a62ae.jpeg)
编译FFmpeg生成.so文件
以上配置完成后,就可以编译了,控制台中切换到jni目录下,执行ndk-build命令(需要配置ndk),执行完成后,会自动生成libs和obj两个文件夹,这就是我们需要的.so文件了。
![fe15ecd3c8d36785ac4b3fdc612f3d38.png](https://i-blog.csdnimg.cn/blog_migrate/d4c7abc49ae72d82cc12d7415de023cc.jpeg)
这里插一句:如果编译的时候报各种警告,生成的.so是不行的,把我们上面的新建的哪个com_ffmpegtest_www_utils_FFmpegKit.c文件,随便乱删除点东西保存后执行ndk-build,然后再恢复正确,再执行ndk-build,不要问我为什么,姑且理解为编译器不识好歹!
结语
到此为止,FFmpeg的移植就完成了,至于怎么压缩怎么添加水印,那是FFmpeg命令行的具体应用了,大家结合着Demo和FFmpeg文档自求多福吧。Demo中的ffmpeglib已经封装好,大家可以在项目中直接import model使用(亲测没问题),避免了每次都要编译,而且独立的mk和gradle配置,免去了和其他第三方库的冲突。
十分感谢reverse_Android对此次集成的帮助和解答。
参考文章如下
最简单的基于FFmpeg的移动端例子:Android HelloWorld
http://blog.csdn.net/leixiaohua1020/article/details/47008825/
FFmpeg-Android拍摄压缩Demo(敲黑板)
https://www.jianshu.com/p/fd748001ca53
仿微信视频拍摄UI, 基于ffmpeg的视频录制编辑(上)(api>22的情况下无法找不到so文件,慎用)
https://www.jianshu.com/p/5a173841a828
项目github地址:
https://github.com/moushao/FFmpeg4Android
如果有什么问题欢迎留言哈,谢谢!