This is a follow up post of the previous blog How to Build FFmpeg for Android.  You can read the previous tutorial first, or refer back to it when you feel necessary.

This blog covers how to build a simple Android app based on FFmpeg library. The app will detect the input video file’s resolution and codec information through interface provided by FFmpeg.

Blow is a screenshot of the app,

device

Figure 1. Screen shot of the sample android app based on FFmpeg

0. Create a new Android Project FFmpegTest.

When you’re asked to select targeted platform, select 2.2 as it’s the platform used in previous blog. But you’re free to change it.

Also create a folder named jni under the root directory “FFmpegTest” of this project.

1. Download the ffmpeg Source Code and Extract it to jni Folder

Follow the previous blog How to Build FFmpeg for Android to build the library.

2. Write the Native Code that use FFmpeg’s libavcodec library.

You can copy and paste the code below and save it as ffmpeg-test-jni.c under FFmpegTest/jni/ directory. Note that the code below is not completed, you can download the entire code at the end of the post.

/*for android logs*/

#define LOG_TAG "FFmpegTest"

#define LOG_LEVEL 10

#define LOGI(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__);}

#define LOGE(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__);}

char *gFileName;      //the file name of the video

AVFormatContext *gFormatCtx;

int gVideoStreamIndex;    //video stream index

AVCodecContext *gVideoCodecCtx;

static void get_video_info(char *prFilename);

static void get_video_info(char *prFilename) {

    AVCodec *lVideoCodec;

    int lError;

    /*register the codec*/

    extern AVCodec ff_h264_decoder;

    avcodec_register(&ff_h264_decoder);

    /*register demux*/

    extern AVInputFormat ff_mov_demuxer;

    av_register_input_format(&ff_mov_demuxer);

    /*register the protocol*/

    extern URLProtocol ff_file_protocol;

    av_register_protocol2(&ff_file_protocol, sizeof(ff_file_protocol));

    /*open the video file*/

    if ((lError = av_open_input_file(&gFormatCtx, gFileName, NULL, 0, NULL)) !=0 ) {

        LOGE(1, "Error open video file: %d", lError);

        return;    //open file failed

    }

    /*retrieve stream information*/

    if ((lError = av_find_stream_info(gFormatCtx)) < 0) {

        LOGE(1, "Error find stream information: %d", lError);

        return;

    }

    /*find the video stream and its decoder*/

    gVideoStreamIndex = av_find_best_stream(gFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, &lVideoCodec, 0);

    if (gVideoStreamIndex == AVERROR_STREAM_NOT_FOUND) {

        LOGE(1, "Error: cannot find a video stream");

        return;

    } else {

        LOGI(10, "video codec: %s", lVideoCodec->name);

    }

    if (gVideoStreamIndex == AVERROR_DECODER_NOT_FOUND) {

        LOGE(1, "Error: video stream found, but no decoder is found!");

        return;

    }

    /*open the codec*/

    gVideoCodecCtx = gFormatCtx->streams[gVideoStreamIndex]->codec;

    LOGI(10, "open codec: (%d, %d)", gVideoCodecCtx->height, gVideoCodecCtx->width);

    if (avcodec_open(gVideoCodecCtx, lVideoCodec) < 0) {

        LOGE(1, "Error: cannot open the video codec!");

        return;

    }

}

JNIEXPORT void JNICALL Java_roman10_ffmpegTest_VideoBrowser_naInit(JNIEnv *pEnv, jobject pObj, jstring pFileName) {

    int l_mbH, l_mbW;

    /*get the video file name*/

    gFileName = (char *)(*pEnv)->GetStringUTFChars(pEnv, pFileName, NULL);

    if (gFileName == NULL) {

        LOGE(1, "Error: cannot get the video file name!");

        return;

    }

    LOGI(10, "video file name is %s", gFileName);

    get_video_info(gFileName);

}

JNIEXPORT jstring JNICALL Java_roman10_ffmpegTest_VideoBrowser_naGetVideoCodecName(JNIEnv *pEnv, jobject pObj) {

    char* lCodecName = gVideoCodecCtx->codec->name;

    return (*pEnv)->NewStringUTF(pEnv, lCodecName);

}

 

 

 

If you’re not familiar with Java JNI, you may need to read about JNI first in order to understand the code. But this is not the focus of this tutorial hence not covered.

3. Build the Native Code.

Create a file named Android.mk under jni directory and copy paste the content below,

LOCAL_PATH := $(call my-dir)

 


 

#declare the prebuilt library

 

include $(CLEAR_VARS)

 

LOCAL_MODULE := ffmpeg-prebuilt

 

LOCAL_SRC_FILES := ffmpeg-0.8/android/armv7-a/libffmpeg.so

 

LOCAL_EXPORT_C_INCLUDES := ffmpeg-0.8/android/armv7-a/include

 

LOCAL_EXPORT_LDLIBS := ffmpeg-0.8/android/armv7-a/libffmpeg.so

 

LOCAL_PRELINK_MODULE := true

 

include $(PREBUILT_SHARED_LIBRARY)

 


 

#the ffmpeg-test-jni library

 

include $(CLEAR_VARS)

 

LOCAL_ALLOW_UNDEFINED_SYMBOLS=false

 

LOCAL_MODULE := ffmpeg-test-jni

 

LOCAL_SRC_FILES := ffmpeg-test-jni.c

 

LOCAL_C_INCLUDES := $(LOCAL_PATH)/ffmpeg-0.8/android/armv7-a/include

 

LOCAL_SHARED_LIBRARY := ffmpeg-prebuilt

 

LOCAL_LDLIBS    := -llog -ljnigraphics -lz -lm $(LOCAL_PATH)/ffmpeg-0.8/android/armv7-a/libffmpeg.so

 

include $(BUILD_SHARED_LIBRARY)

Create another file named Application.mk under jni directory and copy paste the content below,

# The ARMv7 is significanly faster due to the use of the hardware FPU

 

APP_ABI := armeabi-v7a

 

APP_PLATFORM := android-8

For more information about what Android.mk and Application.mk do, you can refer to the documentation comes with android NDK.

Your folder structure should be something like below after you finish all steps above,

jni

Figure 2. Folder structure of project FFmpegTest and jni

4. Call the Native Code from FFmpegTest Java Code.

You’ll need to load the libraries and declare the jni functions. The code below is extracted from the app source code, which is provided for download at the end of this tutorial.

/*this part communicates with native code through jni (java native interface)*/

 

    //load the native library

 

    static {

 

        System.loadLibrary("ffmpeg");

 

        System.loadLibrary("ffmpeg-test-jni");

 

    }

 

    //declare the jni functions

 

    private static native void naInit(String _videoFileName);

 

    private static native int[] naGetVideoResolution();

 

    private static native String naGetVideoCodecName();

 

    private static native String naGetVideoFormatName();

 

    private static native void naClose();

 


 

    private void showVideoInfo(final File _file) {

 

        String videoFilename = _file.getAbsolutePath();

 

        naInit(videoFilename);

 

        int[] prVideoRes = naGetVideoResolution();

 

        String prVideoCodecName = naGetVideoCodecName();

 

        String prVideoFormatName = naGetVideoFormatName();

 

        naClose();

 

        String displayText = "Video: " + videoFilename + "\n";

 

        displayText += "Video Resolution: " + prVideoRes[0] + "x" + prVideoRes[1] + "\n";

 

        displayText += "Video Codec: " + prVideoCodecName + "\n";

 

        displayText += "Video Format: " + prVideoFormatName + "\n";

 

        text_titlebar_text.setText(displayText);

 

    }

5. You can Download the Entire Source Code from here.

Note: the code is tested on Ubuntu 10.04 and Android ndk-5b, but it should work on other platforms (except for Windows, which I’m not sure about.)

 

115 comments on “How to Build Android Applications Based on FFmpeg by An Example

  1. rurtle on said:

    Hi Liu,
    I came across your posts related to building Android applications using FFMpeg in here & found those to be really interesting. Congratulations on the job done well! Moreover, these posts are particularly relevant to one of my hobby DIY projects. The goal for my project is to develop an Android application capable of streaming live feeds captured through web cams in a LAN environment using FFMpeg as the underlying engine. So far, following the instructions mentioned in your blog, I did the following –

    1. Compiling and generating FFMpeg related libraries for the following releases –

    FFMpeg version: 2.0
    NDK version: r8e & r9
    Android Platform version: android-16 & android-18
    Toolchain version: 4.6 & 4.8
    Platform built on: Fedora 18 (x86_64)

    2. Creating the files Android.mk & Application.mk in appropriate path (as suggested in the tutorial).

    However, when it came to writing the native C code for utilizing appropriate functionality of FFMpeg from the application layer using Java, the following questions came to my mind –

    a) Which all of FFMpeg’s features I need to make available from native to application layer?
    b) Whether the compilation options (as shown in the tutorial) are sufficient for handling *.sdp streams or do I need to modify it?
    c) Do I need to make use of live555?

    I am totally new to FFMpeg and Android application development and this is going to be my first serious project on Android platform. I have been searching for relevant tutorials dealing with RTSP streaming using FFMpeg for a while now without much success. Moreover, I tried the latest development build of VLC player and found it to be great in streaming RT feeds. However, it’s a complex beast and the goal for my project is of quite limited nature, mostly learning – within a short time span.

    Could you suggest some pointers (e.g. links, documents or sample code) on how can I write the native C code for utilizing FFMpeg and subsequently use those functionality from the app layer? Moreover, will really appreciate if you could let me know the kind of background knowledge necessary for this project from a functional standpoint (in a language agnostic sense).

    Thank you so much!

  2. rurtle on said:

    Hi Liu,

    Hope you’re doing well!

    I came across your posts related to building Android applications using FFMpeg in here and found those to be really interesting. Congratulations on the job done well! Moreover, these posts are particularly relevant to one of my hobby DIY projects. The goal for my project is to develop an Android application capable of streaming live feeds captured through web cams in a LAN environment using FFMpeg as the underlying engine. So far, following the instructions mentioned in your blog, I did the following –

    1. Compiling and generating FFMpeg related libraries for the following releases –

    FFMpeg version: 2.0
    NDK version: r8e & r9
    Android Platform version: android-16 & android-18
    Toolchain version: 4.6 & 4.8
    Platform built on: Fedora 18 (x86_64)

    2. Creating the files Android.mk & Application.mk in appropriate path (as suggested in the tutorial).

    However, when it came to writing the native C code for utilizing appropriate functionality of FFMpeg from the application layer using Java, the following questions came to my mind –

    a) Which all of FFMpeg’s features I need to make available from native to app layer?
    b) Whether the compilation options (as shown in the tutorial) are sufficient for handling *.sdp streams or do I need to modify it?
    c) Do I need to make use of live555?

    I am totally new to FFMpeg and Android application development and this is going to be my first serious project for Android platform. I have been searching for relevant tutorials dealing with RTSP streaming using FFMpeg on Android platform for a while now without much success. Moreover, I tried the latest development build of VLC player and found it to be great in streaming real-time feeds. However, it’s a complex beast and the goal for my project is of quite limited nature, mostly learning – in a short time span.

    Could you suggest some pointers (e.g. links, documents or sample code) on how can I write the native C code for utilizing FFMpeg and subsequently use those functionality from the app layer? Moreover, will really appreciate if you could let me know the kind of background knowledge necessary for this project from a functional standpoint (in a language agnostic sense).

    Thank you so much!

    ~rurtle

    • Bobnono on said:

      Hi did you find the info you need ?
      I have a similar project : display H264 video stream over RTSp without latency,
      I did the jobs on windows, but now i need to port it on android. But i’m new on Android and i’m on windows.

  3. Thanks for this code and tutorial but, your code not running, so please provide me working code.

  4. please give the sample code to convert wav file to m4a format using ffmpeg

  5. Hi Roman, running the entire source code in Ecplise/SDK, he allows finds e cuts file video only.
    How can I do the same thing with mp3 files instead of video files?
    Thank you very much!
    Alex.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Set your Twitter account name in your settings to use the TwitterBar Section.