FFMPEG 3.2.10 installation procedure for Android NDK r14b for Linux Ubuntu14.04

There are 2 important steps.

1 Build the FFMPEG for android arm armeabi architecture with Linux.

The 2nd part is to install the library on android and verify
 -------------------- Step 1 Build FFMPEG from Linux to Arm -----------------------
 [1] Reference http://www.roman10.net/2013/08/18/how-to-build-ffmpeg-with-ndk-r9/ 
Step 2) Reference
[2.1] https://juejin.im/entry/5975a5006fb9a06bc06a8e2a 
[2.2] https://github.com/wanliyang1990/FFmpeg-Android/tree/master/FFmpegPro

My sistem is Mint 17 Linux, which is Ubuntu14.04 , Android Studio 3.2 My NDK is installed at $HOME/Android

 ---------------- Step 1. ----------------

Please see Reference [1] together.

1. Define $NDK environment variable $export NDK=$HOME/Android/Ndk

2. Download and place FFMPEG 3.2.10 at $NDK/sources

3. cd $NDK/sources/ffmpeg-3.2.10

4. change the configure file's following variable to the following value
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. create build.sh and copy-paste to it the following code
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
 
 6. compile. It can take a while, around 10 mins in my computer. If done correctly, you should see a lot of CC lines without error.

$./build.sh

7. Check the build cd $NDK/sources/ffmpeg-3.2.10/android/arm/lib ls You should see a lot of .so libraries


-----------Step 2----- Android ------------

1. Follow steps in Ref[2.1] These steps are nothing but to create a hello C++ world for NDK.

 



















2) Detail of  CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
include_directories(src/main/jni/ffmpeg/include)

add_library( # Sets the name of the library.
             FFmpegPro

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             src/main/cpp/FFmpegPro.c )


#添加libavcodec-57.so
add_library( avcodec-57
             SHARED
             IMPORTED)
set_target_properties( avcodec-57
                       PROPERTIES IMPORTED_LOCATION
                       ${CMAKE_SOURCE_DIR}/src/main/jni/ffmpeg/armeabi/libavcodec-57.so)


#添加libavdevice-57.so
add_library( avdevice-57
             SHARED
             IMPORTED)
set_target_properties( avdevice-57
                       PROPERTIES IMPORTED_LOCATION
                       ${CMAKE_SOURCE_DIR}/src/main/jni/ffmpeg/armeabi/libavdevice-57.so)

add_library( avfilter-6
             SHARED
             IMPORTED)
set_target_properties( avfilter-6
                       PROPERTIES IMPORTED_LOCATION
                       ${CMAKE_SOURCE_DIR}/src/main/jni/ffmpeg/armeabi/libavfilter-6.so)

add_library( avformat-57
             SHARED
             IMPORTED)
set_target_properties( avformat-57
                       PROPERTIES IMPORTED_LOCATION
                       ${CMAKE_SOURCE_DIR}/src/main/jni/ffmpeg/armeabi/libavformat-57.so)

add_library( avutil-55
             SHARED
             IMPORTED)
set_target_properties( avutil-55
                       PROPERTIES IMPORTED_LOCATION
                       ${CMAKE_SOURCE_DIR}/src/main/jni/ffmpeg/armeabi/libavutil-55.so)

add_library( swresample-2
             SHARED
             IMPORTED)
set_target_properties( swresample-2
                       PROPERTIES IMPORTED_LOCATION
                       ${CMAKE_SOURCE_DIR}/src/main/jni/ffmpeg/armeabi/libswresample-2.so)

add_library( swscale-4
             SHARED
             IMPORTED)
set_target_properties( swscale-4
                       PROPERTIES IMPORTED_LOCATION
                       ${CMAKE_SOURCE_DIR}/src/main/jni/ffmpeg/armeabi/libswscale-4.so)

add_library( postproc-54
             SHARED
             IMPORTED)
set_target_properties( postproc-54
                       PROPERTIES IMPORTED_LOCATION
                       ${CMAKE_SOURCE_DIR}/src/main/jni/ffmpeg/armeabi/libpostproc-54.so)
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
                       FFmpegPro
                       avcodec-57
                       avdevice-57
                       avfilter-6
                       avformat-57
                       avutil-55
                       swresample-2
                       swscale-4
                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

3) cd $ANDROID_PROJECT_ROOT/app/src/main
mkdir -p jni/ffmpeg
cd jni/ffmpeg
cp -r $NDK/sources/ffmpeg-3.2.10/android/arm/include .
mkdir armeabi
cd armeabi
cp -r  $NDK/sources/ffmpeg-3.2.10/android/arm/lib/*.so .

Check that 
$ app/src/main/jni/ffmpeg $ ls
armeabi  include


4. Add new C++ source file to the project. Right Click at cpp folder on Android Studio Android project view and Click add new C++ source file. Name this file FFmpegPro.c. Put the following code inside FFmpegPro.c

#include "com_ywl5320_ffmpegpro_FFmplayer.h"
#include "../jni/ffmpeg/include/libavutil/avutil.h"
#include "../jni/ffmpeg/include/libavcodec/avcodec.h"
#include "../jni/ffmpeg/include/libavformat/avformat.h"

/* ffmpeg库
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libavutil/avutil.h"
 */
//打印日志
#include <android/log.h>
#define LOGI(FORMAT,...) __android_log_print(ANDROID_LOG_INFO,"ywl5320",FORMAT,##__VA_ARGS__);
#define LOGE(FORMAT,...) __android_log_print(ANDROID_LOG_ERROR,"ywl5320",FORMAT,##__VA_ARGS__);
JNIEXPORT void JNICALL
Java_ywl5320_com_ffmpegpro_FFmpegPlayer_showFFmpegInfo(JNIEnv *env, jobject instance) {

    // TODO
}

JNIEXPORT void JNICALL
Java_ywl5320_com_ffmpegpro_FFmpegPlayer_playMyMedia(JNIEnv *env, jobject instance, jstring url_) {
    const char *url = (*env)->GetStringUTFChars(env, url_, 0);

    // TODO
    LOGI("url:%s", url);

    av_register_all();
    AVCodec *c_temp = av_codec_next(NULL);
    while (c_temp != NULL)
    {
        switch (c_temp->type)
        {
            case AVMEDIA_TYPE_VIDEO:
                LOGI("[Video]:%s", c_temp->name);
                break;
            case AVMEDIA_TYPE_AUDIO:
                LOGI("[Audio]:%s", c_temp->name);
                break;
            default:
                LOGI("[Other]:%s", c_temp->name);
                break;
        }
        c_temp = c_temp->next;
    }
    // TODO
    (*env)->ReleaseStringUTFChars(env, url_, url);
}


5. Create a new file called com_ywl5320_ffmpegpro_FFmplayer.h
copy the following code to the .h file
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_ywl5320_ffmpegpro_FFmplayer */

#ifndef _Included_com_ywl5320_ffmpegpro_FFmplayer
#define _Included_com_ywl5320_ffmpegpro_FFmplayer
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_ywl5320_ffmpegpro_FFmplayer
 * Method:    showFFmpegInfo
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_ywl5320_ffmpegpro_FFmplayer_showFFmpegInfo
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

6. Add new java class. Name it FFmpegPlayer. The class code is
public class FFmpegPlayer {

    static    {
        System.loadLibrary("avutil-55");
        System.loadLibrary("swresample-2");
        System.loadLibrary("avcodec-57");
        System.loadLibrary("avformat-57");
        System.loadLibrary("swscale-4");
        //System.loadLibrary("postproc-54");        System.loadLibrary("avfilter-6");
        System.loadLibrary("avdevice-57");
        System.loadLibrary("FFmpegPro");
    }

    public native void showFFmpegInfo();
    public native void playMyMedia(String url);

}

7. Build the android project to see the expected exeption

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:externalNativeBuildDebug'.
> Build command failed.
  Error while executing process /working3/siit/android/Android/Sdk/cmake/3.6.4111459/bin/cmake with arguments {--build /working3/siit/android/AndroidStudioProjects/MyCompilePassFFMPEGonAndroid/app/.externalNativeBuild/cmake/debug/arm64-v8a --target FFmpegPro}
  ninja: error: '../../../../src/main/jni/ffmpeg/armeabi/libavcodec-57.so', needed by '../../../../build/intermediates/cmake/debug/obj/arm64-v8a/libFFmpegPro.so', missing and no known rule to make it

 
8. Compare yourself your module gradle with the following code. Those values in externalNativeBuild can solve 7.
Check the cmake{} ndk{} , and sourceSets{} 
 
android {
    compileSdkVersion 27    defaultConfig {
        applicationId "ywl5320.com.ffmpegpro"        minSdkVersion 23        targetSdkVersion 27        versionCode 1        versionName "1.0"        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"        externalNativeBuild {
            cmake {
                cppFlags ""            }
            ndk {
                abiFilters "armeabi"            }
        }
        sourceSets {
            main {
                jniLibs.srcDirs = ['src/main/jni/ffmpeg']
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }
    }

    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"        }

    }
} 
9. Main Acvitity
 
public class MainActivity extends AppCompatActivity {

    FFmpegPlayer fFmpegPlayer;
    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("avutil-55");
        System.loadLibrary("swresample-2");
        System.loadLibrary("avcodec-57");
        System.loadLibrary("avformat-57");
        System.loadLibrary("swscale-4");
        System.loadLibrary("avfilter-6");
        System.loadLibrary("avdevice-57");
        System.loadLibrary("FFmpegPro");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        fFmpegPlayer = new FFmpegPlayer();
        fFmpegPlayer.playMyMedia("http://blog.csdn.net/ywl5320");
    }


}
 
10. compile and run on real mobile phone. If you see in the log cat the following line. You are done. Successfully
 
    [Video]:a64multi5
    [Video]:aasc
    [Video]:aic
    [Video]:alias_pix
    [Video]:alias_pix
    [Video]:amv
    [Video]:amv
    [Video]:anm
    [Video]:ansi
    [Video]:apng
    [Video]:apng
    [Video]:asv1
    [Video]:asv1
    [Video]:asv2
    [Video]:asv2
    [Video]:aura
    [Video]:aura2
    [Video]:avrp
    [Video]:avrp
    [Video]:avrn
    [Video]:avs
    [Video]:avui
    [Video]:avui
    [Video]:ayuv
    [Video]:ayuv
    [Video]:bethsoftvid
    [Video]:bfi
    [Video]:binkvideo
    [Video]:bmp
    [Video]:bmp
    [Video]:bmv_video
    [Video]:brender_pix
    [Video]:c93
    [Video]:cavs
    [Video]:cdgraphics
    [Video]:cdxl
    [Video]:cfhd
    [Video]:cinepak
    [Video]:cinepak
    [Video]:cljr
    [Video]:cljr
    [Video]:cllc
    [Audio]:comfortnoise
    [Audio]:comfortnoise
    [Video]:cpia
    [Video]:camstudio
    [Video]:cyuv
    [Video]:dds
    [Video]:dfa
    [Video]:dirac
    [Video]:dnxhd
    [Video]:dnxhd
    [Video]:dpx
    [Video]:dpx
    [Video]:dsicinvideo
    [Audio]:dvaudio
    [Video]:dvvideo
    [Video]:dvvideo
    [Video]:dxa
    [Video]:dxtory
    [Video]:dxv
    [Video]:eacmv
    [Video]:eamad
    [Video]:eatgq
    [Video]:eatgv
    [Video]:eatqi
    [Video]:8bps
    [Audio]:8svx_exp
    [Audio]:8svx_fib
    [Video]:escape124
    [Video]:escape130
    [Video]:exr
    [Video]:ffv1
    [Video]:ffv1
    [Video]:ffvhuff
    [Video]:ffvhuff
    [Video]:fic
    [Video]:flashsv
    [Video]:flashsv
    [Video]:flashsv2
    [Video]:flashsv2
    [Video]:flic
    [Video]:flv
    [Video]:flv
    [Video]:4xm
    [Video]:fraps
    [Video]:frwu
    [Video]:g2m
    [Video]:gif
    [Video]:gif
    [Video]:h261
    [Video]:h261
    [Video]:h263
    [Video]:h263
    [Video]:h263i
    [Video]:h263p
    [Video]:h263p
    [Video]:h264
    [Video]:hap
    [Video]:hevc
    [Video]:hnm4video
    [Video]:hq_hqa
    [Video]:hqx
    [Video]:huffyuv
    [Video]:huffyuv
    [Video]:idcinvideo
    [Video]:iff
    [Video]:indeo2
    [Video]:indeo3
    [Video]:indeo4
    [Video]:indeo5
    [Video]:interplayvideo
    [Video]:jpeg2000
    [Video]:jpeg2000
    [Video]:jpegls
    [Video]:jpegls
    [Video]:jv
    [Video]:kgv1
    [Video]:kmvc
    [Video]:lagarith
    [Video]:ljpeg
    [Video]:loco
    [Video]:m101
    [Video]:magicyuv
    [Video]:mdec
    [Video]:mimic
    [Video]:mjpeg
    [Video]:mjpeg
    [Video]:mjpegb
    [Video]:mmvideo
    [Video]:motionpixels
    [Video]:mpeg1video
    [Video]:mpeg1video
    [Video]:mpeg2video
    [Video]:mpeg2video
    [Video]:mpeg4
    [Video]:mpeg4
    [Video]:mpegvideo
    [Video]:msa1
    [Video]:msmpeg4v1
    [Video]:msmpeg4v2
    [Video]:msmpeg4v2
    [Video]:msmpeg4
    [Video]:msmpeg4
    [Video]:msrle
    [Video]:mss1
    [Video]:mss2
    [Video]:msvideo1
    [Video]:msvideo1
    [Video]:mszh
    [Video]:mts2
    [Video]:mvc1
    [Video]:mvc2
    [Video]:mxpeg
    [Video]:nuv
    [Video]:paf_video
    [Video]:pam
    [Video]:pam
    [Video]:pbm
    [Video]:pbm
    [Video]:pcx
    [Video]:pcx
    [Video]:pgm
    [Video]:pgm
    [Video]:pgmyuv
    [Video]:pgmyuv
    [Video]:pictor
    [Video]:png
    [Video]:png
    [Video]:ppm
    [Video]:ppm
    [Video]:prores
    [Video]:prores
    [Video]:prores_aw
    [Video]:prores_ks
    [Video]:prores_lgpl
    [Video]:ptx
    [Video]:qdraw
    [Video]:qpeg
    [Video]:qtrle
    [Video]:qtrle
    [Video]:r10k
    [Video]:r10k
    [Video]:r210
    [Video]:r210
    [Video]:rawvideo
    [Video]:rawvideo
    [Video]:rl2
    [Video]:roqvideo
    [Video]:roqvideo
    [Video]:rpza
    [Video]:rscc
    [Video]:rv10
    [Video]:rv10
    [Video]:rv20
    [Video]:rv20
    [Video]:rv30
    [Video]:rv40
    [Audio]:s302m
    [Audio]:s302m
    [Video]:sanm
    [Video]:screenpresso
    [Audio]:sdx2_dpcm
    [Video]:sgi
    [Video]:sgi
    [Video]:sgirle
    [Video]:sheervideo
    [Video]:smackvid
    [Video]:smc
    [Video]:smvjpeg
    [Video]:snow
    [Video]:snow
    [Video]:sp5x
    [Video]:sunrast
    [Video]:sunrast
    [Video]:svq1
    [Video]:svq1
    [Video]:svq3
    [Video]:targa
    [Video]:targa
    [Video]:targa_y216
    [Video]:tdsc
    [Video]:theora
    [Video]:thp
    [Video]:tiertexseqvideo
    [Video]:tiff
    [Video]:tiff
    [Video]:tmv
    [Video]:truemotion1
    [Video]:truemotion2
    [Video]:truemotion2rt
    [Video]:camtasia
    [Video]:tscc2
    [Video]:txd
    [Video]:ultimotion
    [Video]:utvideo
    [Video]:utvideo
    [Video]:v210
    [Video]:v210
    [Video]:v210x
    [Video]:v308
    [Video]:v308
    [Video]:v408
    [Video]:v408
    [Video]:v410
    [Video]:v410
    [Video]:vb
    [Video]:vble
    [Video]:vc1
    [Video]:vc1image
    [Video]:vc2
    [Video]:vcr1
    [Video]:vmdvideo
    [Video]:vmnc
    [Video]:vp3
    [Video]:vp5
    [Video]:vp6
    [Video]:vp6a
    [Video]:vp6f
    [Video]:vp7
    [Video]:vp8
    [Video]:vp9
    [Video]:vqavideo
    [Video]:webp
    [Video]:wrapped_avframe
    [Video]:wmv1
    [Video]:wmv1
    [Video]:wmv2
    [Video]:wmv2
    [Video]:wmv3
    [Video]:wmv3image
    [Video]:wnv1
    [Video]:xan_wc3
    [Video]:xan_wc4
    [Video]:xbm
    [Video]:xbm
    [Video]:xface
    [Video]:xface
    [Video]:xl
    [Video]:xwd
    [Video]:xwd
    [Video]:y41p
    [Video]:y41p
    [Video]:ylc
    [Video]:yop
    [Video]:yuv4
    [Video]:yuv4
    [Video]:012v
    [Video]:zerocodec
    [Video]:zlib
    [Video]:zlib
    [Video]:zmbv
    [Video]:zmbv
03-30 17:29:41.925 4669-4669/com.example.peerajak.mycompilepassffmpegonandroid I/ywl5320: [Audio]:aac
    [Audio]:aac
    [Audio]:aac_fixed
    [Audio]:aac_latm
    [Audio]:ac3
    [Audio]:ac3
    [Audio]:ac3_fixed
    [Audio]:ac3_fixed
    [Audio]:alac
    [Audio]:alac
    [Audio]:als
    [Audio]:amrnb
    [Audio]:amrwb
    [Audio]:ape
    [Audio]:atrac1
    [Audio]:atrac3
    [Audio]:atrac3plus
    [Audio]:binkaudio_dct
    [Audio]:binkaudio_rdft
    [Audio]:bmv_audio
    [Audio]:cook
    [Audio]:dca
    [Audio]:dca
    [Audio]:dsd_lsbf
    [Audio]:dsd_msbf
    [Audio]:dsd_lsbf_planar
    [Audio]:dsd_msbf_planar
    [Audio]:dsicinaudio
    [Audio]:dss_sp
    [Audio]:dst
    [Audio]:eac3
    [Audio]:eac3
    [Audio]:evrc
    [Audio]:wavesynth
    [Audio]:flac
    [Audio]:flac
    [Audio]:g723_1
    [Audio]:g723_1
    [Audio]:g729
    [Audio]:gsm
    [Audio]:gsm_ms
    [Audio]:iac
    [Audio]:imc
    [Audio]:interplayacm
    [Audio]:mace3
    [Audio]:mace6
    [Audio]:metasound
    [Audio]:mlp
    [Audio]:mlp
    [Audio]:mp1
    [Audio]:mp1float
    [Audio]:mp2
    [Audio]:mp2
    [Audio]:mp2float
    [Audio]:mp2fixed
    [Audio]:mp3
    [Audio]:mp3float
    [Audio]:mp3adu
    [Audio]:mp3adufloat
    [Audio]:mp3on4
    [Audio]:mp3on4float
    [Audio]:mpc7
    [Audio]:mpc8
    [Audio]:nellymoser
    [Audio]:nellymoser
    [Audio]:on2avc
    [Audio]:opus
    [Audio]:paf_audio
    [Audio]:qcelp
    [Audio]:qdm2
    [Audio]:real_144
    [Audio]:real_144
    [Audio]:real_288
    [Audio]:ralf
    [Audio]:shorten
    [Audio]:sipr
    [Audio]:smackaud
    [Audio]:sonic
    [Audio]:sonic
    [Audio]:sonicls
    [Audio]:tak
    [Audio]:truehd
    [Audio]:truehd
    [Audio]:truespeech
    [Audio]:tta
    [Audio]:tta
    [Audio]:twinvq
    [Audio]:vmdaudio
    [Audio]:vorbis
    [Audio]:vorbis
    [Audio]:wavpack
    [Audio]:wavpack
    [Audio]:wmalossless
    [Audio]:wmapro
    [Audio]:wmav1
    [Audio]:wmav1
    [Audio]:wmav2
    [Audio]:wmav2
    [Audio]:wmavoice
    [Audio]:ws_snd1
    [Audio]:xma1
    [Audio]:xma2
    [Audio]:pcm_alaw
    [Audio]:pcm_alaw
    [Audio]:pcm_bluray
    [Audio]:pcm_dvd
    [Audio]:pcm_f32be
    [Audio]:pcm_f32be
    [Audio]:pcm_f32le
    [Audio]:pcm_f32le
    [Audio]:pcm_f64be
    [Audio]:pcm_f64be
    [Audio]:pcm_f64le
    [Audio]:pcm_lxf
    [Audio]:pcm_s8
    [Audio]:pcm_s16be_planar
    [Audio]:pcm_s24daud
    [Audio]:pcm_u8
    [Audio]:pcm_u32be
    [Audio]:roq_dpcm
    [Audio]:adpcm_4xm
    [Audio]:adpcm_ea
    [Audio]:adpcm_ea_r1
    [Audio]:adpcm_ima_dk3
    [Audio]:adpcm_mtaf
    [Audio]:adpcm_thp_le 



ความคิดเห็น

บทความที่ได้รับความนิยม