-
Notifications
You must be signed in to change notification settings - Fork 2
/
FFmpeg.java
134 lines (112 loc) · 4.91 KB
/
FFmpeg.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package com.github.hiteshsondhi88.libffmpeg;
import android.content.Context;
import android.os.AsyncTask;
import android.text.TextUtils;
import java.lang.reflect.Array;
import java.util.Map;
import com.github.hiteshsondhi88.libffmpeg.exceptions.FFmpegCommandAlreadyRunningException;
import com.github.hiteshsondhi88.libffmpeg.exceptions.FFmpegNotSupportedException;
@SuppressWarnings("unused")
public class FFmpeg implements FFmpegInterface {
private final Context context;
private FFmpegExecuteAsyncTask ffmpegExecuteAsyncTask;
private FFmpegLoadLibraryAsyncTask ffmpegLoadLibraryAsyncTask;
private static final long MINIMUM_TIMEOUT = 10 * 1000;
private long timeout = Long.MAX_VALUE;
private static FFmpeg instance = null;
private FFmpeg(Context context) {
this.context = context.getApplicationContext();
Log.setDEBUG(Util.isDebug(this.context));
}
public static FFmpeg getInstance(Context context) {
if (instance == null) {
instance = new FFmpeg(context);
}
return instance;
}
@Override
public void loadBinary(FFmpegLoadBinaryResponseHandler ffmpegLoadBinaryResponseHandler) throws FFmpegNotSupportedException {
String cpuArchNameFromAssets = null;
switch (CpuArchHelper.getCpuArch()) {
case x86:
Log.i("Loading FFmpeg for x86 CPU");
cpuArchNameFromAssets = "x86";
break;
case ARMv7:
Log.i("Loading FFmpeg for armv7 CPU");
cpuArchNameFromAssets = "armeabi-v7a";
break;
case ARMv8:
Log.i("Loading FFmpeg for arm64-v8a CPU");
cpuArchNameFromAssets = "arm64-v8a";
break;
case x86_64:
Log.i("Loading FFmpeg for x86_64 CPU");
cpuArchNameFromAssets = "x86_64";
break;
case NONE:
throw new FFmpegNotSupportedException("Device not supported");
}
if (!TextUtils.isEmpty(cpuArchNameFromAssets)) {
ffmpegLoadLibraryAsyncTask = new FFmpegLoadLibraryAsyncTask(context, cpuArchNameFromAssets, ffmpegLoadBinaryResponseHandler);
ffmpegLoadLibraryAsyncTask.execute();
} else {
throw new FFmpegNotSupportedException("Device not supported");
}
}
@Override
public void execute(Map<String, String> environvenmentVars, String[] cmd, FFmpegExecuteResponseHandler ffmpegExecuteResponseHandler) throws FFmpegCommandAlreadyRunningException {
/*if (ffmpegExecuteAsyncTask != null && !ffmpegExecuteAsyncTask.isProcessCompleted()) {
throw new FFmpegCommandAlreadyRunningException("FFmpeg command is already running, you are only allowed to run single command at a time");
}*/
if (cmd.length != 0) {
String[] ffmpegBinary = new String[] { FileUtils.getFFmpeg(context, environvenmentVars) };
String[] command = concatenate(ffmpegBinary, cmd);
ffmpegExecuteAsyncTask = new FFmpegExecuteAsyncTask(command , timeout, ffmpegExecuteResponseHandler);
ffmpegExecuteAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
throw new IllegalArgumentException("shell command cannot be empty");
}
}
public <T> T[] concatenate (T[] a, T[] b) {
int aLen = a.length;
int bLen = b.length;
@SuppressWarnings("unchecked")
T[] c = (T[]) Array.newInstance(a.getClass().getComponentType(), aLen + bLen);
System.arraycopy(a, 0, c, 0, aLen);
System.arraycopy(b, 0, c, aLen, bLen);
return c;
}
@Override
public void execute(String[] cmd, FFmpegExecuteResponseHandler ffmpegExecuteResponseHandler) throws FFmpegCommandAlreadyRunningException {
execute(null, cmd, ffmpegExecuteResponseHandler);
}
@Override
public String getDeviceFFmpegVersion() throws FFmpegCommandAlreadyRunningException {
ShellCommand shellCommand = new ShellCommand();
CommandResult commandResult = shellCommand.runWaitFor(new String[] { FileUtils.getFFmpeg(context), "-version" });
if (commandResult.success) {
return commandResult.output.split(" ")[2];
}
// if unable to find version then return "" to avoid NPE
return "";
}
@Override
public String getLibraryFFmpegVersion() {
return context.getString(R.string.shipped_ffmpeg_version);
}
@Override
public boolean isFFmpegCommandRunning() {
return ffmpegExecuteAsyncTask != null && !ffmpegExecuteAsyncTask.isProcessCompleted();
}
@Override
public boolean killRunningProcesses() {
return Util.killAsync(ffmpegLoadLibraryAsyncTask) || Util.killAsync(ffmpegExecuteAsyncTask);
}
@Override
public void setTimeout(long timeout) {
if (timeout >= MINIMUM_TIMEOUT) {
this.timeout = timeout;
}
}
}