I want to use a C++ shared library inside my Android App.
I tried to follow along the hello-libs example from Google's NDK samples, but somehow it doesn't work out.
It seems, that my library isn't packed into the APK. All tutorials i found are using *.mk-files, but I want to use cmake.
This is my CMakeLists.txt:
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
# native lib
add_library(native-lib SHARED
native-lib.cpp)
set(IMPORT_DIR ${CMAKE_SOURCE_DIR}/../jniLibs)
# shared lib
add_library(shared-lib SHARED IMPORTED)
set_target_properties(shared-lib PROPERTIES IMPORTED_LOCATION
${IMPORT_DIR}/dynamic/lib/${ANDROID_ABI}/libLibrary.so)
target_include_directories(native-lib PRIVATE
${IMPORT_DIR}/dynamic/include)
# linking libs
target_link_libraries(native-lib
android
shared-lib
log)
As soon as I link the shared-lib along with the others, I get the following error, when running the app:
E/art: dlopen("/data/app/my.package.name-1/lib/arm/libnative-lib.so", RTLD_LAZY) failed: dlopen failed: library "C:/projects/HelloLibs/app/src/main/cpp/../jniLibs/dynamic/lib/armeabi-v7a/libLibrary.so" not foun
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: my.package.name, PID: 29266
java.lang.UnsatisfiedLinkError: dlopen failed: library "C:/projects/HelloLibs/app/src/main/cpp/../jniLibs/dynamic/lib/armeabi-v7a/libLibrary.so" not found
at java.lang.Runtime.loadLibrary(Runtime.java:371)
at java.lang.System.loadLibrary(System.java:988)
at my.package.name.MainActivity.<clinit>(MainActivity.java:11)
at java.lang.reflect.Constructor.newInstance(Native Method)
at java.lang.Class.newInstance(Class.java:1690)
at android.app.Instrumentation.newActivity(Instrumentation.java:1078)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2543)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2771)
at android.app.ActivityThread.access$900(ActivityThread.java:177)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1432)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5912)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)
It looks like the library is not found on the device. Otherwise it looks like the librarie's path is still the one on my local maschine.
The prebuilt libLibrary.so does not have SONAME. If for whatever reason you cannot rebuild this library with latest NDK, you may try the patchelf utility to add SONAME to existing binary.
To package the prebuilt library into your APK, you need to manually configure Gradle with the sourceSets block to include the path to your .so file. After building your APK, you can verify which libraries Gradle packages into your APK by using the APK Analyzer(Build>Analyze APK...).
android {
...
sourceSets {
main {
jniLibs.srcDirs 'imported-lib/src/', 'more-imported-libs/src/'
}
}
for more information please see here "Include prebuilt native libraries"
You don't need to use CMake to use shared libraries (.so files). Just place the libraries inside the respective directories in src/main/jniLibs directory. Then you can load the libraries directly.
Android studio may show error in the native method declarations but, your app will work fine.
Another solution for packing the prebuilt libraries into your APK - linking them to jniLibs.
For example, I don't use direct placement of libraries (because they already exist elsewhere - in my case in docker image with all required prebuilts, SDK, NDK, etc.) but instead of it I just use linking to them to put them in APK. And if such libraries are also needed at build time, cmake can simply uses find_package().
/app/src/main$ tree
.
├── jniLibs
│ ├── arm64-v8a
│ │ ├── libCommonAPI.so -> /opt/thirdparty/android-29/arm64-v8a/capicxx-core-runtime/lib/libCommonAPI.so
│ │ ├── libCommonAPI-SomeIP.so -> /opt/thirdparty/android-29/arm64-v8a/capicxx-someip-runtime/lib/libCommonAPI-SomeIP.so
│ │ ├── libvsomeip3-cfg.so -> /opt/thirdparty/android-29/arm64-v8a/vsomeip/lib/libvsomeip3-cfg.so
│ │ ├── libvsomeip3-e2e.so -> /opt/thirdparty/android-29/arm64-v8a/vsomeip/lib/libvsomeip3-e2e.so
│ │ ├── libvsomeip3-sd.so -> /opt/thirdparty/android-29/arm64-v8a/vsomeip/lib/libvsomeip3-sd.so
│ │ └── libvsomeip3.so -> /opt/thirdparty/android-29/arm64-v8a/vsomeip/lib/libvsomeip3.so
│ ├── armeabi-v7a
│ │ ├── libCommonAPI.so -> /opt/thirdparty/android-29/armeabi-v7a/capicxx-core-runtime/lib/libCommonAPI.so
│ │ ├── libCommonAPI-SomeIP.so -> /opt/thirdparty/android-29/armeabi-v7a/capicxx-someip-runtime/lib/libCommonAPI-SomeIP.so
│ │ ├── libvsomeip3-cfg.so -> /opt/thirdparty/android-29/armeabi-v7a/vsomeip/lib/libvsomeip3-cfg.so
│ │ ├── libvsomeip3-e2e.so -> /opt/thirdparty/android-29/armeabi-v7a/vsomeip/lib/libvsomeip3-e2e.so
│ │ ├── libvsomeip3-sd.so -> /opt/thirdparty/android-29/armeabi-v7a/vsomeip/lib/libvsomeip3-sd.so
│ │ └── libvsomeip3.so -> /opt/thirdparty/android-29/armeabi-v7a/vsomeip/lib/libvsomeip3.so
│ ├── x86
│ │ ├── libCommonAPI.so -> /opt/thirdparty/android-29/x86/capicxx-core-runtime/lib/libCommonAPI.so
│ │ ├── libCommonAPI-SomeIP.so -> /opt/thirdparty/android-29/x86/capicxx-someip-runtime/lib/libCommonAPI-SomeIP.so
│ │ ├── libvsomeip3-cfg.so -> /opt/thirdparty/android-29/x86/vsomeip/lib/libvsomeip3-cfg.so
│ │ ├── libvsomeip3-e2e.so -> /opt/thirdparty/android-29/x86/vsomeip/lib/libvsomeip3-e2e.so
│ │ ├── libvsomeip3-sd.so -> /opt/thirdparty/android-29/x86/vsomeip/lib/libvsomeip3-sd.so
│ │ └── libvsomeip3.so -> /opt/thirdparty/android-29/x86/vsomeip/lib/libvsomeip3.so
│ └── x86_64
│ ├── libCommonAPI.so -> /opt/thirdparty/android-29/x86_64/capicxx-core-runtime/lib/libCommonAPI.so
│ ├── libCommonAPI-SomeIP.so -> /opt/thirdparty/android-29/x86_64/capicxx-someip-runtime/lib/libCommonAPI-SomeIP.so
│ ├── libvsomeip3-cfg.so -> /opt/thirdparty/android-29/x86_64/vsomeip/lib/libvsomeip3-cfg.so
│ ├── libvsomeip3-e2e.so -> /opt/thirdparty/android-29/x86_64/vsomeip/lib/libvsomeip3-e2e.so
│ ├── libvsomeip3-sd.so -> /opt/thirdparty/android-29/x86_64/vsomeip/lib/libvsomeip3-sd.so
│ └── libvsomeip3.so -> /opt/thirdparty/android-29/x86_64/vsomeip/lib/libvsomeip3.so
.
Related
I was trying to build native shared library of minizip-ng with flutter on Linux, but I'm getting the error below.
It seems that it cannot find lzma.h, but trying set the property 'MZ_LZMA' in minizip-ng's CMakeLists.txt to 'OFF' does not helps.
I also tried installing the liblzma-dev, but nothing changed.
The error:
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':native_add:buildCMakeDebug[arm64-v8a]'.
> Build command failed.
Error while executing process /home/user/Android/Sdk/cmake/3.18.1/bin/ninja with arguments {-C /home/user/Dev/flutter/native_add/android/.cxx/Debug/5c706627/arm64-v8a native_add}
ninja: Entering directory `/home/user/Dev/flutter/native_add/android/.cxx/Debug/5c706627/arm64-v8a'
[1/3] Building C object minizip-ng/CMakeFiles/minizip.dir/mz_strm_lzma.c.o
FAILED: minizip-ng/CMakeFiles/minizip.dir/mz_strm_lzma.c.o
/home/user/Android/Sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --target=aarch64-none-linux-android24 --sysroot=/home/user/Android/Sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/sysroot -DHAVE_INTTYPES_H -DHAVE_LZMA -DHAVE_STDINT_H -DHAVE_ZLIB -DLZMA_API_STATIC -DMZ_ZIP_NO_CRYPTO -DMZ_ZIP_NO_ENCRYPTION -DZLIB_COMPAT -D_LARGEFILE64_SOURCE -D_POSIX_C_SOURCE=200112L -D__USE_LARGEFILE64 -I../../../../minizip-ng -Iminizip-ng -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fno-limit-debug-info -fPIC -Wall -std=gnu99 -MD -MT minizip-ng/CMakeFiles/minizip.dir/mz_strm_lzma.c.o -MF minizip-ng/CMakeFiles/minizip.dir/mz_strm_lzma.c.o.d -o minizip-ng/CMakeFiles/minizip.dir/mz_strm_lzma.c.o -c ../../../../minizip-ng/mz_strm_lzma.c
../../../../minizip-ng/mz_strm_lzma.c:15:10: fatal error: 'lzma.h' file not found
#include "lzma.h"
^~~~~~~~
1 error generated.
ninja: build stopped: subcommand failed.
And the CMakeLists.txt in project/android/ is:
cmake_minimum_required(VERSION 3.13)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "-O3 -Wall -Wextra")
add_library(native_test SHARED lib.cpp)
add_subdirectory(minizip-ng)
target_link_libraries(native_test minizip)
The content of lib.cpp is:
#include "minizip-ng/mz_compat.h"
extern "C" {
int native_add(int a, int b) {
return a + b;
}
}
The structure of project/android/:
├── build.gradle
├── CMakeLists.txt
├── lib.cpp
├── local.properties
├── minizip-ng
│ ├── cmake
│ │ ├── clone-repo.cmake
│ │ └── FindZLIBNG.cmake
│ ├── CMakeLists.txt
│ ├── INDEX.md
│ ├── LICENSE
│ ├── minigzip.c
│ ├── minizip.c
│ ├── minizip.pc.cmakein
│ ├── mz_compat.c
│ ├── mz_compat.h
│ ├── mz_compat_shim.h.in
│ ├── mz_crypt_apple.c
│ ├── mz_crypt.c
│ ├── mz_crypt.h
│ ├── mz_crypt_openssl.c
│ ├── mz_crypt_win32.c
│ ├── mz.h
│ ├── mz_os.c
│ ├── mz_os.h
│ ├── mz_os_posix.c
│ ├── mz_os_win32.c
│ ├── mz_strm_buf.c
│ ├── mz_strm_buf.h
│ ├── mz_strm_bzip.c
│ ├── mz_strm_bzip.h
│ ├── mz_strm.c
│ ├── mz_strm.h
│ ├── mz_strm_libcomp.c
│ ├── mz_strm_libcomp.h
│ ├── mz_strm_lzma.c
│ ├── mz_strm_lzma.h
│ ├── mz_strm_mem.c
│ ├── mz_strm_mem.h
│ ├── mz_strm_os.h
│ ├── mz_strm_os_posix.c
│ ├── mz_strm_os_win32.c
│ ├── mz_strm_pkcrypt.c
│ ├── mz_strm_pkcrypt.h
│ ├── mz_strm_split.c
│ ├── mz_strm_split.h
│ ├── mz_strm_wzaes.c
│ ├── mz_strm_wzaes.h
│ ├── mz_strm_zlib.c
│ ├── mz_strm_zlib.h
│ ├── mz_strm_zstd.c
│ ├── mz_strm_zstd.h
│ ├── mz_zip.c
│ ├── mz_zip.h
│ ├── mz_zip_rw.c
│ ├── mz_zip_rw.h
│ ├── README.md
├── native_test_android.iml
├── settings.gradle
└── src
└── main
├── AndroidManifest.xml
└── kotlin
└── com
└── example
└── native_test
└── NativeTestPlugin.kt
I tried to search the error, but didn't find anything similar.
edit:
The Android Ndk version is 25.1.8937393
I am working on a Visual Studio Mobile development project using the Basic Application (Android, Gradle) template but I modified the main file to be a C++ file instead of Java. Here is my Project structure:
VSProject
├─VSProject.sln
├─VSProject.sln.DotSettings.user
└─VSProject
├── VSProject.androidproj
├── VSProject.androidproj.user
├── app
│ ├── build.gradle
│ └── src
│ └── main
│ ├── AndroidManifest.xml
│ └── cpp
│ ├── CMakeLists.txt
│ ├── app_framework
│ └── main.cpp
├── build.gradle
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradle.properties
├── gradlew.bat
└── settings.gradle
My main.cpp starts by including some headers that are necessary for the file to compile, but in the Visual Studio Android,Gradle template there is no "Additional Include Directories" entry in Project->Properties.
Here are my includes:
#include <app_framework/application.h>
#include <gflags/gflags.h>
#include <test_audio.h>
#include <algorithm>
#include <fstream>
#include <limits>
#include <vector>
None of these files is found in the search paths and hence none is included. "app_framework" is a local directory (same location as main.cpp), so I fixed it by simply doing:
#include "app_framework/application.h"
The others are more problematic:
"gflags" is a sub folder to "app_framework" and I would like to avoid having to write down the whole path to "gflags" as it is fairly long.
"test_audio.h" is an external file to my solution.
Same for "algorithm", "fstream", "limits" and "vector". I am trying to find a way to do what I usually do in a C++ application template in Visual Studio through "Additional Include Directories" in the Gradle template in VS but I do not know how to do so. Where can I set the search include paths to find the files and have the main.cpp compile?
When I build the solution, the .apk application is correctly created and installed on the device, but it does not run due to the main.cpp file not including those files. I am using Gradle 7.5.1.
I have a C++ CMake project which has a straightforward structure:
<root>
├── Projects
│ ├── Core
│ │ └── CMakeLists.txt
│ ├── ApplicationMain
│ │ └── CMakeLists.txt
│ └── Samples
│ ├── Sample01
│ │ └── CMakeLists.txt
│ └── ...
│ └── CMakeLists.txt
└── CMakeLists.txt
Root CMakeLists.txt loads each project in order via add_subdirectory which exposes all created targets in global scope. Then my IDE can build each target and i can run each one. Root CMakeLists.txt heavily relies on CMAKE_SOURCE_DIRECTORY and other auto-set variables during its configuring. All dependent libraries are defined here
Now I want to add android project which must contain its own project structure. It has to have the same structure of projects (Core, ApplicationMain, Sample01, SampleN). I wanted to reuse all targets except ApplicationMain (because NDK defines android_main entry instead of main) and use them as android project "subprojects". The main problem is that android studio project doesn't respect my repo root CMakeLists.txt and i didn't found a way to include it as the first-class citizen config file
I tried this:
set(BACKUP_CMAKE_SOURCE_DIR ${CMAKE_SOURCE_DIR})
set(CMAKE_SOURCE_DIR ${CMAKE_SOURCE_DIR}/../../)
include(${CMAKE_SOURCE_DIR}/CMakeLists.txt)
set(CMAKE_SOURCE_DIR ${BACKUP_CMAKE_SOURCE_DIR})
And this fails on adding subdirectories for third parties and dependent subprojects like Core (because they are in the scope of repository root and not of my android's project root which is inside the repo root). I could specify the path for build files in add_subdirectory to add out-of-tree projects but i don't want to affect my primary C++ project with such decisions.
The above approach looks too bad to me
I didn't find another good approach to make this work
I did the following before:
MacBook-Pro:bb-ns-ng-dr ishandutta2007$ npm uninstall -g semver
MacBook-Pro:bb-ns-ng-dr ishandutta2007$ npm uninstall semver
MacBook-Pro:bb-ns-ng-dr ishandutta2007$ rm -rf platforms/
MacBook-Pro:bb-ns-ng-dr ishandutta2007$ rm -rf node_modules/
MacBook-Pro:bb-ns-ng-dr ishandutta2007$ tns build android --clean
I keep getting semver Duplicate resources error, even though semver is neither any of of node modules I defines nor any of theri tertiary dependency. Keeping aside the reson of Duplicate resources I am more curious how is it coming in the first place.
Could not merge source set folders:
[app/node_modules/semver/semver.min.js]
/Users/ishandutta2007/Documents/Projects/bb-ns-ng-dr/platforms/android/src/main/assets/app/node_modules/semver/semver.min.js
[app/node_modules/semver/semver.min.js]
/Users/ishandutta2007/Documents/Projects/bb-ns-ng-dr/platforms/android/src/main/assets/app/node_modules/semver/semver.min.js.gz:
Error: Duplicate resources [app/node_modules/semver/semver.browser.js]
/Users/ishandutta2007/Documents/Projects/bb-ns-ng-dr/platforms/android/src/main/assets/app/node_modules/semver/semver.browser.js
[app/node_modules/semver/semver.browser.js]
/Users/ishandutta2007/Documents/Projects/bb-ns-ng-dr/platforms/android/src/main/assets/app/node_modules/semver/semver.browser.js.gz:
Error: Duplicate resources
Here is how my node modules package tree looks like
MacBook-Pro:bb-ns-ng-dr ishandutta2007$ npm ls
/Users/ishandutta2007/Documents/Projects/bb-ns-ng-dr
├── #angular/animations#4.1.3
├── #angular/common#4.1.3
├── #angular/compiler#4.1.3
├── UNMET PEER DEPENDENCY #angular/core#4.1.3
├── #angular/forms#4.1.3
├── #angular/http#4.1.3
├── #angular/platform-browser#4.1.3
├── #angular/platform-browser-dynamic#4.1.3
├── #angular/router#4.1.3
├── #ngrx/core#1.2.0
├── #ngrx/effects#2.0.2
├── #ngrx/store#2.2.1
├── #ngrx/store-devtools#3.2.4
├── #types/gapi#0.0.30
├── #types/gapi.auth2#0.0.34
├── #types/gapi.youtube#3.0.31
├── #types/jasmine#2.5.38
├── #types/youtube#0.0.28
├─┬ babel-traverse#6.24.1
│ ├─┬ babel-code-frame#6.22.0
│ │ ├─┬ chalk#1.1.3
│ │ │ ├── ansi-styles#2.2.1
│ │ │ ├── escape-string-regexp#1.0.5
│ │ │ ├─┬ has-ansi#2.0.0
│ │ │ │ └── ansi-regex#2.1.1
│ │ │ ├── strip-ansi#3.0.1
│ │ │ └── supports-color#2.0.0
│ │ └── js-tokens#3.0.1
│ ├── babel-messages#6.23.0
│ ├─┬ babel-runtime#6.23.0
│ │ ├── core-js#2.4.1
│ │ └── regenerator-runtime#0.10.5
│ ├─┬ debug#2.6.8
│ │ └── ms#2.0.0
│ ├── globals#9.17.0
│ ├─┬ invariant#2.2.2
│ │ └── loose-envify#1.3.1
│ └── lodash#4.17.4
├─┬ babel-types#6.24.1
│ ├── esutils#2.0.2
│ └── to-fast-properties#1.0.3
├── babylon#6.17.1
├── lazy#1.0.11
├─┬ nativescript-angular#3.0.0
│ └── nativescript-intl#3.0.0
├─┬ nativescript-dev-typescript#0.4.5
│ └─┬ nativescript-hook#0.2.1
│ ├─┬ glob#6.0.4
│ │ ├─┬ inflight#1.0.6
│ │ │ └── wrappy#1.0.2
│ │ ├── inherits#2.0.3
│ │ ├─┬ minimatch#3.0.4
│ │ │ └─┬ brace-expansion#1.1.7
│ │ │ ├── balanced-match#0.4.2
│ │ │ └── concat-map#0.0.1
│ │ ├── once#1.4.0
│ │ └── path-is-absolute#1.0.1
│ └─┬ mkdirp#0.5.1
│ └── minimist#0.0.8
├── nativescript-exoplayer#3.0.7
├── nativescript-localstorage#1.1.2
├── nativescript-telerik-ui#2.0.1
├── nativescript-theme-core#1.0.4
├── ngrx-action-creator-factory#0.0.1
├── ngrx-store-localstorage#0.1.5
├── reflect-metadata#0.1.10
├─┬ rxjs#5.3.3
│ └── symbol-observable#1.0.4
├─┬ tns-core-modules#3.0.1
│ └── tns-core-modules-widgets#3.0.1
├── typescript#2.2.2
└── zone.js#0.8.11
npm ERR! peer dep missing: #angular/core#^2.0.0, required by #ngrx/effects#2.0.2
npm ERR! peer dep missing: #angular/core#^2.0.0, required by #ngrx/store#2.2.1
npm ERR! peer dep missing: #angular/core#^2.0.0-rc.5, required by ngrx-store-localstorage#0.1.5
npm depends on semver, so it seems unlikely you can totally get rid of it from your globals. According to npm there are over 4,000 packages with a dependency on it.
Instead of asking where it is coming from, perhaps you would want to focus your questions on what problem you are having.
I have compiled FFmpeg for Android to suite my needs in terms of codecs, muxers etc.
Now I have an executable that, from what I understand, should be placed in my project dir under <project-root>/external/<arbitrary-folder-name>/data/data/<my-app-package-name>/app_opt. What I have inside app_opt now is:
.
├── bin
│ └── ffmpeg
├── include
│ ├── libavcodec
│ │ ├── avcodec.h
│ │ ├── avfft.h
│ │ ├── dxva2.h
│ │ ├── vaapi.h
│ │ ├── vda.h
│ │ ├── vdpau.h
│ │ ├── version.h
│ │ └── xvmc.h
│ ├── libavdevice
│ │ └── avdevice.h
│ ├── libavfilter
│ │ ├── asrc_abuffer.h
│ │ ├── avcodec.h
│ │ ├── avfiltergraph.h
│ │ ├── avfilter.h
│ │ ├── buffersink.h
│ │ ├── buffersrc.h
│ │ ├── version.h
│ │ └── vsrc_buffer.h
│ ├── libavformat
│ │ ├── avformat.h
│ │ ├── avio.h
│ │ └── version.h
│ ├── libavutil
│ │ ├── adler32.h
│ │ ├── aes.h
│ │ ├── attributes.h
│ │ ├── audioconvert.h
│ │ ├── audio_fifo.h
│ │ ├── avassert.h
│ │ ├── avconfig.h
│ │ ├── avstring.h
│ │ ├── avutil.h
│ │ ├── base64.h
│ │ ├── bprint.h
│ │ ├── bswap.h
│ │ ├── common.h
│ │ ├── cpu.h
│ │ ├── crc.h
│ │ ├── dict.h
│ │ ├── error.h
│ │ ├── eval.h
│ │ ├── fifo.h
│ │ ├── file.h
│ │ ├── imgutils.h
│ │ ├── intfloat.h
│ │ ├── intfloat_readwrite.h
│ │ ├── intreadwrite.h
│ │ ├── lfg.h
│ │ ├── log.h
│ │ ├── lzo.h
│ │ ├── mathematics.h
│ │ ├── md5.h
│ │ ├── mem.h
│ │ ├── opt.h
│ │ ├── parseutils.h
│ │ ├── pixdesc.h
│ │ ├── pixfmt.h
│ │ ├── random_seed.h
│ │ ├── rational.h
│ │ ├── samplefmt.h
│ │ ├── sha.h
│ │ ├── timecode.h
│ │ └── timestamp.h
│ ├── libpostproc
│ │ └── postprocess.h
│ ├── libswresample
│ │ └── swresample.h
│ └── libswscale
│ └── swscale.h
├── lib
│ ├── libavcodec.a
│ ├── libavdevice.a
│ ├── libavfilter.a
│ ├── libavformat.a
│ ├── libavutil.a
│ ├── libpostproc.a
│ ├── libswresample.a
│ ├── libswscale.a
│ └── pkgconfig
│ ├── libavcodec.pc
│ ├── libavdevice.pc
│ ├── libavfilter.pc
│ ├── libavformat.pc
│ ├── libavutil.pc
│ ├── libpostproc.pc
│ ├── libswresample.pc
│ └── libswscale.pc
└── share
└── ffmpeg
├── examples
│ ├── decoding_encoding.c
│ ├── filtering_audio.c
│ ├── filtering_video.c
│ ├── Makefile
│ ├── metadata.c
│ └── muxing.c
├── ffprobe.xsd
├── libvpx-1080p50_60.ffpreset
├── libvpx-1080p.ffpreset
├── libvpx-360p.ffpreset
├── libvpx-720p50_60.ffpreset
├── libvpx-720p.ffpreset
├── libx264-ipod320.ffpreset
└── libx264-ipod640.ffpreset
Do I need just the ffmpeg under bin to place in my project's <project-root>/res/raw dir?
And what is the easiest way to call ffmpeg and feed it with a command string?
I compiled FFmpeg with limited decoders and demuxers, because I need audio extraction only.
See: How can I get FFmpeg to locate installed libraries when --sysroot is pointing to another directory?
I would use it in background and notify the user in notification bar on completion.
I know that, here on SO, other similar questions are present, but they are a bit vague or confusing, at least for me. I understand at this point I lack of competences (actually my App is a jigsaw made of java-code-snippets from the Net that work together).
I'd appreciate some guidance.
Thanks.
Although an executable 'ffmpeg' placed in a bin folder will run on a rooted phone, its actually not the best way to distribute ffmpeg in an app which will be suitable for general distribution.
The better interface is to use a standard JNI interface where android loads a shared lib permitting an invocation of ffmpeg and then calls the shell, android method serving as a wrapper for a CLI exec of ffmpeg.
For a great sample , see "android-ffmpeg-x264" project on github.
The android JNI interface is here
The project linked above is no longer supported. A newer alternative can be found at http://writingminds.github.io/ffmpeg-android-java/