Skip to content

Commit 038fe3e

Browse files
author
Karim Jahed
committed
Enabled loading FFmpeg binary from http and added back neon
1 parent 6fd8356 commit 038fe3e

File tree

13 files changed

+119
-103
lines changed

13 files changed

+119
-103
lines changed
-17.6 MB
Binary file not shown.

FFmpegAndroid/assets/x86/ffmpeg

-20.9 MB
Binary file not shown.

FFmpegAndroid/src/androidTest/java/com/github/hiteshsondhi88/libffmpeg/CpuArchTest.java

-38
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,8 @@
11
package com.github.hiteshsondhi88.libffmpeg;
22

3-
import android.text.TextUtils;
4-
53
enum CpuArch {
6-
x86("0dd4dbad305ff197a1ea9e6158bd2081d229e70e"),
7-
ARMv7("871888959ba2f063e18f56272d0d98ae01938ceb"),
8-
NONE(null);
9-
10-
private String sha1;
11-
12-
CpuArch(String sha1) {
13-
this.sha1 = sha1;
14-
}
15-
16-
String getSha1(){
17-
return sha1;
18-
}
19-
20-
static CpuArch fromString(String sha1) {
21-
if (!TextUtils.isEmpty(sha1)) {
22-
for (CpuArch cpuArch : CpuArch.values()) {
23-
if (sha1.equalsIgnoreCase(cpuArch.sha1)) {
24-
return cpuArch;
25-
}
26-
}
27-
}
28-
return NONE;
29-
}
4+
x86,
5+
ARMv7,
6+
ARMv7Neon,
7+
NONE
308
}

FFmpegAndroid/src/main/java/com/github/hiteshsondhi88/libffmpeg/CpuArchHelper.java

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ static CpuArch getCpuArch() {
1717
// check if device is arm v7
1818
if (cpuNativeArchHelper.isARM_v7_CPU(archInfo)) {
1919
// check if device is neon
20+
if(cpuNativeArchHelper.isNeonSupported(archInfo))
21+
return CpuArch.ARMv7Neon;
2022
return CpuArch.ARMv7;
2123
}
2224
// check if device is arm64 which is supported by ARMV7

FFmpegAndroid/src/main/java/com/github/hiteshsondhi88/libffmpeg/FFmpeg.java

+17-5
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
import android.content.Context;
44
import android.text.TextUtils;
55

6-
import java.lang.reflect.Array;
7-
import java.util.Map;
8-
96
import com.github.hiteshsondhi88.libffmpeg.exceptions.FFmpegCommandAlreadyRunningException;
107
import com.github.hiteshsondhi88.libffmpeg.exceptions.FFmpegNotSupportedException;
118

9+
import java.io.File;
10+
import java.lang.reflect.Array;
11+
import java.util.Map;
12+
1213
@SuppressWarnings("unused")
1314
public class FFmpeg implements FFmpegInterface {
1415

@@ -34,7 +35,7 @@ public static FFmpeg getInstance(Context context) {
3435
}
3536

3637
@Override
37-
public void loadBinary(FFmpegLoadBinaryResponseHandler ffmpegLoadBinaryResponseHandler) throws FFmpegNotSupportedException {
38+
public void loadBinary(String url, FFmpegLoadBinaryResponseHandler ffmpegLoadBinaryResponseHandler) throws FFmpegNotSupportedException {
3839
String cpuArchNameFromAssets = null;
3940
switch (CpuArchHelper.getCpuArch()) {
4041
case x86:
@@ -45,18 +46,29 @@ public void loadBinary(FFmpegLoadBinaryResponseHandler ffmpegLoadBinaryResponseH
4546
Log.i("Loading FFmpeg for armv7 CPU");
4647
cpuArchNameFromAssets = "armeabi-v7a";
4748
break;
49+
case ARMv7Neon:
50+
Log.i("Loading FFmpeg for armv7-neon CPU");
51+
cpuArchNameFromAssets = "armeabi-v7a-neon";
52+
break;
4853
case NONE:
4954
throw new FFmpegNotSupportedException("Device not supported");
5055
}
5156

5257
if (!TextUtils.isEmpty(cpuArchNameFromAssets)) {
53-
ffmpegLoadLibraryAsyncTask = new FFmpegLoadLibraryAsyncTask(context, cpuArchNameFromAssets, ffmpegLoadBinaryResponseHandler);
58+
ffmpegLoadLibraryAsyncTask = new FFmpegLoadLibraryAsyncTask(context, url, cpuArchNameFromAssets, ffmpegLoadBinaryResponseHandler);
5459
ffmpegLoadLibraryAsyncTask.execute();
5560
} else {
5661
throw new FFmpegNotSupportedException("Device not supported");
5762
}
5863
}
5964

65+
@Override
66+
public void unloadBinary() {
67+
File ffmpegFile = new File(FileUtils.getFFmpeg(context));
68+
if(ffmpegFile.exists())
69+
ffmpegFile.delete();
70+
}
71+
6072
@Override
6173
public void execute(Map<String, String> environvenmentVars, String[] cmd, FFmpegExecuteResponseHandler ffmpegExecuteResponseHandler) throws FFmpegCommandAlreadyRunningException {
6274
if (ffmpegExecuteAsyncTask != null && !ffmpegExecuteAsyncTask.isProcessCompleted()) {

FFmpegAndroid/src/main/java/com/github/hiteshsondhi88/libffmpeg/FFmpegInterface.java

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
package com.github.hiteshsondhi88.libffmpeg;
22

3-
import java.util.Map;
4-
53
import com.github.hiteshsondhi88.libffmpeg.exceptions.FFmpegCommandAlreadyRunningException;
64
import com.github.hiteshsondhi88.libffmpeg.exceptions.FFmpegNotSupportedException;
75

6+
import java.util.Map;
7+
88
@SuppressWarnings("unused")
99
interface FFmpegInterface {
1010

1111
/**
1212
* Load binary to the device according to archituecture. This also updates FFmpeg binary if the binary on device have old version.
13+
* @param url the url to download the binary from
1314
* @param ffmpegLoadBinaryResponseHandler {@link FFmpegLoadBinaryResponseHandler}
1415
* @throws FFmpegNotSupportedException
1516
*/
16-
public void loadBinary(FFmpegLoadBinaryResponseHandler ffmpegLoadBinaryResponseHandler) throws FFmpegNotSupportedException;
17+
public void loadBinary(String url, FFmpegLoadBinaryResponseHandler ffmpegLoadBinaryResponseHandler) throws FFmpegNotSupportedException;
1718

1819
/**
1920
* Executes a command
@@ -63,4 +64,8 @@ interface FFmpegInterface {
6364
*/
6465
public void setTimeout(long timeout);
6566

67+
/**
68+
* Delete the FFmpeg binary from the file system
69+
*/
70+
public void unloadBinary();
6671
}

FFmpegAndroid/src/main/java/com/github/hiteshsondhi88/libffmpeg/FFmpegLoadBinaryResponseHandler.java

+5
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,9 @@ public interface FFmpegLoadBinaryResponseHandler extends ResponseHandler {
1212
*/
1313
public void onSuccess();
1414

15+
/**
16+
* on Progress
17+
*/
18+
public void onProgress(int progress);
19+
1520
}

FFmpegAndroid/src/main/java/com/github/hiteshsondhi88/libffmpeg/FFmpegLoadLibraryAsyncTask.java

+62-16
Original file line numberDiff line numberDiff line change
@@ -4,43 +4,87 @@
44
import android.os.AsyncTask;
55

66
import java.io.File;
7+
import java.io.FileOutputStream;
8+
import java.io.IOException;
9+
import java.io.InputStream;
10+
import java.io.OutputStream;
11+
import java.net.HttpURLConnection;
12+
import java.net.URL;
713

8-
class FFmpegLoadLibraryAsyncTask extends AsyncTask<Void, Void, Boolean> {
14+
class FFmpegLoadLibraryAsyncTask extends AsyncTask<Void, Integer, Boolean> {
915

16+
private final String baseUrl;
1017
private final String cpuArchNameFromAssets;
1118
private final FFmpegLoadBinaryResponseHandler ffmpegLoadBinaryResponseHandler;
1219
private final Context context;
1320

14-
FFmpegLoadLibraryAsyncTask(Context context, String cpuArchNameFromAssets, FFmpegLoadBinaryResponseHandler ffmpegLoadBinaryResponseHandler) {
21+
FFmpegLoadLibraryAsyncTask(Context context, String baseUrl, String cpuArchNameFromAssets, FFmpegLoadBinaryResponseHandler ffmpegLoadBinaryResponseHandler) {
1522
this.context = context;
23+
this.baseUrl = baseUrl;
1624
this.cpuArchNameFromAssets = cpuArchNameFromAssets;
1725
this.ffmpegLoadBinaryResponseHandler = ffmpegLoadBinaryResponseHandler;
1826
}
1927

2028
@Override
2129
protected Boolean doInBackground(Void... params) {
2230
File ffmpegFile = new File(FileUtils.getFFmpeg(context));
23-
if (ffmpegFile.exists() && isDeviceFFmpegVersionOld() && !ffmpegFile.delete()) {
24-
return false;
25-
}
31+
2632
if (!ffmpegFile.exists()) {
27-
boolean isFileCopied = FileUtils.copyBinaryFromAssetsToData(context,
28-
cpuArchNameFromAssets + File.separator + FileUtils.ffmpegFileName,
29-
FileUtils.ffmpegFileName);
33+
InputStream input = null;
34+
OutputStream output = null;
35+
HttpURLConnection connection = null;
36+
37+
try {
38+
URL url = new URL(baseUrl + "/" + cpuArchNameFromAssets + "/" + FileUtils.ffmpegFileName);
39+
connection = (HttpURLConnection) url.openConnection();
40+
connection.connect();
41+
42+
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK)
43+
return false;
44+
45+
int fileLength = connection.getContentLength();
46+
input = connection.getInputStream();
47+
output = new FileOutputStream(ffmpegFile, false);
48+
49+
byte data[] = new byte[8192];
50+
long total = 0;
51+
int count;
52+
53+
while ((count = input.read(data)) != -1) {
54+
total += count;
55+
56+
if (fileLength > 0)
57+
publishProgress((int) (total * 100 / fileLength));
58+
59+
output.write(data, 0, count);
60+
}
3061

31-
// make file executable
32-
if (isFileCopied) {
3362
if(!ffmpegFile.canExecute()) {
34-
Log.d("FFmpeg is not executable, trying to make it executable ...");
3563
if (ffmpegFile.setExecutable(true)) {
3664
return true;
3765
}
38-
} else {
39-
Log.d("FFmpeg is executable");
40-
return true;
4166
}
67+
68+
return true;
69+
70+
} catch (Exception e) {
71+
72+
return false;
73+
74+
} finally {
75+
try {
76+
if (output != null)
77+
output.close();
78+
if (input != null)
79+
input.close();
80+
} catch (IOException e) {
81+
}
82+
83+
if (connection != null)
84+
connection.disconnect();
4285
}
4386
}
87+
4488
return ffmpegFile.exists() && ffmpegFile.canExecute();
4589
}
4690

@@ -57,7 +101,9 @@ protected void onPostExecute(Boolean isSuccess) {
57101
}
58102
}
59103

60-
private boolean isDeviceFFmpegVersionOld() {
61-
return CpuArch.fromString(FileUtils.SHA1(FileUtils.getFFmpeg(context))).equals(CpuArch.NONE);
104+
@Override
105+
protected void onProgressUpdate(Integer... values) {
106+
super.onProgressUpdate(values);
107+
ffmpegLoadBinaryResponseHandler.onProgress(values[0]);
62108
}
63109
}

FFmpegAndroid/src/main/java/com/github/hiteshsondhi88/libffmpeg/LoadBinaryResponseHandler.java

+5
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,9 @@ public void onStart() {
2121
public void onFinish() {
2222

2323
}
24+
25+
@Override
26+
public void onProgress(int progress) {
27+
28+
}
2429
}

app/src/main/java/com/github/hiteshsondhi88/sampleffmpeg/Home.java

+9-8
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import android.app.ProgressDialog;
66
import android.content.DialogInterface;
77
import android.os.Bundle;
8-
import android.text.TextUtils;
98
import android.util.Log;
109
import android.view.View;
1110
import android.widget.Button;
@@ -14,22 +13,24 @@
1413
import android.widget.TextView;
1514
import android.widget.Toast;
1615

17-
import javax.inject.Inject;
18-
19-
import butterknife.ButterKnife;
20-
import butterknife.InjectView;
21-
import dagger.ObjectGraph;
22-
2316
import com.github.hiteshsondhi88.libffmpeg.ExecuteBinaryResponseHandler;
2417
import com.github.hiteshsondhi88.libffmpeg.FFmpeg;
2518
import com.github.hiteshsondhi88.libffmpeg.LoadBinaryResponseHandler;
2619
import com.github.hiteshsondhi88.libffmpeg.exceptions.FFmpegCommandAlreadyRunningException;
2720
import com.github.hiteshsondhi88.libffmpeg.exceptions.FFmpegNotSupportedException;
2821

22+
import javax.inject.Inject;
23+
24+
import butterknife.ButterKnife;
25+
import butterknife.InjectView;
26+
import dagger.ObjectGraph;
27+
2928
public class Home extends Activity implements View.OnClickListener {
3029

3130
private static final String TAG = Home.class.getSimpleName();
3231

32+
private static final String FFMPEG_URL = "http://jahed.ca/ffmpeg";
33+
3334
@Inject
3435
FFmpeg ffmpeg;
3536

@@ -64,7 +65,7 @@ private void initUI() {
6465

6566
private void loadFFMpegBinary() {
6667
try {
67-
ffmpeg.loadBinary(new LoadBinaryResponseHandler() {
68+
ffmpeg.loadBinary(FFMPEG_URL, new LoadBinaryResponseHandler() {
6869
@Override
6970
public void onFailure() {
7071
showUnsupportedExceptionDialog();

build.gradle

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ buildscript {
55
jcenter()
66
}
77
dependencies {
8-
classpath 'com.android.tools.build:gradle:2.1.0-beta3'
9-
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'
8+
classpath 'com.android.tools.build:gradle:2.3.3'
9+
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
1010
classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.1"
1111

1212
// NOTE: Do not place your application dependencies here; they belong
@@ -21,9 +21,9 @@ allprojects {
2121
}
2222

2323
ext {
24-
compileSdkVersion = 22
25-
buildToolsVersion = '22.0.1'
26-
targetSdkVersion = 22
24+
compileSdkVersion = 26
25+
buildToolsVersion = '26.0.2'
26+
targetSdkVersion = 26
2727
minSdkVersion = 16
2828
versionCode = 28
2929
versionName = "0.3.2"
+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#Wed Apr 20 11:52:28 GMT+05:30 2016
1+
#Thu Dec 28 18:54:00 EST 2017
22
distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
6-
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip

0 commit comments

Comments
 (0)