Skip to content
AnJoiner Lo edited this page Apr 14, 2020 · 3 revisions

引入

根据最新版本替换下面的${latestVersion},当前最新版本 Download

implementation 'com.coder.command:ffmpeg:${latestVersion}'

配置

一般我们使用APP_ABI时只需要armeabi-v7aarm64-v8a就行了,所以只需要在app的bulid.gradle下加入如下代码:

android {
    ...
    defaultConfig {
        ...
        ndk {
            abiFilters 'armeabi-v7a', 'arm64-v8a'
            moduleName "app"
        }
    }
}

Debug模式

可以在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方法

FFmpegCommand->runSync(final String[] cmd)  // 同步执行ffmpeg命令,外部需添加延时线程      
FFmpegCommand->runSync(final String[] cmd, FFmpegCmd.OnFFmpegProgressListener listener)//同步执行ffmpeg命令,并返回进度   
FFmpegCommand->runAsync(final String[] cmd, final ICallBack callBack)//异步执行,外部无需添加延时线程     
FFmpegCommand->getInfoSync(String path,@Attribute int type)//获取媒体信息,type值必须为`@Attribute`中注解参数

使用runSync

FFmpegCommand.runSync(final String[] cmd)方法不能直接使用,需要在子线程中运行,其中参数由FFmpegUtils工具类提供,也可以自己添加

String cmd = "ffmpeg -y -i %s -an -c:v rawvideo -pixel_format yuv420p %s";
final String result = String.format(Locale.CHINA, cmd, videoPath,output);
new Thread(
        new Runnable() {
            @Override
            public void run() {
                FFmpegCmd.runCmd(result.split(" "));
            }
        }
).start();

还可以使用获取进度的方法FFmpegCommand.runSync(final String[] cmd, FFmpegCmd.OnFFmpegProgressListener listener),但是需要注意的是,进度只能在Debug模式下才能获取

new Thread(new Runnable() {
            @Override
            public void run() {
                FFmpegCommand.runSync(FFmpegUtils.videoHLS(mVideoPath, targetPath, 10),new FFmpegCommand.OnFFmpegProgressListener() {
                    @Override
                    public void onProgress(int progress) {
                        Log.d("CmdProgress", progress + "");
                    }
                });
            }
        }).start();

使用runAsync

直接调用FFmpegCommand.runAsync(String[] cmd, ICallBack callback)方法,其中第一个参数由FFmpegUtils工具类提供,也可以自己添加

final long startTime = System.currentTimeMillis();
String input =Environment.getExternalStorageDirectory().getPath() + File.separator +
                        "DCIM" + File.separator + "test.mp3";
String output =Environment.getExternalStorageDirectory().getPath() + File.separator +
                        "DCIM" + File.separator + "output.mp3";

FFmpegCommand.runAsync(FFmpegUtils.cutAudio(input, "00:00:30", "00:00:40",
     output), new CommonCallBack() {
     @Override
     public void onComplete() {
         Log.d("FFmpegTest", "run: 耗时:" + (System.currentTimeMillis() - startTime));
     }
});

自定义FFmpeg命令

这里只是演示了音频剪切,很多如上述功能请自行查阅FFmpegUtils 如果其中不满足需求,可添加自己的FFmpeg命令.例如:

String cmd = "ffmpeg -y -i %s -vn -acodec copy -ss %s -t %s %s";
String result = String.format(cmd, input, "00:00:30", "00:00:40", output);
FFmpegCommand.runAsync(result.split(" "), new CommonCallBack() {
     @Override
     public void onComplete() {
         Log.d("FFmpegTest", "run: 耗时:" + (System.currentTimeMillis() - startTime));
     }
})

使用getInfoSync

FFmpegCommand.getInfoSync(String path,@Attribute int type)提供了获取媒体文件大小,视频宽高,比特率,音频采样率等属性值方法

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

参考

Clone this wiki locally