Skip to content

Commit 809d321

Browse files
author
Administrator
committed
新增变速功能
1 parent b93a97b commit 809d321

File tree

2 files changed

+74
-51
lines changed

2 files changed

+74
-51
lines changed

joevideolib/src/main/java/Jni/VideoUitls.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ public static long getDuration(String url) {
2424
MediaExtractor mediaExtractor = new MediaExtractor();
2525
mediaExtractor.setDataSource(url);
2626
int videoExt = TrackUtils.selectVideoTrack(mediaExtractor);
27+
if(videoExt == -1){
28+
videoExt = TrackUtils.selectAudioTrack(mediaExtractor);
29+
if(videoExt == -1){
30+
return 0;
31+
}
32+
}
2733
MediaFormat mediaFormat = mediaExtractor.getTrackFormat(videoExt);
2834
long res = mediaFormat.containsKey(MediaFormat.KEY_DURATION) ? mediaFormat.getLong(MediaFormat.KEY_DURATION) : 0;//时长
2935
mediaExtractor.release();

joevideolib/src/main/java/VideoHandle/EpEditor.java

Lines changed: 68 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package VideoHandle;
22

33
import android.app.Activity;
4+
import android.app.Application;
45
import android.content.Context;
56
import android.media.MediaExtractor;
67
import android.media.MediaFormat;
@@ -25,14 +26,15 @@ public class EpEditor {
2526
private static final int DEFAULT_WIDTH = 480;//默认输出宽度
2627
private static final int DEFAULT_HEIGHT = 360;//默认输出高度
2728

28-
private Context context;
29-
3029
public enum Format {
3130
MP3, MP4
3231
}
3332

34-
public EpEditor(Context context) {
35-
this.context = context;
33+
public enum PTS {
34+
VIDEO, AUDIO, ALL
35+
}
36+
37+
private EpEditor() {
3638
}
3739

3840
/**
@@ -41,7 +43,7 @@ public EpEditor(Context context) {
4143
* @param epVideo 需要处理的视频
4244
* @param outputOption 输出选项配置
4345
*/
44-
public void exec(EpVideo epVideo, OutputOption outputOption, OnEditorListener onEditorListener) {
46+
public static void exec(EpVideo epVideo, OutputOption outputOption, OnEditorListener onEditorListener) {
4547
boolean isFilter = false;
4648
ArrayList<EpDraw> epDraws = epVideo.getEpDraws();
4749
//开始处理
@@ -107,7 +109,7 @@ public void exec(EpVideo epVideo, OutputOption outputOption, OnEditorListener on
107109
isFilter = true;
108110
}
109111
}
110-
if(!filter_complex.toString().equals("")) {
112+
if (!filter_complex.toString().equals("")) {
111113
cmd.append(filter_complex.toString());
112114
}
113115
}
@@ -139,7 +141,7 @@ public void exec(EpVideo epVideo, OutputOption outputOption, OnEditorListener on
139141
* @param epVideos 需要合并的视频集合
140142
* @param outputOption 输出选项配置
141143
*/
142-
public void merge(List<EpVideo> epVideos, OutputOption outputOption, OnEditorListener onEditorListener) {
144+
public static void merge(List<EpVideo> epVideos, OutputOption outputOption, OnEditorListener onEditorListener) {
143145
//检测是否有无音轨视频
144146
boolean isNoAudioTrack = false;
145147
for (EpVideo epVideo : epVideos) {
@@ -225,7 +227,7 @@ public void merge(List<EpVideo> epVideos, OutputOption outputOption, OnEditorLis
225227
}
226228
filter_complex.append("concat=n=").append(epVideos.size()).append(":v=0:a=1[outa]");
227229
}
228-
if(!filter_complex.toString().equals("")) {
230+
if (!filter_complex.toString().equals("")) {
229231
cmd.append(filter_complex.toString());
230232
}
231233
cmd.append("-map").append("[outv]");
@@ -259,11 +261,12 @@ public void merge(List<EpVideo> epVideos, OutputOption outputOption, OnEditorLis
259261
* <p>
260262
* 注意:此方法要求视频格式非常严格,需要合并的视频必须分辨率相同,帧率和码率也得相同
261263
*
264+
* @param context Context
262265
* @param epVideos 需要合并的视频的集合
263266
* @param outputOption 输出选项
264267
* @param onEditorListener 回调监听
265268
*/
266-
public void mergeByLc(List<EpVideo> epVideos, OutputOption outputOption, final OnEditorListener onEditorListener) {
269+
public static void mergeByLc(Context context, List<EpVideo> epVideos, OutputOption outputOption, final OnEditorListener onEditorListener) {
267270
String appDir = context.getFilesDir().getAbsolutePath() + "/EpVideos/";
268271
String fileName = "ffmpeg_concat.txt";
269272
List<String> videos = new ArrayList<>();
@@ -297,7 +300,7 @@ public void mergeByLc(List<EpVideo> epVideos, OutputOption outputOption, final O
297300
* @param audioVolume 背景音乐音量(例:1.5为150%)
298301
* @param onEditorListener 回调监听
299302
*/
300-
public void music(String videoin, String audioin, String output, float videoVolume, float audioVolume, OnEditorListener onEditorListener) {
303+
public static void music(String videoin, String audioin, String output, float videoVolume, float audioVolume, OnEditorListener onEditorListener) {
301304
MediaExtractor mediaExtractor = new MediaExtractor();
302305
try {
303306
mediaExtractor.setDataSource(videoin);
@@ -331,7 +334,7 @@ public void music(String videoin, String audioin, String output, float videoVolu
331334
* @param format 输出类型
332335
* @param onEditorListener 回调监听
333336
*/
334-
public void demuxer(String videoin, String out, Format format, OnEditorListener onEditorListener) {
337+
public static void demuxer(String videoin, String out, Format format, OnEditorListener onEditorListener) {
335338
CmdList cmd = new CmdList();
336339
cmd.append("ffmpeg").append("-y").append("-i").append(videoin);
337340
switch (format) {
@@ -346,6 +349,50 @@ public void demuxer(String videoin, String out, Format format, OnEditorListener
346349
execCmd(cmd, 0, onEditorListener);
347350
}
348351

352+
/**
353+
* 音视频变速
354+
*
355+
* @param videoin 音视频文件
356+
* @param out 输出路径
357+
* @param times 倍率(调整范围0.25-4)
358+
* @param pts 加速类型
359+
* @param onEditorListener 回调接口
360+
*/
361+
public static void changePTS(String videoin, String out, float times, PTS pts, OnEditorListener onEditorListener) {
362+
if (times < 0.25f || times > 4.0f) {
363+
Log.e("ffmpeg", "times参数错误,播放速率调整范围0.25-4倍");
364+
onEditorListener.onFailure();
365+
return;
366+
}
367+
CmdList cmd = new CmdList();
368+
cmd.append("ffmpeg").append("-y").append("-i").append(videoin);
369+
String t = "atempo=" + times;
370+
if (times < 0.5f) {
371+
t = "atempo=0.5,atempo=" + (times / 0.5f);
372+
} else if (times > 2.0f) {
373+
t = "atempo=2.0,atempo=" + (times / 2.0f);
374+
}
375+
Log.v("ffmpeg", "atempo:" + t);
376+
switch (pts) {
377+
case VIDEO:
378+
cmd.append("-filter_complex").append("[0:v]setpts=" + (1 / times) + "*PTS").append("-an");
379+
break;
380+
case AUDIO:
381+
cmd.append("-filter:a").append(t);
382+
break;
383+
case ALL:
384+
cmd.append("-filter_complex").append("[0:v]setpts=" + (1 / times) + "*PTS[v];[0:a]" + t + "[a]")
385+
.append("-map").append("[v]").append("-map").append("[a]");
386+
break;
387+
}
388+
cmd.append("-preset").append("superfast").append(out);
389+
long d = VideoUitls.getDuration(videoin);
390+
double dd = d / times;
391+
long ddd = (long) dd;
392+
Log.v("ffmpeg", "JD:" + d + "," + dd + "," + ddd);
393+
execCmd(cmd, ddd, onEditorListener);
394+
}
395+
349396

350397
/**
351398
* 输出选项设置
@@ -448,38 +495,23 @@ public void setHeight(int height) {
448495
*
449496
* @param cmd 命令
450497
*/
451-
public void execCmd(String cmd, long duration, final OnEditorListener onEditorListener) {
498+
public static void execCmd(String cmd, long duration, final OnEditorListener onEditorListener) {
452499
cmd = "ffmpeg " + cmd;
453500
String[] cmds = cmd.split(" ");
454501
FFmpegCmd.exec(cmds, duration, new OnEditorListener() {
455502
@Override
456503
public void onSuccess() {
457-
((Activity) context).runOnUiThread(new Runnable() {
458-
@Override
459-
public void run() {
460-
onEditorListener.onSuccess();
461-
}
462-
});
504+
onEditorListener.onSuccess();
463505
}
464506

465507
@Override
466508
public void onFailure() {
467-
((Activity) context).runOnUiThread(new Runnable() {
468-
@Override
469-
public void run() {
470-
onEditorListener.onFailure();
471-
}
472-
});
509+
onEditorListener.onFailure();
473510
}
474511

475512
@Override
476513
public void onProgress(final float progress) {
477-
((Activity) context).runOnUiThread(new Runnable() {
478-
@Override
479-
public void run() {
480-
onEditorListener.onProgress(progress);
481-
}
482-
});
514+
onEditorListener.onProgress(progress);
483515
}
484516
});
485517
}
@@ -489,40 +521,25 @@ public void run() {
489521
*
490522
* @param cmd 命令
491523
*/
492-
public void execCmd(CmdList cmd, long duration, final OnEditorListener onEditorListener) {
524+
private static void execCmd(CmdList cmd, long duration, final OnEditorListener onEditorListener) {
493525
String[] cmds = cmd.toArray(new String[cmd.size()]);
494-
for (String ss:cmds) {
495-
Log.v("EpMediaF","cmd:"+ss);
526+
for (String ss : cmds) {
527+
Log.v("EpMediaF", "cmd:" + ss);
496528
}
497529
FFmpegCmd.exec(cmds, duration, new OnEditorListener() {
498530
@Override
499531
public void onSuccess() {
500-
((Activity) context).runOnUiThread(new Runnable() {
501-
@Override
502-
public void run() {
503-
onEditorListener.onSuccess();
504-
}
505-
});
532+
onEditorListener.onSuccess();
506533
}
507534

508535
@Override
509536
public void onFailure() {
510-
((Activity) context).runOnUiThread(new Runnable() {
511-
@Override
512-
public void run() {
513-
onEditorListener.onFailure();
514-
}
515-
});
537+
onEditorListener.onFailure();
516538
}
517539

518540
@Override
519541
public void onProgress(final float progress) {
520-
((Activity) context).runOnUiThread(new Runnable() {
521-
@Override
522-
public void run() {
523-
onEditorListener.onProgress(progress);
524-
}
525-
});
542+
onEditorListener.onProgress(progress);
526543
}
527544
});
528545
}

0 commit comments

Comments
 (0)