├── .gitignore
├── LICENSE
├── README.md
├── build.gradle
├── docs
└── ffmpeg_return_codes.txt
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── sample
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── ffmpeg
│ │ └── videokit
│ │ └── sample
│ │ ├── MainActivity.java
│ │ ├── Model.java
│ │ ├── VideoListAdapter.java
│ │ ├── VideoListItem.java
│ │ └── VideoListViewHolder.java
│ └── res
│ ├── layout
│ ├── activity_main.xml
│ └── video_item.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-v21
│ └── styles.xml
│ ├── values-w820dp
│ └── dimens.xml
│ └── values
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── settings.gradle
└── videokit
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
├── main
├── AndroidManifest.xml
├── java
│ └── processing
│ │ └── ffmpeg
│ │ └── videokit
│ │ ├── AsyncCommandExecutor.java
│ │ ├── Command.java
│ │ ├── CommandBuilder.java
│ │ ├── LogLevel.java
│ │ ├── ProcessingListener.java
│ │ ├── VideoCommand.java
│ │ ├── VideoCommandBuilder.java
│ │ ├── VideoKit.java
│ │ └── VideoProcessingResult.java
├── jniLibs
│ ├── arm64-v8a
│ │ ├── libavcodec.so
│ │ ├── libavdevice.so
│ │ ├── libavfilter.so
│ │ ├── libavformat.so
│ │ ├── libavutil.so
│ │ ├── libswresample.so
│ │ ├── libswscale.so
│ │ └── libvideokit.so
│ ├── armeabi-v7a
│ │ ├── libavcodec.so
│ │ ├── libavdevice.so
│ │ ├── libavfilter.so
│ │ ├── libavformat.so
│ │ ├── libavutil.so
│ │ ├── libswresample.so
│ │ ├── libswscale.so
│ │ └── libvideokit.so
│ ├── armeabi
│ │ ├── libavcodec.so
│ │ ├── libavdevice.so
│ │ ├── libavfilter.so
│ │ ├── libavformat.so
│ │ ├── libavutil.so
│ │ ├── libswresample.so
│ │ ├── libswscale.so
│ │ └── libvideokit.so
│ ├── x86
│ │ ├── libavcodec.so
│ │ ├── libavdevice.so
│ │ ├── libavfilter.so
│ │ ├── libavformat.so
│ │ ├── libavutil.so
│ │ ├── libswresample.so
│ │ ├── libswscale.so
│ │ └── libvideokit.so
│ └── x86_64
│ │ ├── libavcodec.so
│ │ ├── libavdevice.so
│ │ ├── libavfilter.so
│ │ ├── libavformat.so
│ │ ├── libavutil.so
│ │ ├── libswresample.so
│ │ ├── libswscale.so
│ │ └── libvideokit.so
└── res
│ └── values
│ └── strings.xml
└── test
├── java
└── processing
│ └── ffmpeg
│ └── videokit
│ ├── CommandBuilderTest.java
│ └── CommandTest.java
└── resources
└── test
/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | /captures
3 | #Gradle
4 | .gradle
5 | build
6 | result
7 |
8 | #Mac OS
9 | .DS_Store
10 |
11 | # built application files
12 | *.apk
13 | *.ap_
14 |
15 | # files for the dex VM
16 | *.dex
17 |
18 | # Java class files
19 | *.class
20 |
21 | # generated files
22 | bin/
23 | gen/
24 |
25 | # Local configuration file (sdk path, etc)
26 | local.properties
27 |
28 | # Eclipse project files
29 | .classpath
30 | .project
31 |
32 | # Proguard folder generated by Eclipse
33 | proguard/
34 |
35 | # Intellij project files
36 | *.iml
37 | *.ipr
38 | *.iws
39 | .idea/
40 | tools/*.txt
41 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Video processing library based on FFmpeg
2 | ## Main purpose
3 | Main purpose of this library is to allow developers to embed FFmpeg into their application with literally one line of code
4 | in gradle.build. Using native code in Java in general and in Android environment especially always related to some problems.
5 | Hopefully VideoKit will resolve some of them.
6 |
7 | ## Setup
8 | Basic setup just add following line of code to your gradle.build file:
9 | `compile 'com.infullmobile.android:videokit-release:1.1.2'`
10 | Also, if you haven't use inFullMobile public maven in your project before, don't forget to add following line to your
11 | repositories:
12 | `maven { url 'https://maven.infullmobile.com/public' }`
13 | That's pretty much all.
14 |
15 | ## Example usage
16 | Module sample is showing usage of VideoKit. Please note, that VideoKit is basically invoking FFmpeg main() with CLI arguments
17 | so you will use commands almost like you use standard FFmpeg on Linux or Windows or MacOS.
18 | Well, let me show you some code:
19 | ```
20 | final VideoKit videoKit = new VideoKit();
21 | final Command command = videoKit.createCommand()
22 | .overwriteOutput()
23 | .inputPath(path)
24 | .outputPath(path + POSTFIX)
25 | .customCommand("-ss 1 -t 3")
26 | .copyVideoCodec()
27 | .experimentalFlag()
28 | .build();
29 | ```
30 | Command is basically set of instructions for FFmpeg. Please note, that order in which you adding instructions in
31 | CommandBuilder is quite important. Sometimes, when you mess up order, FFmpeg will not recognize command and end up
32 | with error. After you've built a command you should execute it: either with execute() or you can pass it to
33 | AsyncCommandExecutor.
34 | Please note, that:
35 | `command.execute();`
36 | will be executed on thread on which it was called, while:
37 | `new AsyncCommandExecutor(command, this).execute();`
38 | will be executed in background thread and you have to provide implementation of ProcessingListener to get result of
39 | processing either in onSuccess (you will get path to processed file here) or onFailure (you will get error code here).
40 |
41 | ## Other functions
42 | VideoKit is also providing logging mechanism for FFmpeg. You can set logging level by calling function:
43 | `videoKit.setLogLevel(level)`
44 | where level is enum which consists of:
45 | ```
46 | NO_LOG
47 | ERRORS_ONLY
48 | FULL
49 | ```
50 |
51 | ## Specific behavior of flags
52 | As I already have mentioned: FFmpeg is quite sensible to the order of flags. To help out with that
53 | to user VideoKit have default behavior for particular flags, namely: input paths, output path and experimental flag.
54 | The order in which VideoKit is laying those flags is following:
55 |
56 | 1. Input paths are always going first (doesn't matter in which place of chain you have added particular path)
57 | 2. Output path is always going at the end of command
58 | 3. Experimental flag is always just before output path
59 |
60 | ## Error codes
61 | I've tried to make library as debuggable as it even possible, taking in account that we're working with native code.
62 | If you getting failures from VideoKit and log in not really helpfull try to look into *docs* folder in *ffmpeg_return_codes*
63 | file. In this file you not only have list of possible return codes with which FFMpeg can exit, but also file and number of
64 | line of code in which exit was called.
65 | Version of FFmpeg is 3.2.4 and changed sources can be found over here:
66 | [Development Kit](https://github.com/IljaKosynkin/FFmpeg-Development-Kit)
67 |
68 | ## License
69 | FFmpeg is licensed under LGPL:
70 | [License](https://ffmpeg.org/legal.html)
71 | **This software uses libraries from the FFmpeg project under the LGPLv2.1**
72 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | dependencies {
3 | repositories {
4 | jcenter()
5 | mavenCentral()
6 | }
7 | classpath 'com.android.tools.build:gradle:2.2.3'
8 | }
9 | }
10 |
11 | allprojects {
12 | repositories {
13 | jcenter()
14 | mavenLocal()
15 | }
16 | }
17 |
18 | task clean(type: Delete) {
19 | delete rootProject.buildDir
20 | }
21 |
--------------------------------------------------------------------------------
/docs/ffmpeg_return_codes.txt:
--------------------------------------------------------------------------------
1 | This file contains corresponding codes to each specified source file. Every file have assigned leading code from 1 to N and MMM sub-code according to error.
2 | Also every code have according to it number of line.
3 |
4 | CMDUTILS.C LEAD CODE: 1
5 | Code: 1000, line: 120
6 | Code: 1001, line: 140
7 | Code: 1002, line: 151
8 | Code: 1003, line: 325
9 | Code: 1004, line: 385
10 | Code: 1005, line: 693
11 | Code: 1006, line: 892
12 | Code: 1007, line: 960
13 | Code: 1008, line: 1010
14 | Code: 1009, line: 1403
15 | Code: 1010, line: 1970
16 | Code: 1011, line: 2014
17 | Code: 1012, line: 2020
18 |
19 | FFMPEG.C LEAD CODE: 2
20 | Code: 2000, line: 333
21 | Code: 2001, line: 601
22 | Code: 2002, line: 607
23 | Code: 2003, line: 720
24 | Code: 2004, line: 728
25 | Code: 2005, line: 759
26 | Code: 2006, line: 851
27 | Code: 2007, line: 883
28 | Code: 2008, line: 893
29 | Code: 2009, line: 932
30 | Code: 2010, line: 1202
31 | Code: 2011, line: 1271
32 | Code: 2012, line: 1755
33 | Code: 2013, line: 1883
34 | Code: 2014, line: 1888
35 | Code: 2015, line: 1904
36 | Code: 2016, line: 1960
37 | Code: 2017, line: 1988
38 | Code: 2018, line: 2015
39 | Code: 2019, line: 2100
40 | Code: 2020, line: 2169
41 | Code: 2021, line: 2192
42 | Code: 2022, line: 2212
43 | Code: 2023, line: 2364
44 | Code: 2024, line: 2390
45 | Code: 2025, line: 2442
46 | Code: 2026, line: 2639
47 | Code: 2027, line: 2673
48 | Code: 2028, line: 2693
49 | Code: 2029, line: 2767
50 | Code: 2030, line: 2959
51 | Code: 2031, line: 3005
52 | Code: 2032, line: 3027
53 | Code: 2033, line: 3143
54 | Code: 2034, line: 3653
55 | Code: 2035, line: 3761
56 | Code: 2036, line: 4149
57 | Code: 2037, line: 4154
58 | Code: 2038, line: 4160
59 | Code: 2039, line: 4165
60 | Code: 2040, line: 4170
61 | Code: 2041, line: 4178
62 |
63 | FFMPEG_OPT.C LEAD CODE: 3
64 | Code: 3000, line: 55
65 | Code: 3001, line: 268
66 | Code: 3002, line: 281
67 | Code: 3003, line: 294
68 | Code: 3004, line: 302
69 | Code: 3005, line: 341
70 | Code: 3006, line: 384
71 | Code: 3007, line: 394
72 | Code: 3008, line: 400
73 | Code: 3009, line: 406
74 | Code: 3010, line: 411
75 | Code: 3011, line: 440
76 | Code: 3012, line: 451
77 | Code: 3013, line: 494
78 | Code: 3014, line: 525
79 | Code: 3015, line: 529
80 | Code: 3016, line: 539
81 | Code: 3017, line: 582
82 | Code: 3018, line: 586
83 | Code: 3019, line: 621
84 | Code: 3020, line: 656
85 | Code: 3021, line: 664
86 | Code: 3022, line: 670
87 | Code: 3023, line: 692
88 | Code: 3024, line: 720
89 | Code: 3025, line: 729
90 | Code: 3026, line: 755
91 | Code: 3027, line: 763
92 | Code: 3028, line: 772
93 | Code: 3029, line: 785
94 | Code: 3030, line: 791
95 | Code: 3031, line: 813
96 | Code: 3032, line: 821
97 | Code: 3033, line: 849
98 | Code: 3034, line: 863
99 | Code: 3035, line: 928
100 | Code: 3036, line: 950
101 | Code: 3037, line: 996
102 | Code: 3038, line: 1038
103 | Code: 3039, line: 1078
104 | Code: 3040, line: 1144
105 | Code: 3041, line: 1152
106 | Code: 3042, line: 1164
107 | Code: 3043, line: 1184
108 | Code: 3044, line: 1196
109 | Code: 3045, line: 1224
110 | Code: 3046, line: 1287
111 | Code: 3047, line: 1330
112 | Code: 3048, line: 1352
113 | Code: 3049, line: 1370
114 | Code: 3050, line: 1381
115 | Code: 3051, line: 1401
116 | Code: 3052, line: 1413
117 | Code: 3053, line: 1423
118 | Code: 3054, line: 1432
119 | Code: 3055, line: 1441
120 | Code: 3056, line: 1452
121 | Code: 3057, line: 1459
122 | Code: 3058, line: 1495
123 | Code: 3059, line: 1514
124 | Code: 3060, line: 1524
125 | Code: 3061, line: 1543
126 | Code: 3062, line: 1579
127 | Code: 3063, line: 1589
128 | Code: 3064, line: 1613
129 | Code: 3065, line: 1634
130 | Code: 3066, line: 1647
131 | Code: 3067, line: 1681
132 | Code: 3068, line: 1702
133 | Code: 3069, line: 1815
134 | Code: 3070, line: 1827
135 | Code: 3071, line: 1839
136 | Code: 3072, line: 1889
137 | Code: 3073, line: 1898
138 | Code: 3074, line: 1914
139 | Code: 3075, line: 1948
140 | Code: 3076, line: 1960
141 | Code: 3077, line: 1978
142 | Code: 3078, line: 2087
143 | Code: 3079, line: 2124
144 | Code: 3080, line: 2144
145 | Code: 3081, line: 2149
146 | Code: 3082, line: 2154
147 | Code: 3083, line: 2178
148 | Code: 3084, line: 2184
149 | Code: 3085, line: 2213
150 | Code: 3086, line: 2244
151 | Code: 3087, line: 2251
152 | Code: 3088, line: 2263
153 | Code: 3089, line: 2280
154 | Code: 3090, line: 2300
155 | Code: 3091, line: 2341
156 | Code: 3092, line: 2366
157 | Code: 3093, line: 2377
158 | Code: 3094, line: 2383
159 | Code: 3095, line: 2438
160 | Code: 3096, line: 2550
161 | Code: 3097, line: 2612
162 | Code: 3098, line: 2624
163 | Code: 3099, line: 2635
164 |
165 | FFMPEG_FILTER.C LEAD CODE: 4
166 | Code: 4000, line: 125
167 | Code: 4001, line: 163
168 | Code: 4002, line: 193
169 | Code: 4003, line: 198
170 | Code: 4004, line: 206
171 | Code: 4005, line: 229
172 | Code: 4006, line: 241
173 | Code: 4007, line: 259
174 | Code: 4008, line: 273
175 | Code: 4009, line: 284
176 | Code: 4010, line: 315
177 | Code: 4011, line: 636
178 | Code: 4012, line: 652
179 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Oct 03 06:57:42 CEST 2016
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/sample/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/sample/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 25
5 | buildToolsVersion "25.0.2"
6 |
7 | defaultConfig {
8 | applicationId "ffmpeg.videokit.sample"
9 | minSdkVersion 10
10 | targetSdkVersion 25
11 | versionCode 3
12 | versionName "1.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 'com.android.support:appcompat-v7:25.1.1'
26 | compile 'com.android.support:design:25.1.1'
27 | compile project(':videokit')
28 | //compile 'com.infullmobile.android:videokit-release:1.1.0'
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/sample/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 /Users/Ilja/Downloads/android-sdk-macosx/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 |
--------------------------------------------------------------------------------
/sample/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
13 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/sample/src/main/java/ffmpeg/videokit/sample/MainActivity.java:
--------------------------------------------------------------------------------
1 | package ffmpeg.videokit.sample;
2 |
3 | import android.Manifest;
4 | import android.app.ProgressDialog;
5 | import android.content.Intent;
6 | import android.content.pm.PackageManager;
7 | import android.os.Bundle;
8 | import android.support.design.widget.Snackbar;
9 | import android.support.v4.app.ActivityCompat;
10 | import android.support.v4.content.ContextCompat;
11 | import android.support.v7.app.AppCompatActivity;
12 | import android.support.v7.widget.GridLayoutManager;
13 | import android.support.v7.widget.RecyclerView;
14 | import android.util.Log;
15 | import android.view.View;
16 |
17 | import processing.ffmpeg.videokit.AsyncCommandExecutor;
18 | import processing.ffmpeg.videokit.Command;
19 | import processing.ffmpeg.videokit.ProcessingListener;
20 | import processing.ffmpeg.videokit.VideoKit;
21 | import video_processing.ffmpeg.testing.R;
22 | /**
23 | * Created by Ilja Kosynkin on 07.07.2016.
24 | * Copyright by inFullMobile
25 | */
26 | public class MainActivity extends AppCompatActivity implements VideoListAdapter.Callback, ProcessingListener {
27 | private static final String POSTFIX = "_p.mp4";
28 | private static final int SPAN_COUNT = 3;
29 | private static final int REQUEST_CODE = 1337;
30 |
31 | private VideoKit videoKit = new VideoKit();
32 |
33 | private ProgressDialog progressDialog;
34 | private View rootView;
35 | private Model model;
36 |
37 | @Override
38 | protected void onCreate(Bundle savedInstanceState) {
39 | super.onCreate(savedInstanceState);
40 |
41 | setContentView(R.layout.activity_main);
42 |
43 | rootView = findViewById(android.R.id.content);
44 | model = new Model(this);
45 |
46 | Log.d("ARCHITECTURE", System.getProperty("os.arch"));
47 |
48 | setupDialog();
49 | setupListIfWritePermissionGranted();
50 | }
51 |
52 | @Override
53 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
54 | super.onActivityResult(requestCode, resultCode, data);
55 |
56 | if (requestCode == REQUEST_CODE) {
57 | setupList();
58 | }
59 | }
60 |
61 | private void setupDialog() {
62 | progressDialog = new ProgressDialog(this);
63 | progressDialog.setMessage(getString(R.string.processing_message));
64 | progressDialog.setCancelable(false);
65 | }
66 |
67 | private void setupListIfWritePermissionGranted() {
68 | if (ContextCompat.checkSelfPermission(this,
69 | Manifest.permission.WRITE_EXTERNAL_STORAGE)
70 | != PackageManager.PERMISSION_GRANTED) {
71 |
72 | ActivityCompat.requestPermissions(this,
73 | new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
74 | REQUEST_CODE);
75 | } else {
76 | setupList();
77 | }
78 | }
79 |
80 | @SuppressWarnings("ConstantConditions")
81 | private void setupList() {
82 | final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.gallery);
83 |
84 | final VideoListAdapter adapter = new VideoListAdapter();
85 | adapter.setCallback(this);
86 |
87 | recyclerView.setAdapter(adapter);
88 | recyclerView.setLayoutManager(new GridLayoutManager(this, SPAN_COUNT));
89 |
90 | adapter.setData(model.getVideos());
91 | }
92 |
93 | @Override
94 | public void onDestroy() {
95 | super.onDestroy();
96 | progressDialog.dismiss();
97 | }
98 |
99 | @Override
100 | public void onMediaFileSelected(String path) {
101 | progressDialog.show();
102 |
103 | final Command command = videoKit.createCommand()
104 | .overwriteOutput()
105 | .inputPath(path)
106 | .outputPath(path + POSTFIX)
107 | .customCommand("-ss 1 -t 3")
108 | .copyVideoCodec()
109 | .experimentalFlag()
110 | .build();
111 |
112 | new AsyncCommandExecutor(command, this).execute();
113 | }
114 |
115 | @Override
116 | public void onSuccess(String path) {
117 | progressDialog.dismiss();
118 | Snackbar.make(rootView, R.string.success_message, Snackbar.LENGTH_LONG).show();
119 | }
120 |
121 | @Override
122 | public void onFailure(int returnCode) {
123 | progressDialog.dismiss();
124 | Snackbar.make(rootView, R.string.failure_message, Snackbar.LENGTH_LONG).show();
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/sample/src/main/java/ffmpeg/videokit/sample/Model.java:
--------------------------------------------------------------------------------
1 | package ffmpeg.videokit.sample;
2 |
3 | import android.content.Context;
4 | import android.database.Cursor;
5 | import android.media.MediaMetadataRetriever;
6 | import android.net.Uri;
7 | import android.provider.MediaStore;
8 |
9 | import java.io.File;
10 | import java.util.ArrayList;
11 | import java.util.List;
12 |
13 | /**
14 | * Created by Ilja Kosynkin on 07.07.2016.
15 | * Copyright by inFullMobile
16 | */
17 | class Model {
18 | private static final MediaMetadataRetriever retriever = new MediaMetadataRetriever();
19 |
20 | private final Context context;
21 |
22 | Model(Context context) {
23 | this.context = context.getApplicationContext();
24 | }
25 |
26 | List getVideos() {
27 | final Cursor cursor = getMedia();
28 |
29 | final List videos = new ArrayList<>();
30 | while (cursor.moveToNext()) {
31 | int colIndex = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
32 | final String path = cursor.getString(colIndex);
33 |
34 | if (new File(path).exists()) {
35 | final String time = getVideoDuration(path);
36 |
37 | if (time != null) {
38 | final VideoListItem videoListItem = new VideoListItem();
39 |
40 | colIndex = cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID);
41 | videoListItem.videoId = cursor.getInt(colIndex);
42 | videoListItem.videoPath = path;
43 |
44 | videos.add(videoListItem);
45 | }
46 | }
47 | }
48 |
49 | return videos;
50 | }
51 |
52 | private Cursor getMedia() {
53 | final Uri externalContentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
54 | final String mediaConditionTag = MediaStore.Video.Media.DATE_ADDED;
55 |
56 | final String[] projection = {
57 | MediaStore.Video.Media._ID,
58 | MediaStore.Video.Media.DATA
59 | };
60 | return context.getContentResolver().query(
61 | externalContentUri, projection,
62 | null, null, mediaConditionTag + " DESC ");
63 | }
64 |
65 | private String getVideoDuration(String path) {
66 | try {
67 | retriever.setDataSource(path);
68 | return retriever.
69 | extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
70 | } catch (IllegalArgumentException e) {
71 | return null;
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/sample/src/main/java/ffmpeg/videokit/sample/VideoListAdapter.java:
--------------------------------------------------------------------------------
1 | package ffmpeg.videokit.sample;
2 |
3 | import android.support.annotation.NonNull;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.util.Log;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 |
10 | import java.util.ArrayList;
11 | import java.util.List;
12 |
13 | import video_processing.ffmpeg.testing.R;
14 |
15 | /**
16 | * Created by Ilja Kosynkin on 07.07.2016.
17 | * Copyright by inFullMobile
18 | */
19 | class VideoListAdapter extends RecyclerView.Adapter
20 | implements VideoListViewHolder.Callbacks {
21 |
22 | private Callback callback = Callback.EMPTY;
23 | private List videoListItems = new ArrayList<>();
24 |
25 | @Override
26 | public int getItemCount() {
27 | return videoListItems.size();
28 | }
29 |
30 | @Override
31 | public VideoListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
32 | final View view = LayoutInflater.from(parent.getContext())
33 | .inflate(R.layout.video_item, parent, false);
34 | return new VideoListViewHolder(view);
35 | }
36 |
37 | @Override
38 | public void onBindViewHolder(VideoListViewHolder holder, int position) {
39 | final VideoListItem mediaFile = videoListItems.get(position);
40 | holder.bind(mediaFile, this);
41 | }
42 |
43 | void setData(List videos) {
44 | videoListItems = videos;
45 | notifyDataSetChanged();
46 | }
47 |
48 | void setCallback(Callback callback) {
49 | this.callback = callback == null ? Callback.EMPTY : callback;
50 | }
51 |
52 | @Override
53 | public void onMediaSelected(@NonNull VideoListItem videoListItem) {
54 | callback.onMediaFileSelected(videoListItem.videoPath);
55 | }
56 |
57 | interface Callback {
58 | void onMediaFileSelected(String path);
59 |
60 | Callback EMPTY = new Callback() {
61 | @Override
62 | public void onMediaFileSelected(String path) { }
63 | };
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/sample/src/main/java/ffmpeg/videokit/sample/VideoListItem.java:
--------------------------------------------------------------------------------
1 | package ffmpeg.videokit.sample;
2 |
3 | /**
4 | * Created by Ilja Kosynkin on 07.07.2016.
5 | * Copyright by inFullMobile
6 | */
7 | class VideoListItem {
8 | int videoId;
9 | String videoPath;
10 | }
11 |
--------------------------------------------------------------------------------
/sample/src/main/java/ffmpeg/videokit/sample/VideoListViewHolder.java:
--------------------------------------------------------------------------------
1 | package ffmpeg.videokit.sample;
2 |
3 | import android.graphics.Bitmap;
4 | import android.provider.MediaStore;
5 | import android.support.annotation.NonNull;
6 | import android.support.v7.widget.RecyclerView;
7 | import android.view.View;
8 | import android.widget.ImageView;
9 |
10 | import video_processing.ffmpeg.testing.R;
11 |
12 | /**
13 | * Created by Ilja Kosynkin on 07.07.2016.
14 | * Copyright by inFullMobile
15 | */
16 | class VideoListViewHolder extends RecyclerView.ViewHolder {
17 | private final ImageView image;
18 |
19 | VideoListViewHolder(View itemView) {
20 | super(itemView);
21 | image = (ImageView) itemView.findViewById(R.id.image);
22 | }
23 |
24 | void bind(final VideoListItem videoListItem, final Callbacks callbacks) {
25 | if (videoListItem != null) {
26 | final Bitmap thumbnail = MediaStore.Video.Thumbnails.getThumbnail(
27 | itemView.getContext().getContentResolver(), videoListItem.videoId,
28 | MediaStore.Video.Thumbnails.MINI_KIND, null);
29 |
30 | image.setImageBitmap(thumbnail);
31 |
32 | itemView.setOnClickListener(new View.OnClickListener() {
33 | @Override
34 | public void onClick(View v) {
35 | callbacks.onMediaSelected(videoListItem);
36 | }
37 | });
38 | }
39 | }
40 |
41 | interface Callbacks {
42 | void onMediaSelected(@NonNull VideoListItem videoListItem);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/video_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
19 |
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/sample/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/sample/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/sample/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
--------------------------------------------------------------------------------
/sample/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 16dp
6 |
7 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | VideoKit Test
3 | Great success!
4 | Epic fail!
5 | Please, wait, while video processing is going
6 |
7 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':videokit', ':sample'
2 |
--------------------------------------------------------------------------------
/videokit/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/videokit/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'maven-publish'
3 |
4 | repositories {
5 | mavenCentral()
6 | }
7 | group 'com.infullmobile.android'
8 | version '1.1.2'
9 |
10 | task sourceJar(type: Jar) {
11 | from android.sourceSets.main.java.srcDirs
12 | classifier "sources"
13 | }
14 |
15 | publishing {
16 | publications {
17 | maven(MavenPublication) {
18 | groupId project.group
19 | artifactId "videokit-release"
20 | version project.version
21 |
22 | artifact sourceJar
23 | artifact("$buildDir/outputs/aar/videokit-release.aar")
24 |
25 | pom.withXml {
26 | asNode().appendNode('description', 'Library for video processing based on FFmpeg.')
27 | }
28 | }
29 | }
30 | repositories {
31 | maven {
32 | name "iFMPrivateRelease"
33 | url "s3://maven-ifm-internal/private"
34 | credentials(AwsCredentials) {
35 | accessKey project.getMavenAccessKey()
36 | secretKey project.getMavenSecretKey()
37 | }
38 | }
39 | maven {
40 | name "iFMPublicRelease"
41 | url "s3://maven-ifm-internal/public"
42 | credentials(AwsCredentials) {
43 | accessKey project.getMavenAccessKey()
44 | secretKey project.getMavenSecretKey()
45 | }
46 | }
47 | }
48 | }
49 |
50 | ext {
51 | getMavenSecretKey = {
52 | return project.hasProperty('mavenSecretKey') ? project['mavenSecretKey'] : ""
53 | }
54 | getMavenAccessKey = {
55 | return project.hasProperty('mavenAccessKey') ? project['mavenAccessKey'] : ""
56 | }
57 | }
58 |
59 | task("publishIFMPrivate", dependsOn: "publishMavenPublicationToIFMPrivateReleaseRepository") {
60 | group "publishing"
61 | description "Uploads artifacts to inFullMobile private maven repository"
62 | }
63 |
64 | task("publishIFMPublic", dependsOn: "publishMavenPublicationToIFMPublicReleaseRepository") {
65 | group "publishing"
66 | description "Uploads artifacts to inFullMobile public maven repository"
67 | }
68 |
69 | android {
70 | compileSdkVersion 25
71 | buildToolsVersion "25.0.2"
72 |
73 | defaultConfig {
74 | minSdkVersion 10
75 | targetSdkVersion 25
76 | versionCode 3
77 | versionName "1.1.2"
78 | }
79 |
80 | testOptions {
81 | unitTests.returnDefaultValues = true
82 | }
83 |
84 | buildTypes {
85 | release {
86 | minifyEnabled false
87 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
88 | }
89 | }
90 |
91 | splits {
92 | abi {
93 | enable true
94 | reset()
95 | include 'x86', 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
96 | universalApk true
97 | }
98 | }
99 | }
100 |
101 | dependencies {
102 | compile fileTree(include: ['*.jar'], dir: 'libs')
103 |
104 | testCompile 'junit:junit:4.12'
105 | testCompile 'org.mockito:mockito-core:1.10.19'
106 | }
107 |
108 |
--------------------------------------------------------------------------------
/videokit/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\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 |
--------------------------------------------------------------------------------
/videokit/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/videokit/src/main/java/processing/ffmpeg/videokit/AsyncCommandExecutor.java:
--------------------------------------------------------------------------------
1 | package processing.ffmpeg.videokit;
2 |
3 | import java.lang.ref.WeakReference;
4 |
5 | /**
6 | * Created by Ilja Kosynkin on 19.07.16.
7 | * Copyright by inFullMobile
8 | */
9 | public class AsyncCommandExecutor {
10 | private final WeakReference listenerWeakReference;
11 | private final Command command;
12 |
13 | private final Runnable executionRunnable = new Runnable() {
14 | @Override
15 | public void run() {
16 | final VideoProcessingResult result = command.execute();
17 |
18 | final ProcessingListener listener = listenerWeakReference.get();
19 | if (listener != null) {
20 | if (result.isSuccessful()) {
21 | listener.onSuccess(result.getPath());
22 | } else {
23 | listener.onFailure(result.getCode());
24 | }
25 | }
26 | }
27 | };
28 |
29 | public AsyncCommandExecutor(Command command, ProcessingListener listener) {
30 | this.command = command;
31 | this.listenerWeakReference = new WeakReference<>(listener);
32 | }
33 |
34 | public void execute() {
35 | final Thread thread = new Thread(executionRunnable);
36 | thread.start();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/videokit/src/main/java/processing/ffmpeg/videokit/Command.java:
--------------------------------------------------------------------------------
1 | package processing.ffmpeg.videokit;
2 |
3 | /**
4 | * Created by Ilja Kosynkin on 29.07.16.
5 | * Copyright by inFullMobile
6 | */
7 | public interface Command {
8 | VideoProcessingResult execute();
9 | }
10 |
--------------------------------------------------------------------------------
/videokit/src/main/java/processing/ffmpeg/videokit/CommandBuilder.java:
--------------------------------------------------------------------------------
1 | package processing.ffmpeg.videokit;
2 |
3 | /**
4 | * Created by Ilja Kosynkin on 19.07.16.
5 | * Copyright by inFullMobile
6 | */
7 | @SuppressWarnings("unused")
8 | public interface CommandBuilder {
9 | CommandBuilder overwriteOutput();
10 | CommandBuilder inputPath(String inputFilePath);
11 | CommandBuilder outputPath(String outputPath);
12 | CommandBuilder trimForDuration(int startPosition, int duration);
13 | CommandBuilder withoutAudio();
14 | CommandBuilder copyVideoCodec();
15 | CommandBuilder crop(int x, int y, int width, int height);
16 | CommandBuilder customCommand(String customCommand);
17 | CommandBuilder limitVideoBitrate(String bitrate);
18 | CommandBuilder experimentalFlag();
19 | CommandBuilder limitFrameRate(int framerate);
20 | CommandBuilder fastTune();
21 | Command build();
22 | }
23 |
--------------------------------------------------------------------------------
/videokit/src/main/java/processing/ffmpeg/videokit/LogLevel.java:
--------------------------------------------------------------------------------
1 | package processing.ffmpeg.videokit;
2 |
3 | /**
4 | * Created by Ilja Kosynkin on 12.07.2016.
5 | * Copyright by inFullMobile
6 | */
7 | @SuppressWarnings("unused")
8 | public enum LogLevel {
9 | NO_LOG(0), ERRORS_ONLY(1), FULL(2);
10 |
11 | private final int integerValue;
12 |
13 | LogLevel(int value) {
14 | integerValue = value;
15 | }
16 |
17 | public int getValue() {
18 | return integerValue;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/videokit/src/main/java/processing/ffmpeg/videokit/ProcessingListener.java:
--------------------------------------------------------------------------------
1 | package processing.ffmpeg.videokit;
2 |
3 | /**
4 | * Created by Ilja Kosynkin on 06.07.2016.
5 | * Copyright by inFullMobile
6 | */
7 | public interface ProcessingListener {
8 | void onSuccess(String path);
9 | void onFailure(int returnCode);
10 | }
11 |
--------------------------------------------------------------------------------
/videokit/src/main/java/processing/ffmpeg/videokit/VideoCommand.java:
--------------------------------------------------------------------------------
1 | package processing.ffmpeg.videokit;
2 |
3 | import java.io.File;
4 | import java.util.List;
5 |
6 | /**
7 | * Created by Ilja Kosynkin on 25.07.16.
8 | * Copyright by inFullMobile
9 | */
10 | class VideoCommand implements Command {
11 | private static final String FFMPEG_PROGRAM_NAME = "ffmpeg";
12 |
13 | private final List arguments;
14 | private final String outputPath;
15 | private final VideoKit videoKit;
16 |
17 | VideoCommand(List flags, String outputPath, VideoKit videoKit) {
18 | this.arguments = flags;
19 | this.outputPath = outputPath;
20 | this.videoKit = videoKit;
21 |
22 | }
23 |
24 | @Override
25 | public VideoProcessingResult execute() {
26 | final int returnCode = videoKit.process(getArgumentsAsArray());
27 | if (returnCode == VideoProcessingResult.SUCCESSFUL_RESULT) {
28 | return new VideoProcessingResult(returnCode, outputPath);
29 | } else {
30 | deleteOutput();
31 | return new VideoProcessingResult(returnCode, null);
32 | }
33 | }
34 |
35 | private String[] getArgumentsAsArray() {
36 | final String ffmpegArguments[] = new String[arguments.size() + 1];
37 | for (int i = 0; i < arguments.size(); i++) {
38 | ffmpegArguments[i + 1] = arguments.get(i);
39 | }
40 |
41 | ffmpegArguments[0] = FFMPEG_PROGRAM_NAME;
42 |
43 | return ffmpegArguments;
44 | }
45 |
46 | @SuppressWarnings("ResultOfMethodCallIgnored")
47 | private void deleteOutput() {
48 | final File output = new File(outputPath);
49 | if (output.exists()) {
50 | output.delete();
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/videokit/src/main/java/processing/ffmpeg/videokit/VideoCommandBuilder.java:
--------------------------------------------------------------------------------
1 | package processing.ffmpeg.videokit;
2 |
3 | import android.text.TextUtils;
4 |
5 | import java.io.File;
6 | import java.util.ArrayList;
7 | import java.util.Collections;
8 | import java.util.List;
9 |
10 | /**
11 | * Created by Ilja on 19.07.16.
12 | * Copyright by inFullMobile
13 | */
14 | class VideoCommandBuilder implements CommandBuilder {
15 | private static final String OVERWRITE_FLAG = "-y";
16 | private static final String INPUT_FILE_FLAG = "-i";
17 | private static final String TRIM_FLAG = "-ss";
18 | private static final String DURATION_FLAG = "-t";
19 | private static final String COPY_FLAG = "copy";
20 | private static final String VIDEO_CODEC_FLAG = "-vcodec";
21 | private static final String VIDEO_FILTER_FLAG = "-vf";
22 | private static final String VIDEO_BITRATE_FLAG = "-b:v";
23 | private static final String STRICT_FLAG = "-strict";
24 | private static final String EXPERIMENTAL_FLAG = "-2";
25 | private static final String REMOVE_AUDIO_STREAM_FLAG = "-an";
26 | private static final String FRAME_RATE_FLAG = "-framerate";
27 | private static final String TUNE_FLAG = "-tune";
28 | private static final String FAST_DECODE = "fastdecode";
29 | private static final String ZERO_LATENCY = "zerolatency";
30 |
31 | private final List flags = new ArrayList<>();
32 |
33 | private final VideoKit videoKit;
34 |
35 | private final List inputPaths = new ArrayList<>();
36 | private String outputPath;
37 |
38 | private boolean experimentalFlagSet;
39 |
40 | VideoCommandBuilder(VideoKit videoKit) {
41 | this.videoKit = videoKit;
42 | }
43 |
44 | @Override
45 | public CommandBuilder overwriteOutput() {
46 | flags.add(OVERWRITE_FLAG);
47 | return this;
48 | }
49 |
50 | @Override
51 | public CommandBuilder inputPath(String inputFilePath) {
52 | final File inputFile = new File(inputFilePath);
53 | if (!inputFile.exists()) {
54 | throw new RuntimeException("File provided by you does not exists");
55 | }
56 |
57 | inputPaths.add(inputFilePath);
58 | return this;
59 | }
60 |
61 | @Override
62 | public CommandBuilder outputPath(String outputPath) {
63 | if (TextUtils.isEmpty(outputPath)) {
64 | throw new RuntimeException("It's not a good idea to pass empty path here");
65 | }
66 |
67 | this.outputPath = outputPath;
68 | return this;
69 | }
70 |
71 | @Override
72 | public CommandBuilder trimForDuration(int startPosition, int duration) {
73 | flags.add(TRIM_FLAG);
74 | flags.add(String.valueOf(startPosition));
75 | flags.add(DURATION_FLAG);
76 | flags.add(String.valueOf(duration));
77 | return this;
78 | }
79 |
80 | @Override
81 | public CommandBuilder withoutAudio() {
82 | flags.add(REMOVE_AUDIO_STREAM_FLAG);
83 | return this;
84 | }
85 |
86 | @Override
87 | public CommandBuilder copyVideoCodec() {
88 | flags.add(VIDEO_CODEC_FLAG);
89 | flags.add(COPY_FLAG);
90 | return this;
91 | }
92 |
93 | @Override
94 | public CommandBuilder crop(int x, int y, int width, int height) {
95 | flags.add(VIDEO_FILTER_FLAG);
96 | flags.add("crop=" + width + ":" + height + ":" + x + ":" + y);
97 | return this;
98 | }
99 |
100 | @Override
101 | public CommandBuilder customCommand(String customCommand) {
102 | if (TextUtils.isEmpty(customCommand)) {
103 | return this;
104 | }
105 |
106 | final String[] splitedCommand = customCommand.trim().split(" ");
107 | Collections.addAll(flags, splitedCommand);
108 | return this;
109 | }
110 |
111 | @Override
112 | public CommandBuilder limitVideoBitrate(String bitrate) {
113 | if (TextUtils.isEmpty(bitrate)) {
114 | throw new RuntimeException("It's not a good idea to pass empty path here");
115 | }
116 |
117 | flags.add(VIDEO_BITRATE_FLAG);
118 | flags.add(bitrate);
119 | return this;
120 | }
121 |
122 | @Override
123 | public CommandBuilder experimentalFlag() {
124 | experimentalFlagSet = true;
125 | return this;
126 | }
127 |
128 | @Override
129 | public CommandBuilder limitFrameRate(int framerate) {
130 | flags.add(FRAME_RATE_FLAG);
131 | flags.add(String.valueOf(framerate));
132 | return this;
133 | }
134 |
135 | @Override
136 | public CommandBuilder fastTune() {
137 | flags.add(TUNE_FLAG);
138 | flags.add(FAST_DECODE);
139 | flags.add(TUNE_FLAG);
140 | flags.add(ZERO_LATENCY);
141 | return this;
142 | }
143 |
144 | @Override
145 | public Command build() {
146 | checkInputPathsAndThrowIfEmpty();
147 | checkOutputPathAndThrowIfEmpty();
148 |
149 | final List newFlags = new ArrayList<>();
150 |
151 | addInputPathsToFlags(newFlags);
152 | copyFlagsToNewDestination(newFlags);
153 | addExperimentalFlagIfNecessary(newFlags);
154 |
155 | newFlags.add(outputPath);
156 |
157 | return new VideoCommand(newFlags, outputPath, videoKit);
158 | }
159 |
160 | private void checkInputPathsAndThrowIfEmpty() {
161 | if (inputPaths.isEmpty()) {
162 | throw new RuntimeException("You must specify at least one input path");
163 | }
164 | }
165 |
166 | private void checkOutputPathAndThrowIfEmpty() {
167 | if (TextUtils.isEmpty(outputPath)) {
168 | throw new RuntimeException("You must specify output path");
169 | }
170 | }
171 |
172 | private void addInputPathsToFlags(List flags) {
173 | for (String path : inputPaths) {
174 | flags.add(INPUT_FILE_FLAG);
175 | flags.add(path);
176 | }
177 | }
178 |
179 | private void copyFlagsToNewDestination(List destination) {
180 | for (String flag : flags) {
181 | destination.add(flag);
182 | }
183 | }
184 |
185 | private void addExperimentalFlagIfNecessary(List flags) {
186 | if (experimentalFlagSet) {
187 | flags.add(STRICT_FLAG);
188 | flags.add(EXPERIMENTAL_FLAG);
189 | }
190 | }
191 | }
192 |
--------------------------------------------------------------------------------
/videokit/src/main/java/processing/ffmpeg/videokit/VideoKit.java:
--------------------------------------------------------------------------------
1 | package processing.ffmpeg.videokit;
2 |
3 | /**
4 | * Created by Ilja Kosynkin on 06.07.2016.
5 | * Copyright by inFullMobile
6 | */
7 | public class VideoKit {
8 | static {
9 | try {
10 | System.loadLibrary("avutil");
11 | System.loadLibrary("swresample");
12 | System.loadLibrary("avcodec");
13 | System.loadLibrary("avformat");
14 | System.loadLibrary("swscale");
15 | System.loadLibrary("avfilter");
16 | System.loadLibrary("avdevice");
17 | System.loadLibrary("videokit");
18 | } catch (UnsatisfiedLinkError e) {
19 | e.printStackTrace();
20 | }
21 | }
22 |
23 | private LogLevel logLevel = LogLevel.NO_LOG;
24 |
25 | public void setLogLevel(LogLevel level) {
26 | logLevel = level;
27 | }
28 |
29 | int process(String[] args) {
30 | return run(logLevel.getValue(), args);
31 | }
32 |
33 | private native int run(int loglevel, String[] args);
34 |
35 | public CommandBuilder createCommand() {
36 | return new VideoCommandBuilder(this);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/videokit/src/main/java/processing/ffmpeg/videokit/VideoProcessingResult.java:
--------------------------------------------------------------------------------
1 | package processing.ffmpeg.videokit;
2 |
3 | /**
4 | * Created by Ilja Kosynkin on 06.07.2016.
5 | * Copyright by inFullMobile
6 | */
7 | public class VideoProcessingResult {
8 | static final int SUCCESSFUL_RESULT = 0;
9 |
10 | private final int returnCode;
11 | private final String pathToFile;
12 |
13 | VideoProcessingResult(int code, String path) {
14 | returnCode = code;
15 | pathToFile = path;
16 | }
17 |
18 | public boolean isSuccessful() {
19 | return returnCode == SUCCESSFUL_RESULT;
20 | }
21 |
22 | public String getPath() {
23 | return pathToFile;
24 | }
25 |
26 | public int getCode() {
27 | return returnCode;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/arm64-v8a/libavcodec.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/arm64-v8a/libavcodec.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/arm64-v8a/libavdevice.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/arm64-v8a/libavdevice.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/arm64-v8a/libavfilter.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/arm64-v8a/libavfilter.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/arm64-v8a/libavformat.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/arm64-v8a/libavformat.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/arm64-v8a/libavutil.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/arm64-v8a/libavutil.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/arm64-v8a/libswresample.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/arm64-v8a/libswresample.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/arm64-v8a/libswscale.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/arm64-v8a/libswscale.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/arm64-v8a/libvideokit.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/arm64-v8a/libvideokit.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/armeabi-v7a/libavcodec.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/armeabi-v7a/libavcodec.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/armeabi-v7a/libavdevice.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/armeabi-v7a/libavdevice.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/armeabi-v7a/libavfilter.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/armeabi-v7a/libavfilter.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/armeabi-v7a/libavformat.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/armeabi-v7a/libavformat.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/armeabi-v7a/libavutil.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/armeabi-v7a/libavutil.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/armeabi-v7a/libswresample.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/armeabi-v7a/libswresample.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/armeabi-v7a/libswscale.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/armeabi-v7a/libswscale.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/armeabi-v7a/libvideokit.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/armeabi-v7a/libvideokit.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/armeabi/libavcodec.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/armeabi/libavcodec.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/armeabi/libavdevice.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/armeabi/libavdevice.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/armeabi/libavfilter.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/armeabi/libavfilter.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/armeabi/libavformat.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/armeabi/libavformat.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/armeabi/libavutil.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/armeabi/libavutil.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/armeabi/libswresample.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/armeabi/libswresample.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/armeabi/libswscale.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/armeabi/libswscale.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/armeabi/libvideokit.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/armeabi/libvideokit.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/x86/libavcodec.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/x86/libavcodec.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/x86/libavdevice.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/x86/libavdevice.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/x86/libavfilter.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/x86/libavfilter.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/x86/libavformat.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/x86/libavformat.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/x86/libavutil.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/x86/libavutil.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/x86/libswresample.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/x86/libswresample.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/x86/libswscale.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/x86/libswscale.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/x86/libvideokit.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/x86/libvideokit.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/x86_64/libavcodec.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/x86_64/libavcodec.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/x86_64/libavdevice.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/x86_64/libavdevice.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/x86_64/libavfilter.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/x86_64/libavfilter.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/x86_64/libavformat.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/x86_64/libavformat.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/x86_64/libavutil.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/x86_64/libavutil.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/x86_64/libswresample.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/x86_64/libswresample.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/x86_64/libswscale.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/x86_64/libswscale.so
--------------------------------------------------------------------------------
/videokit/src/main/jniLibs/x86_64/libvideokit.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotintent/videokit-ffmpeg-android/7d5978d97c9586583cbe6d08e86cb26e6c3d5724/videokit/src/main/jniLibs/x86_64/libvideokit.so
--------------------------------------------------------------------------------
/videokit/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | VideoKit
3 |
4 |
--------------------------------------------------------------------------------
/videokit/src/test/java/processing/ffmpeg/videokit/CommandBuilderTest.java:
--------------------------------------------------------------------------------
1 | package processing.ffmpeg.videokit;
2 |
3 | import org.junit.Before;
4 | import org.junit.Test;
5 | import org.mockito.ArgumentCaptor;
6 | import org.mockito.Mock;
7 | import org.mockito.MockitoAnnotations;
8 |
9 | import java.net.URL;
10 |
11 | import static org.junit.Assert.assertTrue;
12 | import static org.mockito.Mockito.when;
13 |
14 | /**
15 | * Created by Ilja on 11.08.16.
16 | * Copyright by inFullMobile
17 | */
18 | public class CommandBuilderTest {
19 | private static final String DUMMY_CUSTOM_COMMAND = "--KABOOM";
20 |
21 | private String testPath;
22 |
23 | @Mock VideoKit videoKit;
24 | private ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(String[].class);
25 |
26 | @Before
27 | public void setUp() {
28 | MockitoAnnotations.initMocks(this);
29 | when(videoKit.process(argumentCaptor.capture())).thenReturn(0);
30 | testPath = getTestFilePath();
31 | }
32 |
33 | @Test(expected = RuntimeException.class)
34 | public void shouldThrowOnNullInputPath() {
35 | //given
36 | final CommandBuilder builder = new VideoCommandBuilder(null);
37 |
38 | //when
39 | builder.build();
40 |
41 | }
42 |
43 | @Test(expected = RuntimeException.class)
44 | public void shouldThrowOnIncorrectInputPath() {
45 | //given
46 | final CommandBuilder builder = new VideoCommandBuilder(null);
47 |
48 | //when
49 | builder.inputPath("incorrectPath");
50 | }
51 |
52 | @Test
53 | public void shouldCreateCorrectBuilder() {
54 | //given
55 | final CommandBuilder builder = getCorrectCommandBuilder();
56 |
57 | //when
58 | builder.build();
59 | }
60 |
61 | @Test
62 | public void shouldAppendFewInputPaths() {
63 | // given
64 | final CommandBuilder builder = getCorrectCommandBuilder().inputPath(testPath);
65 | final String[] expectedFlags = { "ffmpeg", "-i", testPath, "-i", testPath, testPath };
66 |
67 | // when
68 | builder.build().execute();
69 |
70 | // then
71 | assertTrue(areStringArraysEqual(argumentCaptor.getValue(), expectedFlags));
72 | }
73 |
74 | @Test
75 | public void shouldAppendOverwriteFlag() {
76 | // given
77 | final CommandBuilder builder = getCorrectCommandBuilder().overwriteOutput();
78 | final String[] expectedFlags = { "ffmpeg", "-i", testPath, "-y", testPath };
79 |
80 | // when
81 | builder.build().execute();
82 |
83 | // then
84 | assertTrue(areStringArraysEqual(argumentCaptor.getValue(), expectedFlags));
85 | }
86 |
87 | @Test
88 | public void shouldAppendTrimFlags() {
89 | // given
90 | final CommandBuilder builder = getCorrectCommandBuilder().trimForDuration(0, 30);
91 | final String[] expectedFlags =
92 | { "ffmpeg", "-i", testPath, "-ss", "0", "-t", "30", testPath };
93 |
94 | // when
95 | builder.build().execute();
96 |
97 | // then
98 | assertTrue(areStringArraysEqual(argumentCaptor.getValue(), expectedFlags));
99 | }
100 |
101 | @Test
102 | public void shouldAppendNoAudioFlag() {
103 | // given
104 | final CommandBuilder builder = getCorrectCommandBuilder().withoutAudio();
105 | final String[] expectedFlags =
106 | { "ffmpeg", "-i", testPath, "-an", testPath };
107 |
108 | // when
109 | builder.build().execute();
110 |
111 | // then
112 | assertTrue(areStringArraysEqual(argumentCaptor.getValue(), expectedFlags));
113 | }
114 |
115 | @Test
116 | public void shouldAppendCopyVideoFlag() {
117 | // given
118 | final CommandBuilder builder = getCorrectCommandBuilder().copyVideoCodec();
119 | final String[] expectedFlags =
120 | { "ffmpeg", "-i", testPath, "-vcodec", "copy", testPath };
121 |
122 | // when
123 | builder.build().execute();
124 |
125 | // then
126 | assertTrue(areStringArraysEqual(argumentCaptor.getValue(), expectedFlags));
127 | }
128 |
129 | @Test
130 | public void shouldAppendCropFlags() {
131 | // given
132 | final CommandBuilder builder = getCorrectCommandBuilder().crop(0, 0, 100, 100);
133 | final String[] expectedFlags =
134 | { "ffmpeg", "-i", testPath, "-vf", "crop=100:100:0:0", testPath };
135 |
136 | // when
137 | builder.build().execute();
138 |
139 | // then
140 | assertTrue(areStringArraysEqual(argumentCaptor.getValue(), expectedFlags));
141 | }
142 |
143 | @Test
144 | public void shouldAppendCustomCommand() {
145 | // given
146 | final CommandBuilder builder = getCorrectCommandBuilder().customCommand(DUMMY_CUSTOM_COMMAND);
147 | final String[] expectedFlags =
148 | { "ffmpeg", "-i", testPath, DUMMY_CUSTOM_COMMAND, testPath };
149 |
150 | // when
151 | builder.build().execute();
152 |
153 | // then
154 | assertTrue(areStringArraysEqual(argumentCaptor.getValue(), expectedFlags));
155 | }
156 |
157 | @Test
158 | public void shouldAppendLimitBitrateFlag() {
159 | // given
160 | final CommandBuilder builder = getCorrectCommandBuilder().limitVideoBitrate("713K");
161 | final String[] expectedFlags =
162 | { "ffmpeg", "-i", testPath, "-b:v", "713K", testPath };
163 |
164 | // when
165 | builder.build().execute();
166 |
167 | // then
168 | assertTrue(areStringArraysEqual(argumentCaptor.getValue(), expectedFlags));
169 | }
170 |
171 | @Test
172 | public void shouldAppendExperimentalFlagToTheEnd() {
173 | // given
174 | final CommandBuilder builder = getCorrectCommandBuilder().experimentalFlag();
175 | final String[] expectedFlags =
176 | { "ffmpeg", "-i", testPath, "-strict", "-2", testPath };
177 |
178 | // when
179 | builder.build().execute();
180 |
181 | // then
182 | assertTrue(areStringArraysEqual(argumentCaptor.getValue(), expectedFlags));
183 | }
184 |
185 | @Test
186 | public void shouldAppendLimitFramerateFlag() {
187 | // given
188 | final CommandBuilder builder = getCorrectCommandBuilder().limitFrameRate(25);
189 | final String[] expectedFlags =
190 | { "ffmpeg", "-i", testPath, "-framerate", "25", testPath };
191 |
192 | // when
193 | builder.build().execute();
194 |
195 | // then
196 | assertTrue(areStringArraysEqual(argumentCaptor.getValue(), expectedFlags));
197 | }
198 |
199 | @Test
200 | public void shouldAppendFastTuneFlag() {
201 | // given
202 | final CommandBuilder builder = getCorrectCommandBuilder().fastTune();
203 | final String[] expectedFlags =
204 | { "ffmpeg", "-i", testPath, "-tune", "fastdecode", "-tune", "zerolatency", testPath };
205 |
206 | // when
207 | builder.build().execute();
208 |
209 | // then
210 | assertTrue(areStringArraysEqual(argumentCaptor.getValue(), expectedFlags));
211 | }
212 |
213 | private CommandBuilder getCorrectCommandBuilder() {
214 | return new VideoCommandBuilder(videoKit)
215 | .inputPath(testPath)
216 | .outputPath(testPath);
217 | }
218 |
219 | private String getTestFilePath() {
220 | final ClassLoader classLoader = getClass().getClassLoader();
221 | final URL resource = classLoader.getResource("test");
222 | return resource.getPath();
223 | }
224 |
225 | private boolean areStringArraysEqual(String[] actual, String[] expected) {
226 | if (actual.length != expected.length) {
227 | return false;
228 | }
229 |
230 | for (int i = 0; i < actual.length; i++) {
231 | if (!actual[i].equals(expected[i])) {
232 | return false;
233 | }
234 | }
235 |
236 | return true;
237 | }
238 | }
239 |
--------------------------------------------------------------------------------
/videokit/src/test/java/processing/ffmpeg/videokit/CommandTest.java:
--------------------------------------------------------------------------------
1 | package processing.ffmpeg.videokit;
2 |
3 | import org.junit.Before;
4 | import org.junit.Test;
5 | import org.mockito.Mockito;
6 |
7 | import java.net.URL;
8 |
9 | import static org.junit.Assert.assertEquals;
10 | import static org.mockito.Mockito.doReturn;
11 | import static org.mockito.Mockito.spy;
12 |
13 | /**
14 | * Created by Ilja on 11.08.16.
15 | * Copyright by inFullMobile
16 | */
17 | public class CommandTest {
18 | private VideoKit videoKit;
19 |
20 | private String testPath;
21 |
22 | @Before
23 | public void setUp() {
24 | testPath = getTestFilePath();
25 |
26 | videoKit = spy(new VideoKit());
27 | doReturn(VideoProcessingResult.SUCCESSFUL_RESULT)
28 | .when(videoKit).process(Mockito.any(String[].class));
29 | }
30 |
31 | @Test
32 | public void shouldReturnSuccess() {
33 | //given
34 | final CommandBuilder builder = new VideoCommandBuilder(videoKit);
35 | final Command command = builder.inputPath(testPath)
36 | .outputPath(testPath)
37 | .build();
38 |
39 | //when
40 | final int result = command.execute().getCode();
41 |
42 | //then
43 | assertEquals(VideoProcessingResult.SUCCESSFUL_RESULT, result);
44 | }
45 |
46 | private String getTestFilePath() {
47 | final ClassLoader classLoader = getClass().getClassLoader();
48 | final URL resource = classLoader.getResource("test");
49 | return resource.getPath();
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/videokit/src/test/resources/test:
--------------------------------------------------------------------------------
1 | {\rtf1\ansi\ansicpg1251\cocoartf1404\cocoasubrtf470
2 | {\fonttbl\f0\fnil\fcharset0 Menlo-Regular;}
3 | {\colortbl;\red255\green255\blue255;\red159\green160\blue28;}
4 | \paperw11900\paperh16840\margl1440\margr1440\vieww10800\viewh8400\viewkind0
5 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0
6 |
7 | \f0\fs22 \cf2 \CocoaLigature0 2470019\
8 | c945b59}
--------------------------------------------------------------------------------