Android 音视频采集与软编码总结


请尊重原创,转载请注明出处:http://blog.csdn.net/mabeijianxi/article/details/75807435(本文已在 “任玉刚” 微信公众号发布)


前言


本文总结了笔者在 Android 音视频采集与软编码中的一些经验与技巧,包括移植 FFmpegYUV 视频帧处理、最新的 JNI 编写技巧、 ndk 开发技巧等,为了不扯太远本文不会对音视频编码的一些原理性东西进行剖析,也不会大量贴源码,更注重使用方法与流程的讲解。 文章最后将展示一个实现了音视频采集功能与本地视频压缩功能的完整项目。

采用软编码利弊


众所周知, Android API 中有个 MediaCodec 的类,利用 MediaCodec 可实现硬编码,高效且方便,Android API 中还有个叫 MediaMuxer 的类,可以实现音频与视频的合成,但是 MediaCodec 使用的 API 最低要求是 16,MediaMuxer 则是 18,除此之外如果对视频想做更多的处理还需要做比较多的开发,当然这点纯粹是偷懒。如果使用软编码,那么 API 限制将不再那么苛刻,笔者开发时调到了 14,然后由于我用的是 FFmpeg 且移植了它的命令行工具,那么对视频很多的处理操作可以使用简单命令即可完成。视频编码我为 FFmpeg 配置的是 x264 ,其可编码为 H.264 视频格式,除此之外比较出名的还有下一代编码标准 HEVCVP9。音频我为 FFmpeg 配置的是 libfdk-aac ,其 libfaac 在新版 FFmpeg 中已经被抛弃了。x264 现在在算法上基本达到了瓶颈,而软编效率很大程度上依赖算法与 cpu ,所以 cpu 就成了决定效率的关键,经过我实验,虽然其跟硬编码效率还是有差距,但是它在普通 64 位的 cpu 上表现还是不错的,处理 480P、帧率 30 、比特率 1000000 的视频帧基本没有延迟。

本地依赖库的准备


需要准备的依赖库有 FFmpeglibx264libfdk-aac 等,它们都是不能直接在 Android 上使用的,需要修改些东西并且需要用 NDK 编译成动态链接库或者静态链接库,修改的东西其实主要是一些命名上的东西,很多平台识别的格式不太一样,如 Android 上不能识别 ffmpeg.so.01 这样的库,对于 FFmpeg 的编译网上有非常多的脚本,但是如果你需求不是和他一模一样,建议还是自己定制下,其实定制无非是对一些功能的开开关关而已,其他平台可能无所谓,大不了功能全开呗,但是对于 Android 来说,编译个全功能的 FFmpeg 可不是什么好事,apk 将会随之变大很多,这是不能接受的。这里有一个项目里面包含了 FFmpeglibx264libfdk-aac 全平台的编译脚本与 Android 下使用的简单 Demo,https://github.com/mabeijianxi/FFmpeg4Android ,你只需要简单修改脚本即可定制自己的 FFmpeg 了。

CMake 脚本编写


如果你 Android Studio 版本大于 2.2 ,且在新建项目时如果勾选上了 Incude C++ Support ,那么 AS 将会默认使用 CMake 插件,我们一般情况下只需要对 CMakeLists.txt进行编写即可完成 Native 编译。下面展示一段 CMakeLists.txt编写的实用列子:

cmake_minimum_required(VERSION 3.4.1)

add_library( # Sets the name of the library.
             jxffmpegrun

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
              src/main/cpp/cmdutils.c
              src/main/cpp/ffmpeg.c
              src/main/cpp/ffmpeg_filter.c
              src/main/cpp/ffmpeg_opt.c
              src/main/cpp/jx_ffmpeg_cmd_run.c
             )
add_library(
            avcodec
            SHARED
            IMPORTED
            )

if(${ANDROID_ABI} STREQUAL "armeabi")
set_target_properties(
    avcodec
    PROPERTIES IMPORTED_LOCATION
    ${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi/libavcodec.so
    )
endif(${ANDROID_ABI} STREQUAL "armeabi")

if(${ANDROID_ABI} STREQUAL "armeabi-v7a")
set_target_properties(
    avcodec
    PROPERTIES IMPORTED_LOCATION
    ${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi-v7a/libavcodec.so
    )
endif(${ANDROID_ABI} STREQUAL "armeabi-v7a")

if(${ANDROID_ABI} STREQUAL "arm64-v8a")
set_target_properties(
    avcodec
    PROPERTIES IMPORTED_LOCATION
    ${CMAKE_SOURCE_DIR}/src/main/jniLibs/arm64-v8a/libavcodec.so
    )
endif(${ANDROID_ABI} STREQUAL "arm64-v8a")

include_directories(
    ${CMAKE_SOURCE_DIR}/ffmpeg-3.2.5

)

find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )

target_link_libraries( # Specifies the target library.
                       jxffmpegrun
                       avcodec
                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

简单分析下上面的脚本:

  • cmake_minimum_required 命令的作用是指定 CMake 使用的最小版本。
  • add_library 命令的作用是添加一个库,首先指定的是库名,如 jxffmpegrun,根据规范最后会生成 
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值