根据最新版本替换下面的${latestVersion}
,当前最新版本
implementation 'com.coder.command:ffmpeg:${latestVersion}'
如果对apk大小有严格的要求,可以使用mini
版本
implementation 'com.coder.command:ffmpeg-mini:${latestVersion}'
一般我们使用CPU_ABI时只需要armeabi-v7a
和arm64-v8a
就行了,所以只需要在app的bulid.gradle下加入如下代码:
android {
...
defaultConfig {
...
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a'
moduleName "app"
}
}
}
可以在Application或者使用之前设置Debug模式
FFmpegCommand.setDebug(true);
使用之后将会打印类似如下信息,正式上线建议关闭
2020-04-14 11:24:34.316 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: Input #0, mp3, from '/storage/emulated/0/Android/data/com.coder.ffmpegtest/cache/test.mp3':
2020-04-14 11:24:34.316 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: Metadata:
2020-04-14 11:24:34.316 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: track :
2020-04-14 11:24:34.316 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: 4
2020-04-14 11:24:34.316 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: album :
2020-04-14 11:24:34.316 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: 老妖的奇异之旅
2020-04-14 11:24:34.316 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: artist :
2020-04-14 11:24:34.316 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: 音频怪物
2020-04-14 11:24:34.316 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: title :
2020-04-14 11:24:34.316 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: 琴师
2020-04-14 11:24:34.316 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: comment :
2020-04-14 11:24:34.317 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: 163 key(Don't modify):L64FU3W4YxX3ZFTmbZ+8/XaHu4ttkjqeshXxH3KzUJIjW7TiQPO7yhdBvVocH3+T10bijFQrb4/8IlKOGmuqVuqY66JjiWF+FKWZIAtFkegR9A1hA0/PQDlrk3QgW2ecLZDxWBvu4ei9113YaekyVuHRKrPI+2wF4Bvt6VS8oTFrOPTNN2kZa8OZq0PUedCDDqfXUU1SGPu6yJt7rwpEOSCMI2WbS1OrwXRuyJQ43
2020-04-14 11:24:34.317 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: encoder :
2020-04-14 11:24:34.317 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: Lavf58.20.100
2020-04-14 11:24:34.317 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: Duration:
2020-04-14 11:24:34.317 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: 00:00:39.99
2020-04-14 11:24:34.317 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: , start:
2020-04-14 11:24:34.317 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: 0.011995
2020-04-14 11:24:34.317 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: , bitrate:
2020-04-14 11:24:34.317 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: 320 kb/s
2020-04-14 11:24:34.317 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: Stream #0:0
2020-04-14 11:24:34.317 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: , 50, 1/14112000
2020-04-14 11:24:34.317 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: : Audio: mp3, 44100 Hz, stereo, fltp, 320 kb/s
2020-04-14 11:24:34.317 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: Metadata:
2020-04-14 11:24:34.317 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: encoder :
2020-04-14 11:24:34.317 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: Lavc57.89
2020-04-14 11:24:34.317 15221-15304/com.coder.ffmpegtest D/ffmpeg-cmd: Successfully opened the file.
方法 | 功能 |
---|---|
FFmpegCommand->setDebug(debug: Boolean) | Dubug模式,可打印日志,默认true |
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() | 退出FFmpeg命令执行 |
以runCmd
调用FFmpeg
为同步执行FFmpeg命令,外部需增加线程,否则会造成应用无响应。
直接调用FFmpegCommand.runCmd(cmd: Array<String?> callBack: IFFmpegCallBack?)
方法,其中第一个参数由FFmpegUtils
工具类提供,也可以自己添加
不支持异步执行FFmpeg命令,毕竟C是面向过程语言,会出现资源占用问题
GlobalScope.launch {
FFmpegCommand.runCmd(FFmpegUtils.transformAudio(audioPath, targetPath), callback("音频转码完成", targetPath))
}
第二个参数是回调方法
open class CommonCallBack : IFFmpegCallBack {
// 开始回调
override fun onStart() {}
// 进度回调
override fun onProgress(progress: Int, pts: Long) {}
// 取消回调
override fun onCancel() {}
// 完成回调
override fun onComplete() {}
// 错误回调
override fun onError(errorCode: Int, errorMsg: String?) {}
}
需要注意的是在onProgress
方法中,可以看到回调回了2个值:
i
之后的输入文件)计算得出,多个输入文件时可能出现不正确的情况var duration :Int? = FFmpegCommand.getMediaInfo(mAudioPath,MediaAttribute.DURATION)
var progress = pts/duration!!
这里只是演示了音频剪切,很多如上述功能请自行查阅FFmpegUtils 如果其中不满足需求,可添加自己的FFmpeg命令.例如:
var command = "ffmpeg -y -i %s -vn -acodec copy -ss %d -t %d %s"
command = String.format(command, srcFile, startTime, duration, targetFile)
GlobalScope.launch {
FFmpegCommand.runCmd(command.split(" ").toTypedArray(), callback("音频剪切完成", targetPath))
}
由于底层暂时无法实现多线程(毕竟C是面向过程的语言),所以如果需要在推流的同时,是无法再同时执行其他命令。 为了解决这个问题,可以使用如下多进程方法:
<service android:name=".service.FFmpegCommandService" android:process=":ffmpegCommand" />
<service android:name=".service.FFmpegCommandService2" android:process=":ffmpegCommand2" />
class FFmpegCommandService : Service() {
override fun onBind(intent: Intent): IBinder? {
return null
}
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
val videoPath = File(externalCacheDir, "test.mp4").absolutePath
val output = File(externalCacheDir, "output.yuv").absolutePath
val cmd = "ffmpeg -y -i %s -an -c:v rawvideo -pixel_format yuv420p %s"
val result = String.format(Locale.CHINA, cmd, videoPath, output)
val strings: Array<String?> = result.split(" ").toTypedArray()
FFmpegCommand.runCmd(strings)
return super.onStartCommand(intent, flags, startId)
}
}
执行下面方法后将会回调 CommonCallBack->onCancel()
方法
FFmpegCommand.cancel();
FFmpegCommand.getMediaInfo(path: String?, @MediaAttribute type: Int)
提供了获取媒体文件大小,视频宽高,比特率,音频采样率等属性值方法
val AV_TIME_BASE = 1000000;
val duration = FFmpegCommand.getInfoSync(mVideoPath, Attribute.DURATION)
var secs = duration / AV_TIME_BASE
al us = duration % AV_TIME_BASE
var mins = secs / 60
secs %= 60
val hours = mins / 60
mins %= 60
val result = String.format("%02d:%02d:%02d.%02d", hours, mins, secs, (100 * us) / AV_TIME_BASE)
tvContent?.text = result
【KFFmpegCommandActivity-命令使用参考】 【KFFmpegInfoActivity-媒体信息参考】 【KFFmppegFormatActivity-支持封装格式】 【KFFmpegCodecActivity-支持编解码】
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。