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.

10 comments:

  1. Hi Amit, I have successfully done everything as per your blog but not getting how to compile or create FileName.c. How to use ndk-build for it. Suppose my project full path is D:\Android App\FFMPEG New\android-ffmpeg-tutorial-master\android-ffmpeg-tutorial02 and when I tried $NDK/ndk-build it gives me NDK is not a recognized internal or external command.

    2:- I have checked Android-FFMPEG-Player but it's tutorial02.c file given error.

    ReplyDelete
  2. hi maroti have you done ndk build

    ReplyDelete
    Replies
    1. Hi Jitendra, I have done with ndk part but not sure how to use generated .so file in android application.

      Delete
    2. This comment has been removed by the author.

      Delete
  3. Hi Amit. I came to the 5th step, the build is created but there is no android folder. P.S. I'm using ffmpeg 3.2.1

    ReplyDelete
  4. Edit post and add sudo ./build_android.sh

    because without it sometimes permission denied by system

    ReplyDelete
  5. I have a problem until step 7.
    But it give me this error:

    [arm64-v8a] SharedLibrary : libLibffmpeg.so
    ./obj/local/arm64-v8a/libavformat.so: error adding symbols: File in wrong format
    clang++: error: linker command failed with exit code 1 (use -v to see invocation)
    make: *** [obj/local/arm64-v8a/libLibffmpeg.so] Error 1

    can you help me?

    ReplyDelete
  6. Nice it seems to be good post... It will get readers engagement on the article since readers engagement plays an vital role in every.
    top android app development companies | professional custom website design company

    ReplyDelete
  7. Hi Amit,

    Thanks for writing wonderful blog on FFMPEG for Android.
    I am trying to compile the latest version of FFMPEG3.4 with latest NDK16. But I am facing below errors/warning:

    WARNING: /Users/strehan/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-pkg-config not found, library detection may fail.
    2. Error: In file included from libavdevice/avdevice.c:19:0:./libavutil/avassert.h:30:20: fatal error: stdlib.h: No such file or directory

    3. Error: /Users/strehan/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/include/stdint.h:9:26: fatal error: stdint.h: No such file or directory

    4. Error: /libavutil/common.h:33:19: fatal error: errno.h: No such file or directory

    I have posted a same query on below stackoverflow thread.
    https://stackoverflow.com/questions/48293404/error-in-building-ffmpeg-3-4-with-android-ndk-16-1/48310165#48310165

    Please share your inputs.

    ReplyDelete
  8. Following pretty much the same approach, i built FFMPEG2.8 and wrapped it in a library that is easy to integrate with a onle line integration :)

    https://github.com/madhavanmalolan/ffmpegandroidlibrary

    Cheers!
    Thanks for the post!

    ReplyDelete