Library / SDK
Javernaut/ffmpeg-android-maker avatar
Javernaut/ffmpeg-android-maker

ffmpeg-android-maker: building FFmpeg shared libraries for Android

Contains a script that assembles FFmpeg library for Android

814 stars235 forksShellMIT

At a glance

What is it?
ffmpeg-android-maker is a shell script that downloads FFmpeg source, compiles it against the Android NDK for four ABIs, and assembles the shared libraries, headers and the ffmpeg and ffprobe binaries into an output directory ready to drop into an Android project. The default build targets FFmpeg 8.1.2 and API level 19, and the version can be overridden.
Who is it for?
ffmpeg-android-maker suits a developer who needs FFmpeg inside an Android application and wants a reproducible build script rather than a set of prebuilt binaries from an untrusted source. It is the wrong tool if you only need FFmpeg on a desktop, where the system package or a static build is simpler, and the wrong choice if you cannot run the NDK toolchain.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 124 days ago.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the script produces

The repository contains a script that downloads the source code of the FFmpeg library and assembles it for Android. The output is shared libraries, the .so files, and header files, the .h files, laid out in an output directory whose structure is shown in an image in the repository.

The script also produces the ffmpeg and ffprobe executables, which the README says can be used in Android's terminal directly or can even be embedded into an Android app. They are found in the build directory after a successful build.

The stated main focus is preparing shared libraries for integration into an Android project, and the output directory is meant to be used as is. The README is also careful to say this is not the only thing the project does, which is a hint that the build script is one part of a wider set of tools in the scripts/ and tools/ directories.

By default the script downloads and builds FFmpeg 8.1.2, and the README states plainly that the version can be overridden.

The project is a shell script at the root, ffmpeg-android-maker.sh, with the primary language listed as Shell, and the topic tags name android, ffmpeg, ndk and shell-script. The three-part write-up on proandroiddev describes how the script is implemented, covering compilation, integration and extension.

The supported ABIs and the API level trade-off

Four Android ABIs are supported: armeabi-v7a with NEON, arm64-v8a, x86 and x86_64. If you only need some of them, the README says you can build a subset by specifying a flag, and it links the wiki page on desired ABIs to build.

The API level is where the interesting trade-off sits. The default Android API version used to compile the binaries is 19, and the stated reason is that it is the minimum supported by the Android NDK r24. With NDK r23 it is still possible to have 16.

So the floor depends on the NDK you build with, and that in turn depends on which devices you need to support. An older NDK buys a lower minimum API and therefore a wider device range, at the cost of an older toolchain.

There is a second constraint, and it is a catch. Some external libraries, libvpx being the one the README names, require a higher API level, 21. So a build that includes those libraries cannot use 19 or 16, and the wiki page on the Android platform version explains the details.

The practical consequence is that the API level is not one number but a negotiation between three things: the NDK version, the minimum device level you must support, and which external libraries are in the build. The README flags it as a topic that has a wiki page of its own, which is a sign that the interaction is not trivial.

Requirements and the two environment variables

The script assumes Android SDK and NDK are already installed, and to find them you have to define two environment variables.

`ANDROID_SDK_HOME` is the absolute path to the Android SDK, and `ANDROID_NDK_HOME` is the absolute path to the Android NDK. The names are notable because they are the older, deprecated names, and the script is documented against them.

The NDK requirement is a minimum of r23, and the README is explicit that it does not matter which NDK version your own Android project uses. That separation is worth internalising: this is a build tool that produces artefacts, not part of your application's toolchain, so the NDK you build FFmpeg with and the NDK you build your app with are independent decisions.

Certain external libraries need additional host software installed, and the wiki page on supported external libraries lists which. The README makes the point that if you do not need those external libraries then you do not need the extra software either, and that the external libraries are not built by default.

That last clause is the important one for anyone starting. A first run does not attempt to build a dozen third party libraries, so the first build is a plain FFmpeg build and the extra dependencies are something you opt into one at a time.

Running it on macOS, Linux, Windows and in Docker

The script is supported natively on macOS and Linux, where you simply execute it in the terminal after setting up the environment described in the requirements section.

On Windows 10 the README points to WSL, and specifically to installing the Ubuntu 20.04 LTS app in the subsystem, then following the Linux way of executing the script. It warns that you will need to manually install exactly the Linux versions of the Android SDK and NDK into the Linux subsystem, and it suggests the Dockerfile in the tools/docker directory may help in understanding how to do the setup.

The last point is the one that trips people up. An NDK installed on Windows is not the same artefact as an NDK installed in the Linux subsystem, and a cross-compiler built for the wrong host will not work.

On any operating system, Docker is the alternative, and the README points to a wiki page on Docker support to explain the benefits of that approach. A container with the SDK, the NDK and the host build tools already installed removes the setup work entirely, and it also makes the build reproducible, since the container image pins the toolchain.

The repository's own CI uses the same idea. There is a workflow badge for a compilability check, and one of the listed features is that you can test your own configuration in the cloud through the CI integration, with the details in the wiki page on build automation.

Customisation, the media-file branch and the script arguments

The README is explicit that the content of the output directory depends on how FFmpeg was configured before assembling, and the default build on the master branch is described as vanilla, meaning all default components and shared libraries are built.

That default is a starting point rather than a recommendation, and the project demonstrates the alternative with a second branch. The media-file branch contains customisations in the build scripts of FFmpeg and of certain external libraries, and these are meant to be an example of how the project can be tuned to obtain only the functionality that is actually needed. A specific commit link is given so the diff can be read directly.

The example is not hypothetical. The MediaFile Android library uses only a subset of FFmpeg's functionality, so the redundant parts are not compiled at all, which gives much smaller output binaries. That is the central point of the project: a vanilla FFmpeg build for Android is large, and a build trimmed to what your app needs is a fraction of the size.

Beyond the branches, there are many arguments that can be passed to the ffmpeg-android-maker.sh script for tuning certain features, and the README points to the wiki page listing the available script arguments.

Two more customisation points are worth knowing. You can add an arbitrary external library that FFmpeg supports to the build process, by specifying how the source needs to be downloaded and how the build operation is performed. And you can set your own FFmpeg version and origin, overriding the version the script uses.

The text relocations check and where it is wrong to be casual

One feature deserves its own attention because it is a small piece of engineering that saves real debugging time.

After an assembly finishes, you can look at the stats/text-relocations.txt file. It lists all the .so files that were built and reports whether any of them has text relocations. If you see no mention of TEXTREL in the file, you are good. Otherwise the file names the exact binaries that have the problem.

The reason this matters is that text relocations are the thing that makes a shared library fail to load on a modern Android device, with the error pointing at the library rather than at the build script. Because a typical FFmpeg build pulls in several third party libraries, the offending binary is often not the one you would guess, and a report that names it turns a search into a lookup.

The check is cheap to run and it is part of the build output rather than a separate step, so there is no reason to skip it.

The other thing to notice about the project's tone is the amount of work it asks of you. A wiki, a set of flags for the ABIs, a set of flags for the API level, a page per external library, a page for Docker support, a page for build automation and a page for the FFmpeg version. This is a tool that assumes you are comfortable with cross-compilation, and the documentation is structured for that reader rather than for someone who wants a working .so file quickly.

Where ffmpeg-android-maker is the wrong tool

The first limitation is that this is a source build, and a source build of FFmpeg is a long one. The script does the right things, but a full build across four ABIs with the vanilla configuration is a substantial amount of compilation, and the README gives no indication of a build time, so plan for it rather than expecting a quick job.

The second is the toolchain requirement. The NDK, the SDK and the host build tools have to be present and correctly installed for the host OS, and on Windows that means a Linux subsystem with Linux versions of the SDK and NDK specifically. A developer who wants to ship FFmpeg in an app and does not want to own a cross-compilation toolchain is in the wrong place, and the Docker route is the mitigation.

The third is that there are no prebuilt binaries here. This repository builds them. If you want a ready-made .so file, you are looking at the wrong project, and the security argument for building it yourself is one you have to make deliberately rather than one this repository makes for you.

The fourth is the deprecated environment variable names. ANDROID_SDK_HOME and ANDROID_NDK_HOME are the older names, and while the script documents them, the current tooling convention differs, so you may be exporting variables that your own Android tooling ignores.

The fifth is the API level floor. The default of 19 excludes a large slice of older devices, and the external libraries that some apps need push it to 21, so a project with a wide device range and a heavy codec requirement has a genuine conflict that the wiki page exists to explain.

How it compares with a prebuilt FFmpeg and with a plain NDK build

The comparison with a prebuilt FFmpeg for Android is the one most people start with, and the difference in approach is where the artefacts come from. A prebuilt set of .so files saves you a day of build time, and you inherit the choices of whoever built them: which ABI set, which API level, which external libraries, which configure flags. The size will be the vanilla size, because the size reduction in this project comes from trimming the configuration, and a prebuilt vanilla package cannot be trimmed.

So the trade is time against size and provenance. If the FFmpeg you need is a general purpose library and the app size does not matter, a prebuilt package is the sensible choice. If the app is on the size-sensitive side of the Google Play limits, or if you need to know exactly what is compiled in, building it yourself with a trimmed configuration is the only route, and this script is the tooling for that.

The second comparison is with doing the NDK build by hand, with a configure invocation and an ndk-build or CMake setup of your own. The difference is that this script handles the parts that are tedious rather than the parts that are hard: fetching and configuring FFmpeg, building the external libraries, laying out the output tree with headers in the right place, and producing the command line binaries. The parts you would still do yourself, the integration into your Gradle build and the choice of which APIs to call, are the parts the README's series of posts covers.

The third comparison is with other Android media stacks, and it is worth naming honestly. If your application does not need FFmpeg specifically, a library built on MediaCodec or on the platform's own decoders does the same job with none of this, and the size difference is dramatic. The reason to reach for FFmpeg on Android is usually a specific codec or a specific feature the platform decoders do not offer, and once you have decided that, this script is a good way to get it.

Licence, release cadence and what to check first

The licence field on the repository records MIT, with LICENSE.txt at the root.

The release history shows v2.12 from 2024-11-25, v2.11 from 2024-09-22 and v2.10 from 2024-04-05, so the tags are versioned by minor releases. The last push was on 2026-06-21, so the script is being changed even though the newest tag is older than that, and the README says the default FFmpeg version is 8.1.2, which is a reminder that the script tracks FFmpeg releases independently of its own tags.

There is a Codacy badge for code quality and a compilability check workflow, and the project has been featured in two issues of Android Weekly, which is a reasonable sign that it is known in the community.

Four things to check before your first build.

That your environment is set up, with ANDROID_SDK_HOME and ANDROID_NDK_HOME pointing at real installations and the NDK at r23 or newer. Whether you need the external libraries at all, because they are not built by default and each one adds host dependencies and may raise the API level above 19. Which ABIs you actually need, since building a subset is faster and produces a smaller output tree. And what the vanilla build costs you in size, because the whole point of the media-file branch and the script arguments is that the default is bigger than it needs to be.

And after the build, open the text relocations report. If it is clean, the libraries will load.

Editorial conclusion

ffmpeg-android-maker suits a developer who needs FFmpeg inside an Android application and wants a reproducible build script rather than a set of prebuilt binaries from an untrusted source. It is the wrong tool if you only need FFmpeg on a desktop, where the system package or a static build is simpler, and the wrong choice if you cannot run the NDK toolchain. Before running it, set ANDROID_SDK_HOME and ANDROID_NDK_HOME, and note that some external libraries need extra host software and a higher API level than the default 19, so check the supported external libraries page before assuming a plain build covers your needs.

Frequently asked questions

What does ffmpeg-android-maker produce?

A script that downloads the FFmpeg source and assembles it for Android, producing shared libraries as .so files and header files as .h files in an output directory, plus the ffmpeg and ffprobe executables in the build directory that can be run in an Android terminal or embedded into an app.

Which Android ABIs does ffmpeg-android-maker support?

armeabi-v7a with NEON, arm64-v8a, x86 and x86_64. You can build only a subset of them by specifying the flag described in the wiki page on desired ABIs to build.

What environment variables does the ffmpeg-android-maker script need?

ANDROID_SDK_HOME, the absolute path to the Android SDK, and ANDROID_NDK_HOME, the absolute path to the Android NDK. The script expects at least NDK r23, and the NDK you use for the script does not have to be the one you use for your own Android project.

Which Android API level does ffmpeg-android-maker use by default?

API level 19, which is the minimum supported by Android NDK r24, though with NDK r23 a level of 16 is still possible. Some external libraries such as libvpx require a higher level, 21, and the external libraries are not built by default.

Can I build ffmpeg-android-maker on Windows?

Yes, through WSL, by installing the Ubuntu 20.04 LTS app and then following the Linux procedure. The README notes that you have to install the Linux versions of the Android SDK and NDK into the subsystem yourself, and it also says you can use Docker on any operating system as an alternative.

How do I make the FFmpeg build smaller for an Android app?

The content of the output directory depends on how FFmpeg was configured, and the media-file branch demonstrates the tuning by customising the build scripts so that only the functionality actually needed is compiled, which the README says gives much smaller output binaries. The script also takes arguments for tuning features, listed on the available script arguments wiki page.

Official sources

  1. Issues
  2. Javernaut/ffmpeg-android-maker on GitHub
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/javernaut-ffmpeg-android-maker.svg)](https://hysenlabs.com/projects/javernaut-ffmpeg-android-maker)

Was this useful?