Running FFmpeg from my own AsyncTask
I would like to run FFmpeg from my own AsyncTask but there is no synchronous way to run FFmpeg.
This might be implemented in the future.
Fow now, there are a few options to accomplish what you want:
- Clone the source and modify it so you can use FFmpeg synchronously;
- Make a lock in ur own AsyncTask which waits for FFmpeg to complete.
Hi, trying to implement the second method with ReentrantLock. However it fails with the following error:
04-03 03:43:49.948 15212-15212/com.aviddapp.one E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.ex.ami, PID: 15212
java.lang.IllegalMonitorStateException
at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:126)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1260)
at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:434)
at com.ex.ami.tasks.HlsDownloader$1.onFinish(HlsDownloader.java:69)
at nl.bravobit.ffmpeg.FFcommandExecuteAsyncTask.onPostExecute(FFcommandExecuteAsyncTask.java:74)
at nl.bravobit.ffmpeg.FFcommandExecuteAsyncTask.onPostExecute(FFcommandExecuteAsyncTask.java:11)
at android.os.AsyncTask.finish(AsyncTask.java:660)
at android.os.AsyncTask.-wrap1(AsyncTask.java)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:677)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6123)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)
Here's the code:
lock.lock();
ffmpeg.execute(cmd, new ExecuteBinaryResponseHandler() {
@Override
public void onSuccess(String message) {
Log.d(TAG, "onSuccess");
download.setStatus(Download.DONE);
}
@Override
public void onProgress(String message) {
Log.d(TAG, "onProgress: " + message);
}
@Override
public void onFailure(String message) {
download.setStatus(Download.FAILED);
}
@Override
public void onStart() {
download.setStatus(Download.DOWNLOADING);
}
@Override
public void onFinish() {
Log.d(TAG, "onFinish");
lock.unlock();
}
});
Would be really helpful, 'cause we are using our own thread pools with dedicated max size.
A simple semaphore inside the doInBackground() of my AsyncTask did the trick for me :slightly_smiling_face: as per this answer,
all you have to do is acquire() the semaphore just after ffmpeg.execute(), and release() the semaphore in ffmpeg's onFinish(), it is working fine with me.
Now we have an issue, that standard Android ASYNC_TASK_POOL rejects works, if we trying to put too many tasks to queue. With our own thread pool, it would be much easier to do it.