bravobit / FFmpeg-Android

FFMpeg/FFprobe compiled for Android
https://bravobit.nl/
MIT License
741 stars 176 forks source link

Running FFmpeg from my own AsyncTask #27

Open royale1223 opened 6 years ago

royale1223 commented 6 years ago

I would like to run FFmpeg from my own AsyncTask but there is no synchronous way to run FFmpeg.

Brianvdb commented 6 years ago

This might be implemented in the future.

Fow now, there are a few options to accomplish what you want:

royale1223 commented 6 years ago

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();
            }
        });
formatBCE commented 6 years ago

Would be really helpful, 'cause we are using our own thread pools with dedicated max size.

Abdelhady commented 5 years ago

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.

formatBCE commented 5 years ago

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.