Thursday 19 June 2014

Integrate FFMPEG library in Android

FFMPEG is an open-source platform for recording, converting, playing and streaming video and audio. It includes libavcodec, which is a popular video/audio codec.

FFMPEG has written in C language, so to use this library we need android NDK as interface between FFMPEG library and Android.

Please follow the below steps to integrate library :

1.  Download Android SDK

If you don't have Android SDK, please refer below URL:

2. Download Android NDK

Please download the latest version of Android NDK, please refer below URL:

The newest version is of NDK is “r9d”.

Note: - The website provides both current and legacy tool chains. We need only the current tool chain to compile FFMPEG.

After downloading NDK, simply decompress the archive.

Note: - We’ll use $NDK to represent the root path of the decompressed NDK.

3. Download FFMPEG Source Code

FFMPEG source code can be downloaded from the ffmpeg official website.

The latest stable release of library is 2.2.3.
Download the source code and decompress it into $NDK/sources folder.
All the external modules automatically search by $NDK below the source folder,so that we have to put our library in to that folder.


4. Update Configure File

Open ffmpeg-2.2.3/configure file with a text editor and locate the following lines:
SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'

LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'

SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'

SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)'


To make the library compatible with Android OS we have to replcae above lines by the given below lines (e.g. libavcodec.so.55): 
SLIBNAME_WITH_MAJOR ='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'

LIB_INSTALL_EXTRA_CMD ='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'

SLIB_INSTALL_NAME ='$(SLIBNAME_WITH_MAJOR)'

SLIB_INSTALL_LINKS ='$(SLIBNAME)'

5. Build FFMPEG

Create a file build_ffmpeg_android.sh under the $NDK/sources/ ffmpeg-2.2.3 folder and paste below code:
#!/bin/bash

NDK=$HOME/Desktop/adt/android-ndk-r9

SYSROOT=$NDK/platforms/android-9/arch-arm/

TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64

function build_one

{

./configure \

    --prefix=$PREFIX \

    --enable-shared \

    --disable-static \

    --disable-doc \

    --disable-ffmpeg \

    --disable-ffplay \

    --disable-ffprobe \

    --disable-ffserver \

    --disable-avdevice \

    --disable-doc \

    --disable-symver \

    --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \

    --target-os=linux \

    --arch=arm \

    --enable-cross-compile \

    --sysroot=$SYSROOT \

    --extra-cflags="-Os -fpic $ADDI_CFLAGS" \

    --extra-ldflags="$ADDI_LDFLAGS" \

    $ADDITIONAL_CONFIGURE_FLAG

make clean

make

make install

}

CPU=arm

PREFIX=$(pwd)/android/$CPU 

ADDI_CFLAGS="-marm"

build_one


After saving this file, it will disabled static library and enabled shared library (.so files).

Open the terminal and run below commands:

  • Navigate to the FFMPEG library root folder 

cd $NDK/sources/ ffmpeg-2.2.3
  • Validate the script is executable

sudo chmod +x build_android.sh
  • Execute the script 

./build_android.sh

Note: - Time to creat build is depending upon the system speed.

After build completion we can check the shared libraries in  $NDK/sources/ ffmpeg-2.2.3/android/arm/lib folder (e.g.: - libavcodec-55.so).


Note: - lib folder also contains the symbolic links (e.g.: - libavcodec.so). We can remove them to avoid the confusion.

6. Make ffmpeg library available for android projects

Android NDK allows us to reuse a compiled module through the import-module build command.

To declare the FFMPEG libraries as reusable modules, we’ll need to add a file Android.mk under the $NDK/sources/ffmpeg-2.2.3/android/arm folder and paste the below content,
LOCAL_PATH:= $(call my-dir)

 

include $(CLEAR_VARS)

LOCAL_MODULE:= libavcodec

LOCAL_SRC_FILES:= lib/libavcodec-55.so

LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include

include $(PREBUILT_SHARED_LIBRARY)

 

include $(CLEAR_VARS)

LOCAL_MODULE:= libavformat

LOCAL_SRC_FILES:= lib/libavformat-55.so

LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include

include $(PREBUILT_SHARED_LIBRARY)

 

include $(CLEAR_VARS)

LOCAL_MODULE:= libswscale

LOCAL_SRC_FILES:= lib/libswscale-2.so

LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include

include $(PREBUILT_SHARED_LIBRARY)

 

include $(CLEAR_VARS)

LOCAL_MODULE:= libavutil

LOCAL_SRC_FILES:= lib/libavutil-52.so

LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include

include $(PREBUILT_SHARED_LIBRARY)

 

include $(CLEAR_VARS)

LOCAL_MODULE:= libavfilter

LOCAL_SRC_FILES:= lib/libavfilter-3.so

LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include

include $(PREBUILT_SHARED_LIBRARY)

 

include $(CLEAR_VARS)

LOCAL_MODULE:= libwsresample

LOCAL_SRC_FILES:= lib/libswresample-0.so

LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include

include $(PREBUILT_SHARED_LIBRARY)

Now we can use the ffmpeg library.

7. Use FFMPEG Library in Android Project

Create a jni folder under the root of the android project, create Android.mk files under that folder,

Paste the below code in Android.mk and save the file,
LOCAL_PATH := $(call my-dir)

 

include $(CLEAR_VARS)

 

LOCAL_MODULE    := FileName

LOCAL_SRC_FILES := FileName.c

LOCAL_LDLIBS := -llog -ljnigraphics -lz -landroid

LOCAL_SHARED_LIBRARIES := libavformat libavcodec libswscale libavutil

 

include $(BUILD_SHARED_LIBRARY)

$(call import-module,ffmpeg-2.2.3/android/arm)

Compile the FileName.c file code with ffmpeg library run the below command:

cd <Projet root folder full path>
$NDK/ndk-build

For real examples to how to use the ffmpeg libraries in Android app, please refer to Github repo of Android-FFMPEG-Player.