FFMPEG-AAC-264-Android-32-64
疯狂的程序员群:186305789
个人兴趣网站,zero 接码平台
个人兴趣网站,猿指
FFMPEG-AAC-264-Android-32-64
android 视频压缩,使用 ffmpeg 方案,集成 fdk-aac 与 264 编码,适用于 32 位系统与 64 位系统,ARM cpu 与 x86 cpu,mips 理论都可以,不过占有量太小,被我忽略了 本 SDK 主要用于视频压缩,视频录制功能存在异常请不要使用
fdk-aac
acc 源码,编译方式已经整理为 sh 文件,见 build_ARM.sh ...
x264
x264 源码,编译方式已经整理为 sh 文件
ffmpeg-3.2.5
ffmpeg-3.2.5 源码,编译完 aac 与 x264 之后将结果 copy 到 mylib 文件夹下,然后执行 ffmpeg 的 sh 文件进行编译
SmallVideoRecord
SmallVideoRecord Android 工程,包含 lib 工程与 example 工程,lib 给 ffmpeg 做了封装,实现了 ffmepg 拍摄与视频压缩。
使用详解
在 manifests 里面添加(只做压缩不需要任何界面,可以不导入)
<activity
android:name="com.zero.smallvideorecord.VideoPlayerActivity"
android:theme="@style/AppNoBarTheme"/>
<activity
android:name="com.zero.smallvideorecord.MediaRecorderActivity"
android:theme="@style/AppNoBarTheme"/>
<activity
android:name="com.zero.smallvideorecord.SendSmallVideoActivity"
android:theme="@style/AppNoBarTheme"/>
在 Application 里面初始化压缩之后的视频存放位置
public static void initSmallVideo(Context context) {
// 设置拍摄视频缓存路径
File dcim = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
if (DeviceUtils.isZte()) {
if (dcim.exists()) {
JianXiCamera.setVideoCachePath(dcim + "/mabeijianxi/");
} else {
JianXiCamera.setVideoCachePath(dcim.getPath().replace("/sdcard/",
"/sdcard-ext/")
+ "/zero/");
}
} else {
JianXiCamera.setVideoCachePath(dcim + "/zero/");
}
// 开启 log 输出,ffmpeg 输出到 logcat
//JianXiCamera.setDebugMode(true);
// 初始化拍摄 SDK,必须
JianXiCamera.initialize(false,null);
}
跳转录制界面或选择压缩
// 录制
MediaRecorderConfig config = new MediaRecorderConfig.Buidler()
.doH264Compress(new AutoVBRMode()
// .setVelocity(BaseMediaBitrateConfig.Velocity.ULTRAFAST)
)
.setMediaBitrateConfig(new AutoVBRMode()
// .setVelocity(BaseMediaBitrateConfig.Velocity.ULTRAFAST)
)
.smallVideoWidth(480)
.smallVideoHeight(360)
.recordTimeMax(6 * 1000)
.maxFrameRate(20)
.captureThumbnailsTime(1)
.recordTimeMin((int) (1.5 * 1000))
.build();
MediaRecorderActivity.goSmallVideoRecorder(this, SendSmallVideoActivity.class.getName(), config);
// 选择本地视频压缩
LocalMediaConfig.Buidler buidler = new LocalMediaConfig.Buidler();
final LocalMediaConfig config = buidler
.setVideoPath(path)
.captureThumbnailsTime(1)
.doH264Compress(new AutoVBRMode())
.setFramerate(15)
.build();
OnlyCompressOverBean onlyCompressOverBean = new LocalMediaCompress(config).startCompress();
一些参数说明
maxFrameRate:指定最大帧率,越大视频质量越好,体积也会越大,当在 cbr 模式下不再是动态帧率,而是固定帧率;
captureThumbnailsTime:指定剪切哪个时间的画面来作为封面图;
doH264Compress:不传入值将不做进一步压缩,暂时可以传入三种模式 AutoVBRMode、VBRMode、VBRMode;
setMediaBitrateConfig:视频录制时期的一些配置,暂时可以传入三种模式 AutoVBRMode、VBRMode、VBRMode;
AutoVBRMode:可以传入一个视频等级与转码速度,等级为 0-51,越大质量越差,建议 18~28 之间即可。转码速度有 ultrafast、superfast、 veryfast、faster、fast、medium、slow、slower、veryslow、placebo。
VBRMode:此模式下可以传入一个最大码率与一个额定码率,当然同样可以设置转码速度。
VBRMode:可以传入一个固定码率,也可以添加一个转码速度。
关于项目文件很大的问题
首先项目看着很大,其实编译之后差不多 11M 左右,建议 lib 导出成 aar 然后导入到自己项目, 其次可根据自己需求重新执行 sh 文件,configure 提供 disable 与 enable 各种功能的方法,disable 之后就不会打包到 so 库中,从而减小 so 大小
交叉编译的时候遇到一些坑,分享出来,希望对其他人有所帮助。
(1) 编译 ffmpeg 时提示找不到 libfdk-aac 扩这 libx264。这个问题是由于 ffmpeg 的交叉编译器找不到 libfdk-aac/x264 的头文件或者是静态库导致的,解决这个问题只要将 ffmpeg、libfdk-aac、libx264 的–prefix 选项指向相同的目录,并且在调用 ffmpeg 的 configure 脚本时指定–extra-cflags=“-I${PREFIX}/include”和–extra-ldflags=“-L${PREFIX}/lib -lx264 -lfdk-aac”即可,另外请主要 configure 的 libfdk-aac 支持选项有时候是 libfdk-aac(小短线),有时候又是 libfdk_aac(下划线)。如果还没解决问题,就查 configure 生成的日志文件 config.log;
(2) 编译了 32 位 so 文件后再编译 64 位 so 文件时,提示 strtod.o 的文件格式不对。这是由于对于 3.2 版本的 ffmpeg,make clean 不会删除 compat 下的 strtod.o,strtod.d, msvcrt/snprintf.o, msvcrt/snprintf.d 四个文件,只要手动删除后重新编译即可。具体可以参考简书上 esonyf 的这篇文章:http://www.jianshu.com/p/612ef67e42bd
(3) 找不到 AAC 或者 H264 编解码器(调用 avodec_find_decoder|encoder(AVCODEC_ID_AAC|AVCODEC_ID_H264)返回失败)。造成这个问题的原因是为了减小生成库的大小,我在 congiure 时启用了–disable-encoders 和–disable-decoders 选项,这种情况下除了要使用–enable-libx264 和–enable-libfdk-aac,还应该使用–enable-encoder=libx264|libfdk_aac 选项显示启用 libfdk-aac 和 libx264 作为编解码器。
(4) configure 时候提示找不到可工作的 C Compiler。configure 脚本的这个提示具有一定误导性,让我以为是交叉编译器 gcc 的路径配错了,通过分析 config.log 才发现 extra-cflags、extra-ldflags 里面有当前 CPU 架构不支持的选项时都会导致交叉编译器测试失败,然后返回这个错误。解决这个问题主要是通过分析 config.log 脚本来解决。由于 x264 的 configure 脚本不把这个错误信息放在 config.log 里面,只能通过在其 configure 脚本开头添加 set -x 选项来启动调试。
