FFmpegCommand
FFmpegCommand适用于Android的FFmpeg命令库,实现了对音视频相关的处理,能够快速的处理音视频,大概功能包括:音视频剪切,音视频转码,音视频解码原始数据,音视频编码,视频转图片或gif,视频添加水印,多画面拼接,音频混音,视频亮度和对比度,音频淡入和淡出效果等
Install / Use
/learn @AnJoiner/FFmpegCommandREADME

前景提要
在我们的开发中,经常会用到音视频相关内容,一般我们都会选择FFmpeg
,但是其交叉编译对于我们来说是一件很麻烦的事情.所以这里方便日后使用就编写了这个FFmpegCommand,FFmpegCommand
是由FFmpeg核心库,并且集成了lame、libx264、fdk-aac和libopencore-amr主流音视频处理程序构成的Android程序
注意:当前库只适用于Android
如果访问不了全部信息,请跳转【国内镜像】
交叉编译
- Macos 13.2 & Clang++ & Cmake & NDK 21 (支持MediaCodec 编解码)
| 第三方库 | 版本 | 下载地址 | 添加版本 | 说明 | | ------------ | ------------------ | ------------------------------------------------------------ | -------- | ------------------------------------- | | ffmpeg | 6.0 | https://ffmpeg.org/releases/ffmpeg-6.0.tar.xz | 1.0.0 | ffmpeg 音视频库 | | x264 | X264-20191217.2245 | http://download.videolan.org/pub/videolan/x264/snapshots/x264-snapshot-20191217-2245-stable.tar.bz2 | 1.0.0 | libx264视频编码 | | mp3lame | 3.100 | https://sourceforge.net/projects/lame/files/latest/download | 1.0.0 | mp3lame音频编码 | | fdkaac | 2.0.1-ff69b4 | https://downloads.sourceforge.net/opencore-amr/fdk-aac-2.0.1.tar.gz | 1.0.0 | fdk-aac音频编码 | | opencore-amr | 1.1.5 | https://sourceforge.net/projects/opencore-amr/files/opencore-amr/opencore-amr-0.1.5.tar.gz | 1.0.0 | amr音频编解码 | | fribidi | 1.0.10 | https://github.com/fribidi/fribidi/releases/download/v1.0.10/fribidi-1.0.10.tar.xz | 1.3.2 | 双向文本处理,drawtext filter依赖 | | freetype | 2.10.2 | https://mirror.yongbok.net/nongnu/freetype/freetype-2.10.2.tar.gz | 1.3.2 | 支持多种字体格式,drawtext filter依赖 | | fontconfig | 2.13.92 | https://www.freedesktop.org/software/fontconfig/release/fontconfig-2.13.92.tar.gz | 1.3.2 | 字体配置和渲染,drawtext filter依赖 | | ass | 0.14.0 | https://github.com/libass/libass/releases/download/0.14.0/libass-0.14.0.tar.gz | 1.3.2 | 字幕渲染库,可向视频添加字幕 |
主要功能
| 特色功能 | 支持 | 描述 |
| ------------------------------------------------------------ | ------------------ | ------------------------------------------------- |
| ffmpeg命令 | :white_check_mark: | 支持所有的ffmpeg命令 |
| 进度回调 | :white_check_mark: | 支持所有命令的回调 |
| 命令取消 | :white_check_mark: | 支持在命令执行过程中取消命令执行 |
| debug模式 | :white_check_mark: | 支持开启/关闭调试模式 |
| 获取媒体信息 | :white_check_mark: | 获取媒体信息(宽、高...) |
| 绘制文本 (drawtext) | :white_check_mark: | 向视频绘制文本(文字水印 - v1.3.2) |
| 添加字幕 (subtitles) | :white_check_mark: | 向视频添加字幕(支持srt、ass格式 - v1.3.2) |
| MediaCodec编解码 | :white_check_mark: | 支持MediaCodec(v1.3.0) |
| 平台架构 | :white_check_mark: | 支持 armeabi-v7a, arm64-v8a |
| 独立so | :white_check_mark: | 将多个so合并成一个 ffmpeg-org.so |
| 16 kb 对齐 | :white_check_mark: | 支持 16 KB 的页面大小,对齐所有 so 文件(v1.3.3) |
检查是否支持16KB
可以通过项目根目录下的check_elf_alignment.sh进行验证
chmod +x check_elf_alignment.sh
./check_elf_alignment.sh /xxx/app-release.apk
输入内容如下
=== ELF alignment ===
/var/folders/zc/rsfnw8x54tdbdtyk7r3_25hw0000gn/T/app-release_out_XXXXX.K0nw9ZGcco/lib/armeabi-v7a/libffmpeg-command.so: \e[32m ALIGNED \e[0m (2**14)
/var/folders/zc/rsfnw8x54tdbdtyk7r3_25hw0000gn/T/app-release_out_XXXXX.K0nw9ZGcco/lib/armeabi-v7a/libBugly_Native.so: \e[31m UNALIGNED \e[0m (2**12)
/var/folders/zc/rsfnw8x54tdbdtyk7r3_25hw0000gn/T/app-release_out_XXXXX.K0nw9ZGcco/lib/armeabi-v7a/libffmpeg-org.so: \e[32m ALIGNED \e[0m (2**14)
/var/folders/zc/rsfnw8x54tdbdtyk7r3_25hw0000gn/T/app-release_out_XXXXX.K0nw9ZGcco/lib/arm64-v8a/libffmpeg-command.so: \e[32m ALIGNED \e[0m (2**14)
/var/folders/zc/rsfnw8x54tdbdtyk7r3_25hw0000gn/T/app-release_out_XXXXX.K0nw9ZGcco/lib/arm64-v8a/libBugly_Native.so: \e[32m ALIGNED \e[0m (2**16)
/var/folders/zc/rsfnw8x54tdbdtyk7r3_25hw0000gn/T/app-release_out_XXXXX.K0nw9ZGcco/lib/arm64-v8a/libffmpeg-org.so: \e[32m ALIGNED \e[0m (2**14)
\e[31mFound 1 unaligned libs (only arm64-v8a/x86_64 libs need to be aligned).\e[0m
=====================
如果标记出ALIGNED 就表示成功对齐 16KB,如果标记出UNALIGNED就表示未对齐,需要进行对齐处理,可以参考支持 16 KB 的页面大小。
如上除了引入的第三方 bugly 未对齐,其他都是对齐了的。
功能
- 支持视频格式转换 mp4->flv
- 支持音频编解码 mp3->pcm pcm->mp3 pcm->aac
- 支持音频转码 mp3->aac mp3->amr
- 支持视频编解码 mp4->yuv yuv->h264
- 支持视频转码 mp4->flv mp4->avi
- 支持音视频的剪切、拼接
- 支持视频转图片 mp4->png mp4->gif
- 支持音频声音大小控制以及混音(比如朗读的声音加上背景音乐)
- 支持部分滤镜 音频淡入、淡出效果、视频亮度和对比度以及添加水印
- 支持获取媒体文件信息
- 支持 ffmpeg 大多数命令(不包含未引入的第三方)
| 执行FFmpeg | 获取媒体信息 | |----------------------------------------------------------|---------------------------------------------------------| | <img src="images/1.gif" alt="图-1:命令行展示" width="260px" /> | <img src="images/2.gif" alt="图-2:命令行执行" width="260px"/> |
引入
在项目根目录下找到build.gradle,并添加如下
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
然后在app或者其他module下的build.gradle添加引入
下面两种引入只选择一种即可,并根据最新版本替换下面的${latestVersion}
,当前最新版本
// 全部编解码-体积较大
implementation 'com.github.AnJoiner.FFmpegCommand:ffmpeg:${latestVersion}'
// 部分常用编解码-体积较小,比上面引入减少大约6M
implementation 'com.github.AnJoiner.FFmpegCommand:ffmpeg-lite:${latestVersion}'
更改module下build.gradle,当前库只支持armeabi-v7a和arm64-v8a
,当然也可以只使用一种(一般使用armeabi-v7a
可以向下兼容),可以参考【Android ABI】
android {
defaultConfig {
ndk {
abiFilters "armeabi-v7a", 'arm64-v8a'
moduleName "app"
}
}
}
如果没有特别的编解码需求,强烈推荐建议使用lite版本
使用
下面只展示部分使用,其他可以参考 【WIKI】
FFmpegCommand方法
| 方法 | 功能 | | ------------------------------------------------------------ | --------------------------------------------------- | | FFmpegConfig->setDebug(debug: Boolean) | Dubug模式,可打印日志调试 | | FFmpegCommand->runCmd(cmd: Array<String?>) | 执行ffmpeg命令,无回调 | | FFmpegCommand->runCmd(cmd: Array<String?> callBack: IFFmpegCallBack?) | 执行ffmpeg命令,并回调 开始,完成,取消,进度,错误 | | FFmpegCommand->getMediaInfo(path: String?, @MediaAttribute type: Int) | 获取媒体信息:视频宽高、比特率... | | FFmpegCommand->getSupportFormat(@FormatAttribute formatType: Int) | 获取当前库支持的封装、解封装格式 | | FFmpegCommand->getSupportCodec(@CodecAttribute codecType: Int) | 获取当前库支持的编解码 | | FFmpegCommand->cancel(taskId) | 取消某个正在执行的任务 - v1.3.3 | | FFmpegCommand->cancelAll() | 取消全部任务 - v1.3.3 | | FFmpegCommand->getRunningCount() | 获取正在执行的任务数量 - v1.3.3 |
runCmd
以runCmd调用FFmpeg为执行FFmpeg命令,多次调用会按顺序依次执行,如需同时执行 2 个命令请使用多进程FFmpegCommandService2。
直接调用FFmpegCommand.runCmd(cmd: Array<String?> callBack: IFFmpegCallBack?)
方法,其中第一个参数由FFmpegUtils工具类提供,也可以自己自定义。
val taskId = FFmpegCommand.runCmd(
FFmpegUtils.transformAudio(audioPath, targetPath),
callback("音频转码完成", targetPath)
)
// 取消某个任务
FFmpegCommand.cancel(taskId)
第二个参数是回调方法
open class CommonCallBack : IFFmpegCallBack {
// 开始回调
override fun onStart() {}
// 进度回调
override fun onProgress(progress: Int, pts: Long) {}
// 取消回调
override fun onCancel() {}
// 完成回调
override fun onComplete() {}
// 错误回调
override fun onError(err
