Dear fellow StackOverflower,
In my Android application, I'm trying to quickly retrieve a frame from a video using ffmpeg-android-java to display in an ImageView
. The problem is using a typical ffmpeg
's -ss
seeking command will require to write the output into the memory which I suppose is the big hit on performance:
ffmpeg -ss 00:23:00 -i Mononoke.Hime.mkv -frames:v 1 out1.jpg
A typical command execution like above takes around 700 - 1200 milliseconds. So instead of writing into the memory, I would like to write it into LruCache
hoping to achieve a better performance.
The problem is ffmpeg-android-java
is a wrapper to execute ffmpeg
command and as such I don't know how to correctly supply the LruCache
's address for the command.
Below is my code snippet:
private void seekToPosition(long currentVideoPosition){
String position = DiskUtils.formatMillisForFFmpeg(currentVideoPosition);
String[] cmd = {"-ss", String.valueOf(position), "-i", mVideoPath,
"-y", "-an", "-frames:v", "1",
"/storage/emulated/0/Videos/out.jpg"}; //this the problem, I would like to change this to the address of LruCache
try {
// to execute "ffmpeg -version" command you just need to pass "-version"
mFFmpeg.execute(cmd, new ExecuteBinaryResponseHandler() {
long start;
long end;
@Override
public void onStart() {
canSeek = false;
start = System.currentTimeMillis();
}
@Override
public void onProgress(String message) {}
@Override
public void onFailure(String message) {
Log.d(TAG, "FFmpeg cmd failure");
}
@Override
public void onSuccess(String message) {
Log.d(TAG, "FFmpeg cmd success");
/*mFFmpeg.killRunningProcesses();
Log.d(TAG, "FFmpeg kill running process: " + mFFmpeg.killRunningProcesses());*/
}
@Override
public void onFinish() {
canSeek = true;
Log.d(TAG, "FFmpeg cmd finished: is FFmpeg process running: " + mFFmpeg.isFFmpegCommandRunning());
end = System.currentTimeMillis();
Log.d(TAG, "FFmpeg excuted in: " + (end - start) + " milliseconds");
}
});
} catch (FFmpegCommandAlreadyRunningException e) {
// Handle if FFmpeg is already running
Log.d(TAG, "FFmpeg exception: " + e);
}
}
To answer my own question, I haven't found the solution for this yet as it's kind of impossible in nature. So instead, I take the hard way of compiling the FFmpeg and using the JNI to use it as a library.
You can take a look at my step-by-step instructions if you need some guidance on building and using FFmpeg with Android Studio because I know trying to figure this out is a real nightmare.
Sorry I can't post all the instructions here as it is way too long, plus it is easier for me to keep 1 source of information up-to-date.