воскресенье, 15 апреля 2012 г.

How to build ffmpeg and use it in Android applications

This is a shoterned English version of my previous post. If you want to see more details try Google translate service on that post.
I decided to use the capabilities of ffmpeg in my Android application. And I found that almost all information on building ffmpeg project for Android is outdated. So these are my steps.


First of all you should build ffmpeg shared library. To do that you have to use some Linux OS. As far as I know it is impossible to build this library on Windows. But I may be wrong. I used Ubuntu 11.10.

Building

Building ffmpeg library:
1. Install Android NDK. I used Android NDK r7c. I've just unpacked the archive to my home directory and renamed it to "android-ndk".
2. Create a new Android project (target Android 2.3.3 - level 10), name it "MyFfmeg" for example.
3. Create a folder named "jni" in the project directory.
4. Download ffmpeg sources. I used ffmpeg 0.8.11 "Love" version. Unfortunatlly I couldn't compile newer versions. I tried FFmpeg 0.9.1 "Harmony", FFmpeg 0.10 "Freedom" and FFmpeg 0.10.2 "Freedom" but fruitlessly. The bug I found is described here. This bug is closed as invalid but I suspect that it is real.
5. Unpack ffmpeg sources to our "jni" directory and rename "ffmpeg-0.8.11" folder to "ffmpeg".
6. Set an execute permission on file "<my-workspace>/MyFfmpeg/jni/ffmpeg".
7. Create file "<my-workspace>/MyFfmpeg/jni/ffmpeg/build4android.sh". Don't forget an execute permission.
Copy-paste this text:

#!/bin/bash
# Author: Dmitry Dzakhov (based on Guo Mingyu's script)

# Creating conf.sh in ffmpeg directory
NDK=/home/dmitrydzz/android-ndk
PLATFORM=$NDK/platforms/android-8/arch-arm
PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86
output="conf.sh"

[ -f conf.sh ] && echo "Old $output has been removed."
echo '#!/bin/bash' > $output
echo "PREBUILT=$PREBUILT" >> $output
echo "PLATFORM=$PLATFORM" >> $output
echo './configure --target-os=linux \
    --prefix=./android/armv7-a \
    --enable-cross-compile \
    --extra-libs="-lgcc" \
    --arch=arm \
    --cc=$PREBUILT/bin/arm-linux-androideabi-gcc \
    --cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \
    --nm=$PREBUILT/bin/arm-linux-androideabi-nm \
    --sysroot=$PLATFORM \
    --extra-cflags=" -O3 -fpic -DANDROID -DHAVE_SYS_UIO_H=1 -Dipv6mr_interface=ipv6mr_ifindex -fasm -Wno-psabi -fno-short-enums -fno-strict-aliasing -finline-limit=300 -mfloat-abi=softfp -mfpu=neon -marm -march=armv7-a -mtune=cortex-a8 " \
    --disable-shared \
    --enable-static \
    --extra-ldflags="-Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib -lc -lm -ldl -llog" \
    --enable-parsers \
    --enable-encoders \
    --enable-decoders \
    --enable-muxers \
    --enable-demuxers \
    --enable-swscale \
    --enable-swscale-alpha \
    --disable-ffplay \
    --disable-ffprobe \
    --enable-ffserver \
    --enable-network \
    --enable-indevs \
    --disable-bsfs \
    --enable-filters \
    --enable-avfilter \
    --enable-protocols \
    --disable-asm \
    --enable-neon' >> $output

# start configure
sudo chmod +x $output
echo "configuring..."
./$output || (echo configure failed && exit 1)

# modify the config.h
echo "modifying the config.h..."
sed -i "s/#define restrict restrict/#define restrict/g" config.h

# remove static functions in libavutil/libm.h
echo "removing static functions in libavutil/libm.h..."
sed -i "/static/,/}/d" libavutil/libm.h

# modify Makefiles
echo "modifying Makefiles..."
sed -i "/include \$(SUBDIR)..\/subdir.mak/d" libavcodec/Makefile
sed -i "/include \$(SUBDIR)..\/config.mak/d" libavcodec/Makefile
sed -i "/include \$(SUBDIR)..\/subdir.mak/d" libavfilter/Makefile
sed -i "/include \$(SUBDIR)..\/config.mak/d" libavfilter/Makefile
sed -i "/include \$(SUBDIR)..\/subdir.mak/d" libavformat/Makefile
sed -i "/include \$(SUBDIR)..\/config.mak/d" libavformat/Makefile
sed -i "/include \$(SUBDIR)..\/subdir.mak/d" libavutil/Makefile
sed -i "/include \$(SUBDIR)..\/config.mak/d" libavutil/Makefile
sed -i "/include \$(SUBDIR)..\/subdir.mak/d" libpostproc/Makefile
sed -i "/include \$(SUBDIR)..\/config.mak/d" libpostproc/Makefile
sed -i "/include \$(SUBDIR)..\/subdir.mak/d" libswscale/Makefile
sed -i "/include \$(SUBDIR)..\/config.mak/d" libswscale/Makefile

# generate av.mk in ffmpeg
echo "generating av.mk in ffmpeg..."
echo '# LOCAL_PATH is one of libavutil, libavcodec, libavformat, or libswscale

#include $(LOCAL_PATH)/../config-$(TARGET_ARCH).mak
include $(LOCAL_PATH)/../config.mak

OBJS :=
OBJS-yes :=
MMX-OBJS-yes :=
include $(LOCAL_PATH)/Makefile

# collect objects
OBJS-$(HAVE_MMX) += $(MMX-OBJS-yes)
OBJS += $(OBJS-yes)

FFNAME := lib$(NAME)
FFLIBS := $(foreach,NAME,$(FFLIBS),lib$(NAME))
FFCFLAGS  = -DHAVE_AV_CONFIG_H -Wno-sign-compare -Wno-switch -Wno-pointer-sign
FFCFLAGS += -DTARGET_CONFIG=\"config-$(TARGET_ARCH).h\"

ALL_S_FILES := $(wildcard $(LOCAL_PATH)/$(TARGET_ARCH)/*.S)
ALL_S_FILES := $(addprefix $(TARGET_ARCH)/, $(notdir $(ALL_S_FILES)))

ifneq ($(ALL_S_FILES),)
ALL_S_OBJS := $(patsubst %.S,%.o,$(ALL_S_FILES))
C_OBJS := $(filter-out $(ALL_S_OBJS),$(OBJS))
S_OBJS := $(filter $(ALL_S_OBJS),$(OBJS))
else
C_OBJS := $(OBJS)
S_OBJS :=
endif

C_FILES := $(patsubst %.o,%.c,$(C_OBJS))
S_FILES := $(patsubst %.o,%.S,$(S_OBJS))

FFFILES := $(sort $(S_FILES)) $(sort $(C_FILES))' > av.mk

echo 'include $(all-subdir-makefiles)' > ../Android.mk

echo 'LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_STATIC_LIBRARIES := libavformat libavcodec libavutil libpostproc libswscale
LOCAL_MODULE := ffmpeg
include $(BUILD_SHARED_LIBRARY)
include $(call all-makefiles-under,$(LOCAL_PATH))' > Android.mk

echo 'LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../av.mk
LOCAL_SRC_FILES := $(FFFILES)
LOCAL_C_INCLUDES :=        \
    $(LOCAL_PATH)        \
    $(LOCAL_PATH)/..
LOCAL_CFLAGS += $(FFCFLAGS)
LOCAL_CFLAGS += -include "string.h" -Dipv6mr_interface=ipv6mr_ifindex
LOCAL_LDLIBS := -lz
LOCAL_STATIC_LIBRARIES := $(FFLIBS)
LOCAL_MODULE := $(FFNAME)
include $(BUILD_STATIC_LIBRARY)' > libavformat/Android.mk

echo 'LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../av.mk
LOCAL_SRC_FILES := $(FFFILES)
LOCAL_C_INCLUDES :=        \
    $(LOCAL_PATH)        \
    $(LOCAL_PATH)/..
LOCAL_CFLAGS += $(FFCFLAGS)
LOCAL_CFLAGS += -std=c99
LOCAL_LDLIBS := -lz
LOCAL_STATIC_LIBRARIES := $(FFLIBS)
LOCAL_MODULE := $(FFNAME)
include $(BUILD_STATIC_LIBRARY)' > libavcodec/Android.mk

echo 'LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../av.mk
LOCAL_SRC_FILES := $(FFFILES)
LOCAL_C_INCLUDES :=        \
    $(LOCAL_PATH)        \
    $(LOCAL_PATH)/..
LOCAL_CFLAGS += $(FFCFLAGS)
LOCAL_STATIC_LIBRARIES := $(FFLIBS)
LOCAL_MODULE := $(FFNAME)
include $(BUILD_STATIC_LIBRARY)' > libavfilter/Android.mk

echo 'LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../av.mk
LOCAL_SRC_FILES := $(FFFILES)
LOCAL_C_INCLUDES :=        \
    $(LOCAL_PATH)        \
    $(LOCAL_PATH)/..
LOCAL_CFLAGS += $(FFCFLAGS)
LOCAL_STATIC_LIBRARIES := $(FFLIBS)
LOCAL_MODULE := $(FFNAME)
include $(BUILD_STATIC_LIBRARY)' > libavutil/Android.mk

echo 'LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../av.mk
LOCAL_SRC_FILES := $(FFFILES)
LOCAL_C_INCLUDES :=        \
    $(LOCAL_PATH)        \
    $(LOCAL_PATH)/..
LOCAL_CFLAGS += $(FFCFLAGS)
LOCAL_STATIC_LIBRARIES := $(FFLIBS)
LOCAL_MODULE := $(FFNAME)
include $(BUILD_STATIC_LIBRARY)' > libpostproc/Android.mk

echo 'LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../av.mk
LOCAL_SRC_FILES := $(FFFILES)
LOCAL_C_INCLUDES :=        \
    $(LOCAL_PATH)        \
    $(LOCAL_PATH)/..
LOCAL_CFLAGS += $(FFCFLAGS)
LOCAL_STATIC_LIBRARIES := $(FFLIBS)
LOCAL_MODULE := $(FFNAME)
include $(BUILD_STATIC_LIBRARY)' > libswscale/Android.mk

# start build!
echo "start ndk-building..."
cd ../..
$NDK/ndk-build
# Change previous line to "$NDK/ndk-build V=1" if you'll get errors. This will give some more information.

8. Go to "<my-workspace>/MyFfmpeg/jni/ffmpeg" directory and run "build4android.sh" script.

After some minutes of ffmpeg building (13 for my notebook) you'll get ffmpeg shared library and some static libraries in "<my-workspace>/MyFfmpeg/obj" directory. So our next step is to check these libraries.

Demonstration

1. Create one more Android project. I named it "MyFfmpegTest".
2. Create direcory "jni" in "<my-workspace>/MyFfmpegTest".
3. Copy directory "<my-workspace>/MyFfmpeg/obj" to "<my-workspace>/MyFfmpegTest".
4. Copy directory "<my-workspace>/MyFfmpeg/jni/ffmpeg" to "<my-workspace>/MyFfmpegTest/jni". Then run this command:

find ~/robot-mitya/Android/MyFfmpegTest/jni/ffmpeg/ -type f -not \( -name "*.asm" -or -name "*.h" -or -name "*.S" \) -exec rm {} \;

We need only headers, so be careful, this command erases all files from the directory that is defined by the first parameter except for *.h, *.asm and *.S files. Change this parameter for your directory.

5. Create file named "mylib.c" in "<my-workspace>/MyFfmpegTest/jni" directory. Copy-paste this:

#include <jni.h>
#include <android/log.h>

#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"

#define LOG_TAG "mylib"
#define LOGI(...)  __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...)  __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

jint Java_ru_dzakhov_ffmpeg_test_MainActivity_logFileInfo(JNIEnv * env, jobject this, jstring filename)
{
    av_register_all();

    AVFormatContext *pFormatCtx;
    const jbyte *str;
    str = (*env)->GetStringUTFChars(env, filename, NULL);

    if(av_open_input_file(&pFormatCtx, str, NULL, 0, NULL)!=0)
    {
        LOGE("Can't open file '%s'\n", str);
        return 1;
    }
    else
    {
        LOGI("File was opened\n");
        LOGI("File '%s', Codec %s",
            pFormatCtx->filename,
            pFormatCtx->iformat->name
        );
    }
    return 0;
}

6. Create "Android.mk" makefile in "<my-workspace>/MyFfmpegTest/jni" directory. Copy:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_LDFLAGS := -Wl,-rpath-link=/home/dmitrydzz/android-ndk/platforms/android-14/arch-arm/usr/lib/ -rpath-link=/home/dmitrydzz/android-ndk/platforms/android-14/arch-arm/usr/lib/
LOCAL_MODULE := libavformat
LOCAL_SRC_FILES := ../obj/local/armeabi/libavformat.a
LOCAL_CFLAGS := -march=armv7-a -mfloat-abi=softfp -mfpu=neon #надо именно эти 3 параметра! Нашёл это в android-ndk/docs/STANDALONE-TOOLCHAIN.html
LOCAL_LDLIBS := -lz -lm -llog -lc -L$(call host-path, $(LOCAL_PATH))/$(TARGET_ARCH_ABI) -landprof

include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)

LOCAL_LDFLAGS := -Wl,-rpath-link=/home/dmitrydzz/android-ndk/platforms/android-14/arch-arm/usr/lib/ -rpath-link=/home/dmitrydzz/android-ndk/platforms/android-14/arch-arm/usr/lib/
LOCAL_MODULE := libavcodec
LOCAL_SRC_FILES := ../obj/local/armeabi/libavcodec.a
LOCAL_CFLAGS := -march=armv7-a -mfloat-abi=softfp -mfpu=neon
LOCAL_LDLIBS := -lz -lm -llog -lc -L$(call host-path, $(LOCAL_PATH))/$(TARGET_ARCH_ABI) -landprof

include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)

LOCAL_MODULE := libpostproc
LOCAL_SRC_FILES := ../obj/local/armeabi/libpostproc.a
LOCAL_CFLAGS := -march=armv7-a -mfloat-abi=softfp -mfpu=neon

include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE := libswscale
LOCAL_SRC_FILES := ../obj/local/armeabi/libswscale.a
LOCAL_CFLAGS := -march=armv7-a -mfloat-abi=softfp -mfpu=neon

include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE := libavutil
LOCAL_SRC_FILES := ../obj/local/armeabi/libavutil.a
LOCAL_CFLAGS := -march=armv7-a -mfloat-abi=softfp -mfpu=neon

include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)

LOCAL_LDLIBS += -llog -lz
LOCAL_STATIC_LIBRARIES := libavformat libavcodec libpostproc libswscale libavutil
LOCAL_C_INCLUDES += $(LOCAL_PATH)/ffmpeg
LOCAL_SRC_FILES := mylib.c
LOCAL_CFLAGS := -march=armv7-a -mfloat-abi=softfp -mfpu=neon
LOCAL_MODULE := mylib

include $(BUILD_SHARED_LIBRARY)

LOCAL_PATH := $(call my-dir)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/ffmpeg
include $(all-subdir-makefiles)

7. Go to "<my-workspace>/MyFfmpegTest/jni" directory and run command "~/ardroid-ndk/ndk-build". This command will build "libmylib.so" library.

8. Modify Android-application activity:

package ru.dzakhov.ffmpeg.test;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {
    private static native int logFileInfo(String filename);
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        logFileInfo("/sdcard/VIDEO0050.mp4");
    }

    static
    {
        System.loadLibrary("mylib");
    }
}

Don't forget to correct package name and mediafile name.

9. Run this application on your Android-gadget and you'll see something like this in your LogCat window (use tag "mylib" to filter output):

04-08 19:20:09.999: I/mylib(26025): File was opened
04-08 19:20:09.999: I/mylib(26025): File '/sdcard/VIDEO0050.mp4', Codec mov,mp4,m4a,3gp,3g2,mj2

That's all.
You can download my build4android.sh script and source code of MyFfmpegTest project.


50 комментариев:

  1. Thanks a lot, it worked after several tries!

    Here are the things others have to be careful about when trying:

    The build4android.sh and Android.mk have locations set relative to author's machine.

    Change the NDK location in build4android.sh to your location. Currently its set to NDK=/home/dmitrydzz/android-ndk". In Android.mk file look for "/home/dmitrydzz/android-ndk/" and replace the string with your location.

    ОтветитьУдалить
    Ответы
    1. Thanks for your comment :)
      Just change the value of NDK variable in build4android.sh. And that's all. Android.mk will be generated with your ndk location.

      Удалить
    2. Thanks for the indicator. I was going through this to setup environment to do audio mixing of streams using ffmpeg in android. Can you tell me how I could mix the audio streams via code JNI.. ? Any reference would help.

      Thanks!

      Удалить
    3. Zaki, I think I've found a very interesting solution: http://stackoverflow.com/questions/5164211/use-ffmpeg-on-android
      The main idea is here: "compile ffmpeg.c and invoke its main() via jni". There is a lot of information about ffmpeg command line, so we can use it :)

      Удалить
    4. Hi,

      Thanks, yes I was following that link.Currently facing issues with compiling the ffmpeg.c file successfully. I am getting one major error at end of compilation which is:

      error: expected '=', ',', ';', 'asm' or '__attribute__' before 'Java_net_minusdegree_myaudio_MainView_ffmpeg'

      I had to change the main method for JNI invocation. Its showing this error just before the method.

      I will inform you if things change :)

      Удалить
    5. > I will inform you if things change :)

      Yes, please! That's very interesting and may be I'd use it in my next project. Good luck! :)

      Удалить
  2. Thank you very much for taking the time to create this tutorial.
    I'm having a problem though, as the application, MyFfmpegTest, closes automatically and I don't see the message in LogCat, File opened or file not found.I'm running the application in the emulator. I've used Google API & Android for version 2.3.3
    Any ideas of what might be the problem?

    part of the log
    05-04 18:13:06.694: I/ActivityManager(61): Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=ru.dzakhov.ffmpeg.test/.MainActivity } from pid 135
    05-04 18:13:06.884: I/ActivityManager(61): Start proc ru.dzakhov.ffmpeg.test for activity ru.dzakhov.ffmpeg.test/.MainActivity: pid=416 uid=10034 gids={}
    05-04 18:13:07.744: D/dalvikvm(416): Trying to load lib /data/data/ru.dzakhov.ffmpeg.test/lib/libmylib.so 0x40514ff8
    05-04 18:13:07.915: I/ARMAssembler(61): generated scanline__00000177:03515104_00001002_00000000 [ 87 ipp] (110 ins) at [0x445ed6f0:0x445ed8a8] in 621886 ns
    05-04 18:13:08.001: D/dalvikvm(416): Added shared lib /data/data/ru.dzakhov.ffmpeg.test/lib/libmylib.so 0x40514ff8
    05-04 18:13:08.007: D/dalvikvm(416): No JNI_OnLoad found in /data/data/ru.dzakhov.ffmpeg.test/lib/libmylib.so 0x40514ff8, skipping init
    05-04 18:13:08.454: I/DEBUG(31): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
    05-04 18:13:08.454: I/DEBUG(31): Build fingerprint: 'generic/sdk/generic:2.3.3/GRI34/101070:eng/test-keys'
    05-04 18:13:08.464: I/DEBUG(31): pid: 416, tid: 416 >>> ru.dzakhov.ffmpeg.test <<<
    05-04 18:13:08.464: I/DEBUG(31): signal 4 (SIGILL), code 1 (ILL_ILLOPC), fault addr 8102ea08
    05-04 18:13:08.464: I/DEBUG(31): r0 0000abe0 r1 4051c308 r2 8140df20 r3 800a2988
    05-04 18:13:08.464: I/DEBUG(31): r4 0000abe0 r5 4051c308 r6 405182f8 r7 418fcce4

    ОтветитьУдалить
    Ответы
    1. Hi, thanks. Have you searched for "mylib" tag in LogCat?
      There could be an error with "mylib" tag "Can't open file ..." or two information lines with the same tag.

      Some ideas:

      1. If LogCat is empty... that's strange. I didn't run this application on emulator. May be that's the reason... Can you run MyFfmpegTest on real device? I used some special "hardware" flags (-march=armv7-a -mfloat-abi=softfp -mfpu=neon). May be we've got this failure because of these flags?... Remove them from Android.mk. Try to rebuild.

      2. Try Android 4.0.3 application target. Just to check that it doesn't work too. :)

      3. Try to change -rpath-link directory if Android.mk to android-10 (2.3.3).

      Удалить
    2. Thank you for your prompt reply! I thought it would be a good idea to test the native code before making the build changes you have suggested and I think I've spotted the error in mylib.c.
      I've tested the jni/mylib.c by writing to the LogCat after the end of each statement
      e.g.
      av_register_all();
      LOGE("STEP 01 \n");
      AVFormatContext *pFormatCtx;
      LOGE("STEP 02 \n");
      [...]
      and it fails here:
      str = (*env)->GetStringUTFChars(env, filename, NULL);
      Because I'm new to the world of android/ndk development, I couldn't find what's causing this critical exception which closes the application.

      P.S. You should make a complete English version of your blog, navigation & leaving comments are a bit tricky as the options are shown in a different language.
      Is there a way to send you an e-mail so we won't fill the comments with "errors" until we sort this out?
      Using your tutorial to build ffmpeg for android was by far the best one I've found over the Internet. Hopefully we will sort the jni communication problem

      Удалить
    3. > navigation & leaving comments are a bit tricky as the options are shown in a different language

      Oh... I'm sorry. You are right. :) That's my mistake.
      Ok, I'll change page templates or I'll make an English blog.

      > Is there a way to send you an e-mail...?

      Write me: DzakhovDS@gmail.com (Dmitry Dzakhov)
      I'm new in Android and NDK too, but let's try to find out what's the matter with GetStringUTFChars together.

      Удалить
    4. Sorry for this long period of silence. I think I know the reason. It seems like emulator doesn't support neon instructions.

      Try to exclude CFLAGS='-march=armv7-a -mfloat-abi=softfp -mfpu=neon'

      Удалить
  3. Hi,

    I am back :) The previous problem was because I forgot to include #include . Also I want to say something which is the cleaning script that provided will remove all the *.mk files as well. Is that a problem?

    The current problem is I am trying to register ffmpeg and the next two lines compile in my C file:

    avcodec_register_all();
    av_register_all();

    But the following two lines fail to compile:

    avdevice_register_all();
    avfilter_register_all();

    I get this error in my console:

    undefined reference to `avdevice_register_all'
    undefined reference to `avfilter_register_all'

    Is there some configuration which needs to be changed to enable these? I am not sure what's missing.

    ОтветитьУдалить
  4. Hi, how can I use ffmpeg command after compiled it? ex ffmpeg -i input output?
    Thanks

    ОтветитьУдалить
    Ответы
    1. I think you can use Android ADB. But I've planed to incapsulate ffmpeg functions in java. I'm new in Android NDK and it was hard for me so I've tried plan "B". I've decided to incapsulate only one function - "main". And than I've found absolutely different solution for my project (not ffmpeg). That was plan "C" :) So I've stopped my ffmpeg experiments.

      Удалить
  5. Thank you!
    Your posting works on Android NDK r8.
    I have tried ffmpeg-0.11.1. but not works now.
    (ffmpeg-0.11.1 is changed API from 'av_open_input_file' to 'avformat_open_input'. its crush SIGSEGV.)

    ОтветитьУдалить
    Ответы
    1. Google the open-source Dolphin player, download the code it has ffmpeg distribution and a script to build ffmpeg so under android. 0.11.1 builds fine

      Удалить
  6. Hi. I tried your tutorial, but it doesn't work :(
    I get a runtime error at the line where the "System.loadLibrary("mylib");" is called.
    The following things are different at my workflow.

    1. I didn't find ffmpeg-0.8.11. There was only the version 0.8.12.
    2. I'm using android-ndk-r8c
    3. I don't know if step 7 was working fine. I couldn't find the file "libmylib.so". The ndk-build throws the following output.

    ~/workspace/MyFfmpegTest/jni$ sudo /opt/android-ndk-r8c/ndk-build
    /opt/android-ndk-r8c/build/core/add-application.mk:128: Android NDK: WARNING: APP_PLATFORM android-14 is larger than android:minSdkVersion 8 in /home/[...]/workspace/MyFfmpegTest/AndroidManifest.xml
    Compile thumb : mylib <= mylib.c
    /home/[...]/workspace/MyFfmpegTest/jni/mylib.c: In function 'Java_com_example_myffmpegtest_MainActivity_logFileInfo':
    /home/[...]/workspace/MyFfmpegTest/jni/mylib.c:19:5: warning: 'av_open_input_file' is deprecated (declared at /home/[...]/workspace/MyFfmpegTest/jni/ffmpeg/libavformat/avformat.h:1090) [-Wdeprecated-declarations]
    Prebuilt : libavformat.a <= jni/../obj/local/armeabi/
    cp: »/home/[...]/workspace/MyFfmpegTest/jni/../obj/local/armeabi/libavformat.a“ und »/home/[...]/workspace/MyFfmpegTest/obj/local/armeabi/libavformat.a“ sind die gleiche Datei
    make: *** [/home/[...]/workspace/MyFfmpegTest/obj/local/armeabi/libavformat.a] Error 1

    ОтветитьУдалить
    Ответы
    1. I had that same error and I fixed it by changing the Android.mk file to the following:

      LOCAL_PATH := $(call my-dir)

      include $(CLEAR_VARS)

      LOCAL_LDLIBS = -L$(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-arm/usr/lib -L$(LOCAL_PATH)/../obj/local/armeabi/ -lavformat -lavcodec -lpostproc -lswscale -lavutil -llog -ljnigraphics -lz -ldl -lgcc
      LOCAL_C_INCLUDES += $(LOCAL_PATH)/ffmpeg
      LOCAL_SRC_FILES := mylib.c
      LOCAL_CFLAGS := -march=armv7-a -mfloat-abi=softfp -mfpu=neon
      LOCAL_MODULE := mylib

      include $(BUILD_SHARED_LIBRARY)

      LOCAL_PATH := $(call my-dir)
      LOCAL_C_INCLUDES += $(LOCAL_PATH)/ffmpeg
      include $(all-subdir-makefiles)

      Удалить
  7. Now is it possible to build this library on Windows? If yes how ?

    ОтветитьУдалить
    Ответы
    1. That's not hard to do. And you can find a lot of information how to build ffmpeg on Windows or on Linux OS. Actually you can take some ready-made build. This is the first link I've googled about it.

      Удалить
  8. Thank for your tut. I built successfully. I see "File was opened" but I can't see my video in emulator. Can you tell me why?

    ОтветитьУдалить
    Ответы
    1. dungnt, I'm afraid I can't. I think we want too much from the emulator.

      Удалить
    2. Hi
      I have a problem. I want to extract frame from a video file using ffmpeg on android but i can't do that. Can you help me?
      Thank you!

      Удалить
  9. Thanks for the helpful instructions for building the 0.8 version FFMpeg. But while running the sample app, i am not able to open image files like jpeg files with the av_open_input_file api call.It always returns a 0, indicating its inability to open the image file.

    I tried using the same build script to build the FFMpeg 1.0 library, but i get a following build error "target file 'clean' has both : and :: entries. stop", please let me know if there's a way to resolve this, i tried different things but without any success yet on this build.

    ОтветитьУдалить
    Ответы
    1. SKC, zero is OK. It means that the file is opened. And error codes are non-zero. Check this.

      Удалить
    2. Same problem here, I get "target file 'clean' has both : and :: entries. stop". Any idea how to solve it?

      Удалить
  10. There's was an intersting comment on the Russian version of this post: "You may want to check this project http://sourceforge.net/p/ffmpeg4android".

    ОтветитьУдалить
  11. I am facing the following issues while compiling the sources as per your advices. Please help me to over come this issue.


    install: cannot open `/cygdrive/E/Rajesh_Android_Backup/FFMPEG/2013/ffmpegtest/FFmpegTest/obj/local/armeabi-v7a/libffmpeg.so' for reading: Permission denied
    /cygdrive/d/Android_NDK/android-ndk-r5/build/core/build-binary.mk:305: recipe for target `/cygdrive/E/Rajesh_Android_Backup/FFMPEG/2013/ffmpegtest/FFmpegTest/libs/armeabi-v7a/libffmpeg.so' failed


    make: *** [/cygdrive/E/Rajesh_Android_Backup/FFMPEG/2013/ffmpegtest/FFmpegTest/libs/armeabi-v7a/libffmpeg.so] Error 1

    ОтветитьУдалить
  12. I am unable to configure the files..am getting arm-linux-androideabi-pkg-config not found error...can you pls help me in solving this?

    ОтветитьУдалить
  13. Hi..Thanks to the tutorial and it worked like a charm...Can u pls provide me some hints of how to play a media file using ffmpeg in android? Thanks in advance...

    ОтветитьУдалить
  14. Hi Dimitry,

    Thanks for the great tutorial. After I load the library, how can I call ffmpeg command line with options? Do I have to do it in JNI?

    Thanks,
    Alex

    ОтветитьУдалить
  15. Hi
    thanks i load the library but when i call logFileInfo("") its give me
    java.lang.UnsatisfiedLinkError: logFileInfo

    ОтветитьУдалить
  16. Hello Everyone,

    i want to compile ffmpeg on android but when i want to execute ./build4android.sh in cygwin then i found the error is:

    ./build4android.sh
    Old conf.sh has been removed.
    configuring...
    /cygdrive/d/android-ndk-r8d/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/arm-linux-androideabi-gcc is unable to create an executable file.
    C compiler test failed.

    If you think configure made a mistake, make sure you are using the latest
    version from Git. If the latest version fails, report the problem to the
    ffmpeg-user@ffmpeg.org mailing list or IRC #ffmpeg on irc.freenode.net.
    Include the log file "config.log" produced by configure as this will help
    solving the problem.
    configure failed
    modifying the config.h...
    removing static functions in libavutil/libm.h...
    modifying Makefiles...
    generating av.mk in ffmpeg...
    start ndk-building...
    Compile thumb : avformat <= allformats.c
    In file included from jni/ffmpeg/libavformat/avformat.h:201:0,
    from jni/ffmpeg/libavformat/allformats.c:21:
    jni/ffmpeg/libavformat/avio.h: In function 'avio_printf':
    jni/ffmpeg/libavformat/avio.h:260:55: error: expected declaration specifiers before 'av_printf_format'
    In file included from jni/ffmpeg/libavformat/allformats.c:21:0:
    jni/ffmpeg/libavformat/avformat.h:205:28: fatal error: libavutil/time.h: No such file or directory
    compilation terminated.
    /cygdrive/d/android-ndk-r8d/build/core/build-binary.mk:266: recipe for target `obj/local/armeabi/objs/avformat/allformats.o' failed
    make: *** [obj/local/armeabi/objs/avformat/allformats.o] Error 1


    Please help me.
    Thanks

    ОтветитьУдалить
  17. Hi,
    This is very helpful post.
    Do you know if it can be use to convert 440Hz music to 432Hz music?
    Thanks in advance

    ОтветитьУдалить
  18. Thanks for the post. After trying several posts, this one helped me to create ffmpeg .so smoothly. Could get the demo also easily. Thanks for the step-by-step, clear instructions. I would recommend this post to anyone trying to do this activity.

    ОтветитьУдалить
  19. Thanks for your useful information to build ffmpeg on android. I tried out your sample application, it s working fine...

    ОтветитьУдалить
    Ответы
    1. Hi..Did you get it worked? Can you help me regarding my error "mktemp.exe has stopped working" while running "build4android.sh" script.

      Oam

      Удалить
  20. Hi.. I get "mktemp.exe has stopped working" while running "build4android.sh" script. I am stuck with this, please help me rectify it.

    Oam

    ОтветитьУдалить
  21. Hi thanks for this big tutorial

    when i have tried this i got this errors

    cc1: error: unrecognized command line option '-mfloat-abi=softfp'
    cc1: error: unrecognized command line option '-mfpu=neon'
    /home/ubuntu/workspace/MyFfmpegTest/jni/mylib.c:1:0: error: bad value (armv7-a) for -march= switch
    make: *** [/home/ubuntu/workspace/MyFfmpegTest/obj/local/x86/objs/mylib/mylib.o] Error 1

    Thanks for your suggestion

    ОтветитьУдалить
  22. use flag f with rm, because you should approve each deletion operation.

    find ~/robot-mitya/Android/MyFfmpegTest/jni/ffmpeg/ -type f -not \( -name "*.asm" -or -name "*.h" -or -name "*.S" \) -exec rm -f {} \;

    ОтветитьУдалить
  23. hello,
    I want to merge IMAGE + AUDIO and convert them into video using FFMPEG library,i compiled the library successfully as you mentioned in this link,and got libfmpeg.so.but getting problem to execute the ffmpeg command through java code.This is command which i am using...
    "ffmpeg -i image8.jpg -i file.m4a -acodec copy test.mp4"

    if i execute this ffmpeg command through CMD,my test.mp4 file is successfully created,but if exceute same command through my Activity,it doesnot create any file.
    Got Error- JAVA.IO.EXCEPTION: Error running exec().command:
    i thing,this is execution permission problem,,,,plzz help me,,,

    ОтветитьУдалить
  24. Hey can you please tell, how to play that video using FFmpeg??

    ОтветитьУдалить
  25. Can we do this on windows say using Cygwin or Mingw. Please give some details

    ОтветитьУдалить
  26. I want to stream multicast url(UDP/RTMP). How to do it ?
    Please help.

    ОтветитьУдалить
  27. Example . Streaming url : udp://@225.1.1.11:30000
    How to do it ?

    ОтветитьУдалить
  28. Thank you for your help, i can compile and have video and audio in my project, but i have one question, when a reproduce a video in my android device the audio is not synchronize with video, this is in android 4.2, but when i reproduce the video in android 2.3 the video and audio is very slow, do you have some idea?

    thank you for your support

    ОтветитьУдалить
  29. I have done with all steps:
    it also print on the Logcat.....

    04-08 19:20:09.999: I/mylib(26025): File was opened
    04-08 19:20:09.999: I/mylib(26025): File '/sdcard/VIDEO0050.mp4', Codec mov,mp4,m4a,3gp,3g2,mj2

    Now what is its use.... i can't understand...plz help us.

    thanks in advance

    ОтветитьУдалить
  30. After like million attempts from examples all around the internet, this one finally compiled and build successfully. You deserve a thanx man. :)

    ОтветитьУдалить