4

I am trying to reduce the video size captured by the default camera (it's generating high resolution video) in Android. Does FFMPEG have a property to encode a video with given resolution? I tried to Google, but all examples are using command line mode for FFMPEG.

My questions are:

  1. Can we use ffmpeg command line in Android?
  2. If not then how we will achieve it?
  3. Can we able record a video directly using ffmpeg in Android?
  4. Is there any other solution for this?
Bill the Lizard
  • 369,957
  • 201
  • 546
  • 842
Krishnendu
  • 1,129
  • 14
  • 24
  • http://stackoverflow.com/questions/7459183/interact-with-ffmpeg-from-a-net-program-write-input/7608163#7608163 – Miserable Variable Oct 11 '11 at 05:53
  • hi hemal, sorry i think the link you shared is for .net but i need it for android (JAVA). and you are trying to execute ffmpeg in command line. the thing is i know how to run command line methods in android but the problem is by default ffmpeg executable will not present in android device, so ffmpeg have to be part of my application and i think i have to call it natively. – Krishnendu Oct 11 '11 at 06:43
  • Oops, yes my previous answer was for .net. I don't know what you mean by calling natively, I would think you can use `ProcessBuilder`. The bigger issue is to get `ffmpeg` binaries on the device. You aught to be able to redistribute it, so you can bundle it with your app. – Miserable Variable Oct 11 '11 at 08:28
  • yes, i able to bundle ffmpeg with my app. but now the problem is i have to write a c/c++ code which will actually use the ffmpeg library and i will call that native c/c++ method from java. – Krishnendu Oct 11 '11 at 09:43
  • Can you not execute ffmpeg using `ProcessBuilder`? – Miserable Variable Oct 11 '11 at 11:33
  • no because by default ffmpeg will not be installed in android device. – Krishnendu Oct 11 '11 at 12:07
  • It does not have to be "installed by default" for you to be able to execute it using `ProcessBuilder`. Why can't you bundle it and execute it? – Miserable Variable Oct 11 '11 at 12:45
  • possible duplicate of http://stackoverflow.com/q/4725773/808940 which explains accessing FFMPEG via Java. Please use search before adding to the 30,000 other questions that we are struggling to clear up – Moog Oct 11 '11 at 14:47
  • Please @Krishnendu, did you get it? Please I need some indications in this issue... – Gonzalo Solera Sep 24 '13 at 21:32

1 Answers1

3

Compiling ffmpeg for android is possible, as well as running ffmpeg from command line. There's no need to delve into native code and jni calls unless you need more advanced usage than what the command line provides.

For reference, this is the shell script I run to compile ffmpeg (run under Ubuntu, it makes things a lot easier than windows)

#!/bin/bash


ANDROID_API=android-3
export ANDROID_NDK=${HOME}/android-ndk
export ANDROID_SDK=${HOME}/android-sdk
SYSROOT=$ANDROID_NDK/platforms/$ANDROID_API/arch-arm
ANDROID_BIN=$ANDROID_NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/*-x86/bin/
CROSS_COMPILE=${ANDROID_BIN}/arm-linux-androideabi-
export PATH=$PATH:$ANDROID_SDK/tools:$ANDROID_SDK/platform-tools

export ARM_ROOT=${HOME}android-ndk
export ARM_INC=$ARM_ROOT/platforms/android-5/arch-arm/usr/include
export ARM_LIB=$ARM_ROOT/platforms/android-5/arch-arm/usr/lib
export LIB_INC=${HOME}/include
export LIB_LIB=${HOME}/lib
CFLAGS=" -I$ARM_INC -fPIC -DANDROID -fpic -mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__  -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -DANDROID  -Wa,--noexecstack -MMD -MP "
LDFLAGS=" -nostdlib -Bdynamic  -Wl,--no-undefined -Wl,-z,noexecstack  -Wl,-z,nocopyreloc -Wl,-soname,/system/lib/libz.so -Wl,-rpath-link=$ARM_LIB,-dynamic-linker=/system/bin/linker -L$ARM_LIB -nostdlib $ARM_LIB/crtbegin_dynamic.o $ARM_LIB/crtend_android.o -lc -lm -ldl -lgcc "

FLAGS="--target-os=linux --enable-cross-compile --cross-prefix=$CROSS_COMPILE --arch=arm --prefix=$HOME --disable-shared --enable-static --extra-libs=-static --extra-cflags=--static --enable-small --disable-asm --disable-yasm --disable-amd3dnow --disable-amd3dnowext --disable-mmx --disable-mmx2 --disable-sse --disable-ssse3 --disable-indevs"
export CFLAGS=$EXTRA_CFLAGS
export LDFLAGS=$EXTRA_LDFLAGS
./configure $FLAGS --extra-cflags="$CFLAGS" --extra-ldflags="$LDFLAGS" \
--cc="${CROSS_COMPILE}gcc --sysroot=${SYSROOT}" --extra-ldflags="$LDFLAGS" \
--cxx="${CROSS_COMPILE}g++ --sysroot=${SYSROOT}" \
--nm="${CROSS_COMPILE}nm" \
--ar="${CROSS_COMPILE}ar"
make clean
make -j4 || exit 1
make install || exit 1

As for running ffmpeg, first you need to copy ffmpeg into your application's files directory, chmod 755 it using getRuntime.exec() as shown below, then run ffmpeg with the following line:

Process p = Runtime.getRuntime().exec("/data/data/yourpackagename/files/ffmpeg -i in.mp4 out.mp4")

Now, getting the camera's input to ffmpeg in a format it can understand is the tough bit, which I'm still trying to figure out. I've got a stackoverflow question going on the topic: Decode android's hardware encoded H264 camera feed using ffmpeg in real time

Community
  • 1
  • 1
joebobfrank
  • 945
  • 9
  • 13
  • hi thanks for reply. i done everything what you mentioned. i compile ffmpeg using your script, then copy it to application's files directory, chmod 755 it. upto this all is ok but when i try to call ffmpeg nothing happening it's not throwing any error neither it' generating the output file. – Krishnendu Oct 13 '11 at 10:08
  • Process p = Runtime.getRuntime().exec("/data/data/yourpackagename/files/ffmpeg -i in.mp4 out.mp4"); p.waitFor(); returning exit code 1 and i think that mean some internal error is occurring inside ffmpeg – Krishnendu Oct 13 '11 at 11:11
  • Well I can't share my code with you, but I can tell you if you want to find out what's going wrong you should create a datainputstream that takes the standard out and standard error streams of the ffmpeg process. Instead of running p.waitFor(), set up a some sort of loop to write the process output to somewhere you can read it. It's likely that ffmpeg just isn't finding the input, you can set a startup environment location in the getRuntime.exec command so that you can use relative directories like "in.mp4". – joebobfrank Oct 13 '11 at 14:52
  • thanks for reply. it's running now but the problem is it's just keep going on!. i gave a 9MB 3gp file as input and it's generating 0 byte file as output and just keep going on in background (wait 20 minutes). how much time it's taking for you – Krishnendu Oct 14 '11 at 06:15
  • Well are you getting the standard output/error streams to see what's happening? How long ffmpeg runs really depends on what operation you're doing, it can even run indefinitely if you have piped or streaming input, in which case you would have to close the process manually. – joebobfrank Oct 14 '11 at 17:46
  • well i am not getting any error and i am just converting one video in desired resolution – Krishnendu Oct 15 '11 at 17:59
  • Have you ever been success to use commands under android device ? it's very important to me. – iSun Mar 18 '12 at 15:33
  • Yes, if you can get the FFmpeg executable running on the phone you can use the command line in the same way you would on any linux environment. – joebobfrank Apr 02 '12 at 12:30
  • How could I get the FFmpeg executable?? Please, I need to succeed on it!! – Gonzalo Solera Sep 24 '13 at 21:30