├── .gitignore ├── LICENSE ├── README.md ├── build.gradle ├── example ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── cn │ │ └── dxjia │ │ └── ffmpegexecutor │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── cn │ │ │ └── dxjia │ │ │ └── ffmpegexecutor │ │ │ └── MainActivity.java │ └── res │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── cn │ └── dxjia │ └── ffmpegexecutor │ └── ExampleUnitTest.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── library ├── .gitignore ├── address2line.cmd ├── bintray.gradle ├── build.gradle ├── gradle.properties ├── jni │ ├── Android.mk │ ├── FFmpegNativeHelper.c │ ├── FFmpegNativeHelper.h │ ├── android_log.h │ ├── arm_config.h │ ├── build.cmd │ ├── build.sh │ ├── cmdutils.c │ ├── cmdutils.h │ ├── cmdutils_common_opts.h │ ├── config.h │ ├── ffmpeg.h │ ├── ffmpeg_filter.c │ ├── ffmpeg_opt.c │ ├── include │ │ ├── compat │ │ │ └── va_copy.h │ │ ├── libavcodec │ │ │ ├── arm │ │ │ │ └── mathops.h │ │ │ ├── avcodec.h │ │ │ ├── avfft.h │ │ │ ├── dv_profile.h │ │ │ ├── dxva2.h │ │ │ ├── mathops.h │ │ │ ├── old_codec_ids.h │ │ │ ├── qsv.h │ │ │ ├── vaapi.h │ │ │ ├── vda.h │ │ │ ├── vdpau.h │ │ │ ├── version.h │ │ │ ├── vorbis_parser.h │ │ │ ├── x86 │ │ │ │ └── mathops.h │ │ │ └── xvmc.h │ │ ├── libavdevice │ │ │ ├── avdevice.h │ │ │ └── version.h │ │ ├── libavfilter │ │ │ ├── asrc_abuffer.h │ │ │ ├── avcodec.h │ │ │ ├── avfilter.h │ │ │ ├── avfiltergraph.h │ │ │ ├── buffersink.h │ │ │ ├── buffersrc.h │ │ │ └── version.h │ │ ├── libavformat │ │ │ ├── avformat.h │ │ │ ├── avio.h │ │ │ ├── network.h │ │ │ ├── os_support.h │ │ │ ├── url.h │ │ │ └── version.h │ │ ├── libavresample │ │ │ ├── avresample.h │ │ │ └── version.h │ │ ├── libavutil │ │ │ ├── adler32.h │ │ │ ├── aes.h │ │ │ ├── attributes.h │ │ │ ├── audio_fifo.h │ │ │ ├── audioconvert.h │ │ │ ├── avassert.h │ │ │ ├── avconfig.h │ │ │ ├── avstring.h │ │ │ ├── avutil.h │ │ │ ├── base64.h │ │ │ ├── blowfish.h │ │ │ ├── bprint.h │ │ │ ├── bswap.h │ │ │ ├── buffer.h │ │ │ ├── camellia.h │ │ │ ├── cast5.h │ │ │ ├── channel_layout.h │ │ │ ├── common.h │ │ │ ├── cpu.h │ │ │ ├── crc.h │ │ │ ├── dict.h │ │ │ ├── display.h │ │ │ ├── downmix_info.h │ │ │ ├── error.h │ │ │ ├── eval.h │ │ │ ├── ffversion.h │ │ │ ├── fifo.h │ │ │ ├── file.h │ │ │ ├── frame.h │ │ │ ├── hash.h │ │ │ ├── hmac.h │ │ │ ├── imgutils.h │ │ │ ├── intfloat.h │ │ │ ├── intreadwrite.h │ │ │ ├── lfg.h │ │ │ ├── libm.h │ │ │ ├── log.h │ │ │ ├── lzo.h │ │ │ ├── macros.h │ │ │ ├── mathematics.h │ │ │ ├── md5.h │ │ │ ├── mem.h │ │ │ ├── motion_vector.h │ │ │ ├── murmur3.h │ │ │ ├── old_pix_fmts.h │ │ │ ├── opt.h │ │ │ ├── parseutils.h │ │ │ ├── pixdesc.h │ │ │ ├── pixelutils.h │ │ │ ├── pixfmt.h │ │ │ ├── random_seed.h │ │ │ ├── rational.h │ │ │ ├── replaygain.h │ │ │ ├── ripemd.h │ │ │ ├── samplefmt.h │ │ │ ├── sha.h │ │ │ ├── sha512.h │ │ │ ├── stereo3d.h │ │ │ ├── threadmessage.h │ │ │ ├── time.h │ │ │ ├── timecode.h │ │ │ ├── timestamp.h │ │ │ ├── twofish.h │ │ │ ├── version.h │ │ │ ├── x86 │ │ │ │ └── asm.h │ │ │ └── xtea.h │ │ ├── libpostproc │ │ │ ├── postprocess.h │ │ │ └── version.h │ │ ├── libswresample │ │ │ ├── swresample.h │ │ │ └── version.h │ │ └── libswscale │ │ │ ├── swscale.h │ │ │ └── version.h │ ├── prebuilt │ │ ├── armeabi │ │ │ ├── libavcodec-56.so │ │ │ ├── libavdevice-56.so │ │ │ ├── libavfilter-5.so │ │ │ ├── libavformat-56.so │ │ │ ├── libavutil-54.so │ │ │ ├── libswresample-1.so │ │ │ └── libswscale-3.so │ │ └── x86 │ │ │ ├── libavcodec-56.so │ │ │ ├── libavdevice-56.so │ │ │ ├── libavfilter-5.so │ │ │ ├── libavformat-56.so │ │ │ ├── libavutil-54.so │ │ │ ├── libswresample-1.so │ │ │ └── libswscale-3.so │ ├── show_func_wrapper.c │ ├── show_func_wrapper.h │ └── x86_config.h ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── cn │ │ └── dxjia │ │ └── ffmpeg │ │ └── library │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── cn │ │ │ └── dxjia │ │ │ └── ffmpeg │ │ │ └── library │ │ │ └── FFmpegNativeHelper.java │ └── res │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── cn │ └── dxjia │ └── ffmpeg │ └── library │ └── ExampleUnitTest.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | 15 | # Gradle files 16 | .gradle/ 17 | build/ 18 | 19 | # Local configuration file (sdk path, etc) 20 | local.properties 21 | 22 | # Proguard folder generated by Eclipse 23 | proguard/ 24 | 25 | # Log Files 26 | *.log 27 | 28 | # Android Studio Navigation editor temp files 29 | .navigation/ 30 | 31 | # Android Studio captures folder 32 | captures/ 33 | 34 | # Windoes thumbs file 35 | Thumbs.db 36 | 37 | # Idea 38 | .idea/ 39 | *.iml 40 | 41 | # keystore files 42 | *.keyset 43 | 44 | # DS_Store 45 | .DS_Store 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | `This is AS version`
2 | Eclipse version, please refer to [Old Eclipse Version](https://github.com/dxjia/ffmpeg-commands-executor-library/tree/master) 3 | # ffmpeg-commands-executor-library 4 | execute ffmpeg commands as a shared librar, you can try [example.apk](https://github.com/dxjia/ffmpeg-commands-executor-library/releases/download/v0.1.7/example-debug.apk) 5 |
[**Note**]: This library may not support all the codecs you want, for example, h264. 6 | 7 | # Usage 8 | add dependency in your build.gradle 9 | ``` 10 | dependencies { 11 | compile 'cn.dxjia:ffmpegexecutor:0.1.7' 12 | } 13 | ``` 14 | import package 15 | ``` 16 | import cn.dxjia.ffmpeg.library.FFmpegNativeHelper; 17 | ``` 18 | run command 19 | ``` 20 | FFmpegNativeHelper.runCommand("ffmpeg -version"); 21 | ``` 22 | 23 | **`NOTE:`** 24 | - now, runCommand() will return some strings as result, not very friendly; 25 | - this library modified some ffmpeg source code, invasion is relatively strong. 26 | 27 | # Compile library or example by yourself 28 | If you want to compile this library by yourself, you can do that as follow steps. 29 | ### Step 1 30 | Build jni manually 31 | #### Linux or Ubuntu 32 | ``` 33 | cd library/jni 34 | chmod a+x build.sh 35 | . build.sh 36 | ``` 37 | #### Windows 38 | Make sure you have add your NDK path to your PC Enviroment. 39 |
40 | Open a CMD terminal 41 | ``` 42 | cd library\jni 43 | build.cmd 44 | ``` 45 | ### Step 2 46 | Android Studio -> Open Existing Project 47 | 48 | ### Step 3 49 | modify code & build project 50 | 51 | **NOTE:** Every time you changed the jni source code, you need to build it manually before building the project from Android Studio. 52 | 53 | Any issues and PRs are welcome. 54 | 55 | # License 56 | ``` 57 | Copyright (c) 2015 dxjia 58 | 59 | Licensed under the Apache License, Version 2.0 (the "License"); 60 | you may not use this file except in compliance with the License. 61 | You may obtain a copy of the License at 62 | 63 | http://www.apache.org/licenses/LICENSE-2.0 64 | 65 | Unless required by applicable law or agreed to in writing, software 66 | distributed under the License is distributed on an "AS IS" BASIS, 67 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 68 | See the License for the specific language governing permissions and 69 | limitations under the License. 70 | ``` 71 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:2.1.2' 9 | 10 | // uncomment the follow 3 lines to do bintray upload 11 | //classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3' 12 | //classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.6' 13 | //classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.0.0" 14 | 15 | // NOTE: Do not place your application dependencies here; they belong 16 | // in the individual module build.gradle files 17 | } 18 | } 19 | 20 | allprojects { 21 | repositories { 22 | jcenter() 23 | } 24 | } 25 | 26 | task clean(type: Delete) { 27 | delete rootProject.buildDir 28 | } 29 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /example/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.2" 6 | 7 | defaultConfig { 8 | applicationId "cn.dxjia.ffmpegexecutor" 9 | minSdkVersion 7 10 | targetSdkVersion 22 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(include: ['*.jar'], dir: 'libs') 24 | testCompile 'junit:junit:4.12' 25 | compile project(':library') 26 | compile 'com.android.support:appcompat-v7:23.1.1' 27 | } 28 | -------------------------------------------------------------------------------- /example/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\android\android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /example/src/androidTest/java/cn/dxjia/ffmpegexecutor/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package cn.dxjia.ffmpeg.executor; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /example/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /example/src/main/java/cn/dxjia/ffmpegexecutor/MainActivity.java: -------------------------------------------------------------------------------- 1 | package cn.dxjia.ffmpegexecutor; 2 | 3 | import android.app.ProgressDialog; 4 | import android.os.AsyncTask; 5 | import android.os.Handler; 6 | import android.os.Message; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.os.Bundle; 9 | import android.text.TextUtils; 10 | import android.text.method.ScrollingMovementMethod; 11 | import android.view.View; 12 | import android.widget.EditText; 13 | import android.widget.TextView; 14 | 15 | import cn.dxjia.ffmpeg.library.FFmpegNativeHelper; 16 | 17 | public class MainActivity extends AppCompatActivity { 18 | 19 | private EditText mInputEdit; 20 | private TextView mResultBoard; 21 | private String mCurrentCommand; 22 | private AsyncTask mRunCommandAsyncTask; 23 | 24 | private static final int EVENT_SHOW_PROCESS_DIALOG = 0; 25 | private static final int EVENT_DISMISS_PROCESS_DIALOG = 1; 26 | private static ProgressDialog mWaitingDialog; 27 | private WaitingDialogHanlder mWaitingDialogHandler; 28 | 29 | //private static final String testCommand = "ffmpeg -i /sdcard/demo.mp4 -vframes 30 -y -f gif /sdcard/demoout.gif"; 30 | private static final String testCommand = "ffmpeg -h"; 31 | 32 | @Override 33 | protected void onCreate(Bundle savedInstanceState) { 34 | super.onCreate(savedInstanceState); 35 | setContentView(R.layout.activity_main); 36 | 37 | mInputEdit = (EditText) findViewById(R.id.command_input_edit); 38 | mResultBoard = (TextView) findViewById(R.id.result_board); 39 | mResultBoard.setMovementMethod(new ScrollingMovementMethod()); 40 | 41 | mRunCommandAsyncTask = null; 42 | 43 | mWaitingDialog = new ProgressDialog(this); 44 | mWaitingDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 45 | mWaitingDialog.setMessage("Waiting..."); 46 | 47 | mWaitingDialogHandler = new WaitingDialogHanlder(); 48 | 49 | 50 | findViewById(R.id.run_command_sync).setOnClickListener(new View.OnClickListener() { 51 | @Override 52 | public void onClick(View v) { 53 | runCommandSync(); 54 | } 55 | }); 56 | 57 | findViewById(R.id.run_command_async).setOnClickListener(new View.OnClickListener() { 58 | @Override 59 | public void onClick(View v) { 60 | runCommandAsync(); 61 | } 62 | }); 63 | } 64 | 65 | private void prepare() { 66 | clearResultBoard(); 67 | mCurrentCommand = mInputEdit.getText().toString(); 68 | if (TextUtils.isEmpty(mCurrentCommand)) { 69 | mCurrentCommand = testCommand; 70 | } 71 | mRunCommandAsyncTask = null; 72 | } 73 | 74 | // 同步运行命令, 阻塞 75 | private void runCommandSync() { 76 | prepare(); 77 | updateResultBoard(executeCommand(mCurrentCommand)); 78 | } 79 | 80 | /* 异步运行命令, 非阻塞 */ 81 | private void runCommandAsync() { 82 | prepare(); 83 | mRunCommandAsyncTask = new AsyncTask() { 84 | @Override 85 | protected String doInBackground(String... strings) { 86 | String command; 87 | if (strings != null && strings.length > 0) { 88 | command = strings[0]; 89 | } else { 90 | return "Must input command!"; 91 | } 92 | 93 | return executeCommand(command); 94 | } 95 | 96 | @Override 97 | protected void onPostExecute(String s) { 98 | super.onPostExecute(s); 99 | // we got result, dismiss waiting dialog 100 | mWaitingDialogHandler.removeMessages(EVENT_SHOW_PROCESS_DIALOG); 101 | mWaitingDialogHandler.sendEmptyMessage(EVENT_DISMISS_PROCESS_DIALOG); 102 | updateResultBoard(s); 103 | } 104 | }; 105 | 106 | mRunCommandAsyncTask.execute(mCurrentCommand); 107 | 108 | // if we can`t get result after 300ms, show the waiting dialog 109 | mWaitingDialogHandler.sendEmptyMessageDelayed(EVENT_SHOW_PROCESS_DIALOG, 300); 110 | 111 | } 112 | 113 | private String executeCommand(String command) { 114 | return FFmpegNativeHelper.runCommand(command); 115 | } 116 | 117 | private void clearResultBoard() { 118 | mResultBoard.setText(""); 119 | mResultBoard.scrollTo(0, 0); 120 | } 121 | 122 | private void updateResultBoard(String message) { 123 | if (message == null || message.length() == 0) { 124 | return; 125 | } 126 | String currentStr = mResultBoard.getText().toString(); 127 | mResultBoard.setText(currentStr + "\n" + message); 128 | } 129 | 130 | private static class WaitingDialogHanlder extends Handler { 131 | @Override 132 | public void handleMessage(Message msg) { 133 | super.handleMessage(msg); 134 | switch (msg.what) { 135 | case EVENT_SHOW_PROCESS_DIALOG: 136 | mWaitingDialog.show(); 137 | break; 138 | case EVENT_DISMISS_PROCESS_DIALOG: 139 | mWaitingDialog.dismiss(); 140 | break; 141 | default: return; 142 | } 143 | } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /example/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 20 | 28 | 29 |