Building the Opus Codec for Android with DRED Support
This guide provides step-by-step instructions and a shell script to compile the Opus audio codec from the source for the Android platform. The build will be configured to be static and will have the DRED (Deep REDundancy) feature enabled, which is excellent for handling packet loss in real-time communication.
1. Prerequisites
Before you begin, ensure you have the following software installed on your development machine (Linux or macOS is recommended):
- Git: To clone the Opus source code repository.
- Android NDK: The Native Development Kit is essential for cross-compiling for Android. Download the latest version from the official Android NDK page.
- Autotools:
autoconf
,automake
, andlibtool
are required by the Opus build system.- On Debian/Ubuntu:
sudo apt-get install autoconf automake libtool
- On macOS (with Homebrew):
brew install autoconf automake libtool
- On Debian/Ubuntu:
2. Setup and Configuration
First, clone the official Opus repository and prepare your environment.
# Clone the Opus repository if it doesn't exist
if [ ! -d "opus" ]; then
echo "Cloning Opus repository..."
git clone https://github.com/xiph/opus.git
fi
# Navigate into the source directory and update the source
cd opus
echo "Pulling latest changes from Opus repository..."
git pull
# Run the autogen script to create the configure script
./autogen.sh
3. The Android Build Script
The most reliable way to build for multiple Android architectures is to use a shell script. The script below sets the correct environment variables and compiler flags for the NDK toolchain.
Create a new file named build_opus_android.sh
in the opus
directory and paste the following content into it.
#!/bin/bash
# Exit immediately if a command exits with a non-zero status.
set -e
# --- Configuration ---
# Set the path to your Android NDK root directory
export NDK_ROOT="/path/to/your/android-ndk" # <-- IMPORTANT: CHANGE THIS
# Set the Android API level you want to target. 21 is a good minimum for modern apps.
export API_LEVEL=21
# List of architectures to build.
# Common architectures are: aarch64 (arm64-v8a), armv7a (armeabi-v7a), x86_64, x86
TARGET_ARCHS=("aarch64" "armv7a" "x86_64")
# --- DO NOT EDIT BELOW THIS LINE ---
# Check if NDK_ROOT is set correctly
if [ ! -d "$NDK_ROOT" ]; then
echo "Error: NDK_ROOT is not set or not a valid directory."
echo "Please edit this script and set NDK_ROOT to your Android NDK location."
exit 1
fi
# Determine the host OS for the NDK toolchain path
HOST_TAG=""
if [[ $(uname -s) == "Linux" ]]; then
HOST_TAG="linux-x86_64"
elif [[ $(uname -s) == "Darwin" ]]; then
HOST_TAG="darwin-x86_64"
else
echo "Unsupported host OS. This script supports Linux and macOS."
exit 1
fi
# Set the NDK toolchain path
export TOOLCHAIN="$NDK_ROOT/toolchains/llvm/prebuilt/$HOST_TAG"
export PATH="$TOOLCHAIN/bin:$PATH"
# --- Build Function ---
build_for_arch() {
ARCH=$1
echo "================================================="
echo "Building Opus for ANDROID architecture: $ARCH"
echo "================================================="
# Set target host based on architecture
case $ARCH in
"aarch64")
TARGET_HOST="aarch64-linux-android"
;;
"armv7a")
TARGET_HOST="armv7a-linux-androideabi"
;;
"x86_64")
TARGET_HOST="x86_64-linux-android"
;;
"x86")
TARGET_HOST="i686-linux-android"
;;
*)
echo "Unsupported architecture: $ARCH"
exit 1
;;
esac
# Set compiler and other toolchain executables
export AR=$TOOLCHAIN/bin/llvm-ar
export CC=$TOOLCHAIN/bin/$TARGET_HOST$API_LEVEL-clang
export CXX=$TOOLCHAIN/bin/$TARGET_HOST$API_LEVEL-clang++
export LD=$TOOLCHAIN/bin/ld
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
export STRIP=$TOOLCHAIN/bin/llvm-strip
# Define the output directory for this architecture
OUTPUT_DIR="$(pwd)/android-build/$ARCH"
mkdir -p $OUTPUT_DIR
# Clean previous build artifacts if a Makefile exists
if [ -f "Makefile" ]; then
make clean
fi
# Configure the build
./configure \
--host=$TARGET_HOST \
--prefix="$OUTPUT_DIR" \
--enable-static \
--disable-shared \
--disable-doc \
--disable-extra-programs \
--with-sysroot="$TOOLCHAIN/sysroot" \
--enable-dred # <-- This is the flag that enables DRED support
# Compile and install
make -j$(nproc)
make install
echo "-------------------------------------------------"
echo "Successfully built Opus for $ARCH"
echo "Output libraries are in: $OUTPUT_DIR"
echo "-------------------------------------------------"
}
# --- Main Execution ---
# Loop through all target architectures and build
for ARCH in "${TARGET_ARCHS[@]}"; do
build_for_arch $ARCH
done
echo "================================================="
echo "All Android builds completed successfully!"
echo "================================================="
4. How to Run the Script
- Modify the
NDK_ROOT
variable in thebuild_opus_android.sh
script to point to the location where you extracted the Android NDK.
Run the script from within the opus
source directory:
./build_opus_android.sh
Make the script executable:
chmod +x build_opus_android.sh
The script will now configure, compile, and install the Opus library for each architecture specified in the TARGET_ARCHS
array.
5. Verifying the Output
After the script finishes, you will have a new directory named android-build
inside your opus
folder. The structure will look like this:
opus/
├── android-build/
│ ├── aarch64/
│ │ ├── include/opus/
│ │ │ ├── opus.h
│ │ │ ├── opus_defines.h
│ │ │ └── ...
│ │ └── lib/
│ │ ├── libopus.a <-- The static library
│ │ └── pkgconfig/
│ ├── armv7a/
│ │ ├── include/
│ │ └── lib/
│ └── x86_64/
│ ├── include/
│ └── lib/
└── ...
You now have the static library (libopus.a
) and the necessary headers for each Android architecture, ready to be integrated into your project.
6. Integrating into Your Android Project (CMake)
To use these prebuilt libraries in your Android app, you'll need to configure your project's CMakeLists.txt
file.
- Copy the entire
android-build
directory into your app'sapp/src/main/cpp
directory (or a similar location). - Modify your
CMakeLists.txt
to add the library and link against it.
# Add Opus as a prebuilt static library
add_library(opus-prebuilt STATIC IMPORTED)
# Set the location of the .a file based on the Android ABI
set_target_properties(opus-prebuilt PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/android-build/${ANDROID_ABI}/lib/libopus.a)
# Include the Opus header directory
include_directories(${CMAKE_SOURCE_DIR}/android-build/${ANDROID_ABI}/include)
# ... later, when you define your app's native library ...
# Link your native library against the prebuilt Opus library
target_link_libraries(
your-native-lib-name # The name of your app's library
opus-prebuilt
log
)
Now, when you build your Android app, Gradle and CMake will automatically select the correct libopus.a
for the target device's architecture and link it with your native code. You can include <opus/opus.h>
in your C/C++ files to use the Opus API.
Comments ()