FFMPEG-AAC-264-Android-32-64

Introduction: android 视频压缩,使用 ffmpeg 方案,集成 fdk-aac 与 264 编码,适用于 32 位系统与 64 位系统,支持 ARM 32/64 cpu 与 x86 32/64 cpu,mips 32/64 cpu,即支持 android7.0 系统
More: Author   ReportBugs   
Tags:
Installe-

疯狂的程序员群: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 选项来启动调试。

Apps
About Me
GitHub: Trinea
Facebook: Dev Tools