Skip to content

Commit

Permalink
Revert "added support for multithreading"
Browse files Browse the repository at this point in the history
Disable mulththreading support for now, as it is not needed.

This reverts commit 8b562a5.
  • Loading branch information
brarcher committed Apr 3, 2018
1 parent ad34ed0 commit 411bfdb
Show file tree
Hide file tree
Showing 13 changed files with 205 additions and 168 deletions.
21 changes: 14 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,14 @@ FFmpeg in this project was built with the following libraries:
- Uses native CPU capabilities on ARM architectures
- FFprobe is bundled in this library too
- Enabled network capabilities
- Multithreading

## Usage

### Getting Started
Include the dependency
```gradle
dependencies {
implementation 'nl.bravobit:android-ffmpeg:1.1.2'
implementation 'nl.bravobit:android-ffmpeg:1.1.1'
}
```

Expand All @@ -58,8 +57,9 @@ This is all you have to do to load the FFmpeg library.
In this sample code we will run the ffmpeg -version command.
```java
FFmpeg ffmpeg = FFmpeg.getInstance(context);
try {
// to execute "ffmpeg -version" command you just need to pass "-version"
ffmpeg.execute(cmd, new ExecuteBinaryResponseHandler() {
ffmpeg.execute(cmd, new ExecuteBinaryResponseHandler() {

@Override
public void onStart() {}
Expand All @@ -76,7 +76,10 @@ ffmpeg.execute(cmd, new ExecuteBinaryResponseHandler() {
@Override
public void onFinish() {}

});
});
} catch (FFmpegCommandAlreadyRunningException e) {
// Handle if FFmpeg is already running
}
```

### Check if FFprobe is supported
Expand All @@ -94,8 +97,9 @@ This is all you have to do to load the FFprobe library.
In this sample code we will run the ffprobe -version command.
```java
FFprobe ffprobe = FFprobe.getInstance(context);
// to execute "ffprobe -version" command you just need to pass "-version"
ffprobe.execute(cmd, new ExecuteBinaryResponseHandler() {
try {
// to execute "ffprobe -version" command you just need to pass "-version"
ffprobe.execute(cmd, new ExecuteBinaryResponseHandler() {

@Override
public void onStart() {}
Expand All @@ -112,7 +116,10 @@ ffprobe.execute(cmd, new ExecuteBinaryResponseHandler() {
@Override
public void onFinish() {}

});
});
} catch (FFprobeCommandAlreadyRunningException e) {
// Handle if FFprobe is already running
}
```

## Special Thanks To
Expand Down
8 changes: 4 additions & 4 deletions android-ffmpeg/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ext {
siteUrl = 'https://github.com/bravobit/FFmpeg-Android'
gitUrl = 'https://github.com/bravobit/FFmpeg-Android.git'

libraryVersion = '1.1.2'
libraryVersion = '1.1.1'

developerId = 'Bravobit'
developerName = 'Bravobit'
Expand All @@ -27,8 +27,8 @@ android {
defaultConfig {
minSdkVersion 16
targetSdkVersion 27
versionCode 12
versionName "1.1.2"
versionCode 11
versionName "1.1.1"
}

compileOptions {
Expand All @@ -48,7 +48,7 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])

implementation 'com.android.support:appcompat-v7:27.1.0'
implementation 'com.android.support:appcompat-v7:27.0.2'
}

apply plugin: 'com.github.dcendents.android-maven'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import java.util.Map;

import nl.bravobit.ffmpeg.exceptions.FFcommandAlreadyRunningException;
import nl.bravobit.ffmpeg.exceptions.FFmpegCommandAlreadyRunningException;

interface FFbinaryInterface {

/**
Expand All @@ -11,17 +14,19 @@ interface FFbinaryInterface {
* @param cmd command to execute
* @param ffcommandExecuteResponseHandler {@link FFcommandExecuteResponseHandler}
* @return the task
* @throws FFmpegCommandAlreadyRunningException throws exception when binary is already running
*/
FFtask execute(Map<String, String> environmentVars, String[] cmd, FFcommandExecuteResponseHandler ffcommandExecuteResponseHandler);
FFtask execute(Map<String, String> environmentVars, String[] cmd, FFcommandExecuteResponseHandler ffcommandExecuteResponseHandler) throws FFcommandAlreadyRunningException;

/**
* Executes a command
*
* @param cmd command to execute
* @param ffcommandExecuteResponseHandler {@link FFcommandExecuteResponseHandler}
* @return the task
* @throws FFmpegCommandAlreadyRunningException throws exception when binary is already running
*/
FFtask execute(String[] cmd, FFcommandExecuteResponseHandler ffcommandExecuteResponseHandler);
FFtask execute(String[] cmd, FFcommandExecuteResponseHandler ffcommandExecuteResponseHandler) throws FFcommandAlreadyRunningException;

/**
* Checks if FF binary is supported on this device
Expand All @@ -31,25 +36,32 @@ interface FFbinaryInterface {
boolean isSupported();

/**
* Checks if a command with given task is currently running
* Checks if a command is currently running
*
* @param task - the task that you want to check
* @return true if a command is running
*/
boolean isCommandRunning(FFcommandExecuteAsyncTask task);
boolean isCommandRunning();

/**
* Kill given running process
* Kill running process
*
* @param task - the task to kill
* @return true if process is killed successfully
*/
boolean killRunningProcesses(FFcommandExecuteAsyncTask task);
boolean killRunningProcesses();

/**
* Timeout for binary process, should be minimum of 10 seconds
*
* @param timeout in milliseconds
*/
void setTimeout(long timeout);

/**
* Wait for ffmpeg to get ready asynchronously
*
* @param onReady code to run when binary is ready
* @param timeout when to give up in milliseconds
* @return binary observer
*/
FFbinaryObserver whenFFbinaryIsReady(Runnable onReady, int timeout);
}
37 changes: 27 additions & 10 deletions android-ffmpeg/src/main/java/nl/bravobit/ffmpeg/FFmpeg.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,21 @@

import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.util.Map;

import nl.bravobit.ffmpeg.exceptions.FFmpegCommandAlreadyRunningException;

public class FFmpeg implements FFbinaryInterface {
private static final int VERSION = 12; // up this version when you add a new ffmpeg build
private static final String KEY_PREF_VERSION = "ffmpeg_version";

private final FFbinaryContextProvider context;
private FFcommandExecuteAsyncTask ffmpegExecuteAsyncTask;

private static final long MINIMUM_TIMEOUT = 10 * 1000;
private long timeout = Long.MAX_VALUE;
Expand Down Expand Up @@ -109,13 +111,16 @@ public boolean isSupported() {
}

@Override
public FFtask execute(Map<String, String> environvenmentVars, String[] cmd, FFcommandExecuteResponseHandler ffmpegExecuteResponseHandler) {
public FFtask execute(Map<String, String> environvenmentVars, String[] cmd, FFcommandExecuteResponseHandler 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.getFFmpegCommand(context.provide(), environvenmentVars)};
String[] command = concatenate(ffmpegBinary, cmd);
FFcommandExecuteAsyncTask task = new FFcommandExecuteAsyncTask(command, timeout, ffmpegExecuteResponseHandler);
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
return task;
ffmpegExecuteAsyncTask = new FFcommandExecuteAsyncTask(command, timeout, ffmpegExecuteResponseHandler);
ffmpegExecuteAsyncTask.execute();
return ffmpegExecuteAsyncTask;
} else {
throw new IllegalArgumentException("shell command cannot be empty");
}
Expand All @@ -134,18 +139,20 @@ private static <T> T[] concatenate(T[] a, T[] b) {
}

@Override
public FFtask execute(String[] cmd, FFcommandExecuteResponseHandler ffmpegExecuteResponseHandler) {
public FFtask execute(String[] cmd, FFcommandExecuteResponseHandler ffmpegExecuteResponseHandler) throws FFmpegCommandAlreadyRunningException {
return execute(null, cmd, ffmpegExecuteResponseHandler);
}

@Override
public boolean isCommandRunning(FFcommandExecuteAsyncTask task) {
return task != null && !task.isProcessCompleted();
public boolean isCommandRunning() {
return ffmpegExecuteAsyncTask != null && !ffmpegExecuteAsyncTask.isProcessCompleted();
}

@Override
public boolean killRunningProcesses(FFcommandExecuteAsyncTask task) {
return Util.killAsync(task);
public boolean killRunningProcesses() {
boolean status = Util.killAsync(ffmpegExecuteAsyncTask);
ffmpegExecuteAsyncTask = null;
return status;
}

@Override
Expand All @@ -154,4 +161,14 @@ public void setTimeout(long timeout) {
this.timeout = timeout;
}
}

@Override
public FFbinaryObserver whenFFbinaryIsReady(Runnable onReady, int timeout) {
return Util.observeOnce(new Util.ObservePredicate() {
@Override
public Boolean isReadyToProceed() {
return !isCommandRunning();
}
}, onReady, timeout);
}
}
37 changes: 27 additions & 10 deletions android-ffmpeg/src/main/java/nl/bravobit/ffmpeg/FFprobe.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,21 @@

import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.util.Map;

import nl.bravobit.ffmpeg.exceptions.FFprobeCommandAlreadyRunningException;

public class FFprobe implements FFbinaryInterface {
private static final int VERSION = 12; // up this version when you add a new ffprobe build
private static final String KEY_PREF_VERSION = "ffprobe_version";

private final FFbinaryContextProvider context;
private FFcommandExecuteAsyncTask ffprobeExecuteAsyncTask;

private static final long MINIMUM_TIMEOUT = 10 * 1000;
private long timeout = Long.MAX_VALUE;
Expand Down Expand Up @@ -109,13 +111,16 @@ public boolean isSupported() {
}

@Override
public FFtask execute(Map<String, String> environvenmentVars, String[] cmd, FFcommandExecuteResponseHandler ffcommandExecuteResponseHandler) {
public FFtask execute(Map<String, String> environvenmentVars, String[] cmd, FFcommandExecuteResponseHandler ffcommandExecuteResponseHandler) throws FFprobeCommandAlreadyRunningException {
if (ffprobeExecuteAsyncTask != null && !ffprobeExecuteAsyncTask.isProcessCompleted()) {
throw new FFprobeCommandAlreadyRunningException("FFprobe command is already running, you are only allowed to run single command at a time");
}
if (cmd.length != 0) {
String[] ffprobeBinary = new String[]{FileUtils.getFFprobeCommand(context.provide(), environvenmentVars)};
String[] command = concatenate(ffprobeBinary, cmd);
FFcommandExecuteAsyncTask task = new FFcommandExecuteAsyncTask(command, timeout, ffcommandExecuteResponseHandler);
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
return task;
ffprobeExecuteAsyncTask = new FFcommandExecuteAsyncTask(command, timeout, ffcommandExecuteResponseHandler);
ffprobeExecuteAsyncTask.execute();
return ffprobeExecuteAsyncTask;
} else {
throw new IllegalArgumentException("shell command cannot be empty");
}
Expand All @@ -134,18 +139,20 @@ private static <T> T[] concatenate(T[] a, T[] b) {
}

@Override
public FFtask execute(String[] cmd, FFcommandExecuteResponseHandler ffcommandExecuteResponseHandler) {
public FFtask execute(String[] cmd, FFcommandExecuteResponseHandler ffcommandExecuteResponseHandler) throws FFprobeCommandAlreadyRunningException {
return execute(null, cmd, ffcommandExecuteResponseHandler);
}

@Override
public boolean isCommandRunning(FFcommandExecuteAsyncTask task) {
return task != null && !task.isProcessCompleted();
public boolean isCommandRunning() {
return ffprobeExecuteAsyncTask != null && !ffprobeExecuteAsyncTask.isProcessCompleted();
}

@Override
public boolean killRunningProcesses(FFcommandExecuteAsyncTask task) {
return Util.killAsync(task);
public boolean killRunningProcesses() {
boolean status = Util.killAsync(ffprobeExecuteAsyncTask);
ffprobeExecuteAsyncTask = null;
return status;
}

@Override
Expand All @@ -154,4 +161,14 @@ public void setTimeout(long timeout) {
this.timeout = timeout;
}
}

@Override
public FFbinaryObserver whenFFbinaryIsReady(Runnable onReady, int timeout) {
return Util.observeOnce(new Util.ObservePredicate() {
@Override
public Boolean isReadyToProceed() {
return !isCommandRunning();
}
}, onReady, timeout);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package nl.bravobit.ffmpeg.exceptions;

/**
* Created by brian on 12-12-17.
*/

public class FFcommandAlreadyRunningException extends Exception {

public FFcommandAlreadyRunningException(String message) {
super(message);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package nl.bravobit.ffmpeg.exceptions;

public class FFmpegCommandAlreadyRunningException extends FFcommandAlreadyRunningException {

public FFmpegCommandAlreadyRunningException(String message) {
super(message);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package nl.bravobit.ffmpeg.exceptions;

public class FFprobeCommandAlreadyRunningException extends FFcommandAlreadyRunningException {

public FFprobeCommandAlreadyRunningException(String message) {
super(message);
}

}
8 changes: 1 addition & 7 deletions sample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,7 @@ android {

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.0.2'

// Android libraries
implementation 'com.android.support:appcompat-v7:27.1.0'

// Misc
implementation 'com.jakewharton.timber:timber:4.6.1'

// FFmpeg project
implementation project(':android-ffmpeg')
}
4 changes: 0 additions & 4 deletions sample/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,11 @@

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />

<application
android:name=".FFmpegExample"
android:allowBackup="true"
android:hardwareAccelerated="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
Expand Down
Loading

0 comments on commit 411bfdb

Please sign in to comment.