nol*_*nic 6 java android ffmpeg
我在我的一个视频压缩项目中使用 FFmpeg。在 Android 10 (Google Pixel 3a) 上,它会直接转到 onFailure(String message) 并为发送执行的任何命令提供空消息。
所以我在我的应用程序 gradle 文件中指定了 (api 'com.writingminds:FFmpegAndroid:0.3.2'),
指定清单中的权限(android.permission.WRITE_EXTERNAL_STORAGE)
所以我这样做:
InitializationCallback initializationCallback = new InitializationCallback();
try {
FFmpeg.getInstance(context).loadBinary(initializationCallback);
} catch (FFmpegNotSupportedException e) {
initializationCallback.onFailure();
initializationCallback.onFinish();
}
Run Code Online (Sandbox Code Playgroud)
初始化很好,这里没有问题。
之后:
void getData(File inputFile) {
//inputFile points to: /storage/emulated/0/Android/data/{package_name}/files/temp_files/temp_1.mp4
String[] cmd = ("-i " + inputFile.getAbsolutePath()).split(" ");
try {
FFmpeg.getInstance(App.instance).execute(cmd, this);
} catch (FFmpegCommandAlreadyRunningException e) {
throw new Error(e);
}
}
@Override
public void onStart() {
//This method is called
}
@Override
public void onSuccess(String message) {
//This method is NOT called
extractAvailableData(message);
}
@Override
public void onProgress(String message) {
//This method is NOT called
extractAvailableData(message);
}
@Override
public void onFailure(String message) {
//This method is called and the message is empty
extractAvailableData(message);
}
@Override
public void onFinish() {
//This method is called
}
Run Code Online (Sandbox Code Playgroud)
如果我做这样的事情:
String command = "-i ***/file1.mp4 -map 0:v -map 0:a -preset ultrafast -s:v 750:350 ***/file2.mp4";
//file2.mp4 is a non existent file at this point
// (***) --> is just a replacement for the full path of the file, just to keep things shorter here.
String[] cmd = command.split(" ");
try {
FFmpeg.getInstance(App.instance).execute(cmd, this);
} catch (FFmpegCommandAlreadyRunningException e) {
throw new Error(e);
}
Run Code Online (Sandbox Code Playgroud)
给出相同的结果,没有视频转换,只是调用 onFailure("Nothing")
即使我这样做:
String[] cmd = {"-version"};
try {
FFmpeg.getInstance(App.instance).execute(cmd, this);
} catch (FFmpegCommandAlreadyRunningException e) {
throw new Error(e);
}
Run Code Online (Sandbox Code Playgroud)
我什么也没得到,根本没有输出。
到目前为止,我只在 Android 10 上遇到过这个问题,它在其他设备上运行良好。
我不知道这是否是你的情况,但就我而言,问题是我在使用 ffmpeg.loadBinary 之前没有调用它。
这似乎有点违反直觉,因为它实际上可以与我的测试设备一起使用,而无需这样做。我对原因有一些想法,但没有时间测试这些。重要的是它现在正在发挥作用。这是我必须实现的示例:
FFmpeg ffmpeg = FFmpeg.getInstance(context);
ffmpeg.loadBinary(new FFmpegLoadBinaryResponseHandler() {
@Override
public void onFailure() {
// Report failure to logcat,show the user a dialog, throw an exception or whatever you want to do in case of failure
}
@Override
public void onSuccess() {
// Execute the real ffmpeg stuff here
}
@Override
public void onStart() {
}
@Override
public void onFinish() {
}
});
Run Code Online (Sandbox Code Playgroud)
在现实场景中,如果您打算多次使用它,您可以使用一个标志来确保它尚未加载,并避免在这种情况下尝试重新加载它。