I want to upload video files to server and compress before uploading. I'm using ffmpeg libx264. I have seen viber can upload 30 second video file of size 78MB within a minute [reduce it's down to 2.3MB]. I want to know how do they do it so fast?
What I have tried so far -
FFMPEG version : n2.4.2
Built with gcc 4.8
Build Configuraiton : --target-os=linux --cross-prefix=/home/sb/Source-Code/ffmpeg-android/toolchain-android/bin/arm-linux-androideabi- --arch=arm --cpu=cortex-a8 --enable-runtime-cpudetect --sysroot=/home/sb/Source-Code/ffmpeg-android/toolchain-android/sysroot --enable-pic --enable-libx264 --enable-libass --enable-libfreetype --enable-libfribidi --enable-fontconfig --enable-pthreads --disable-debug --disable-ffserver --enable-version3 --enable-hardcoded-tables --disable-ffplay --disable-ffprobe --enable-gpl --enable-yasm --disable-doc --disable-shared --enable-static --pkg-config=/home/sb/Source-Code/ffmpeg-android/ffmpeg-pkg-config --prefix=/home/sb/Source-Code/ffmpeg-android/build/armeabi-v7a-neon --extra-cflags='-I/home/sb/Source-Code/ffmpeg-android/toolchain-android/include -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fno-strict-overflow -fstack-protector-all -mfpu=neon' --extra-ldflags='-L/home/sb/Source-Code/ffmpeg-android/toolchain-android/lib -Wl,-z,relro -Wl,-z,now -pie' --extra-libs='-lpng -lexpat -lm' --extra-cxxflags=
Command:
ffmpeg -y -i /storage/emulated/0/main.mp4 -s 480x320 -r 20 -c:v libx264 -preset ultrafast -c:a copy -me_method zero -tune fastdecode -tune zerolatency -strict -2 -b:v 1000k -pix_fmt yuv420p /storage/emulated/0/output.mp4
The result so far is, a 30second 78MB file gets compressed to 4.3MB which takes around 1min 28seconds. Here is the console dump - http://pastebin.com/rn81acGx . I mainly want to reduce the time it takes to compress. How can I achieve this?
Thanks in advance.
You'll have to use the hardware accelerated encoding capabilities of the device, if any. As far as I can tell
ffmpeg
doesn't offer HW accelerated encoding on Android. There is alibstagefright
but it's used for HW decoding.Depending on your target API version you may be able to use MediaCodec (API 16) to do HW encoding and MediaMuxer (API 18) to mux into
mp4
. If you manage to encode withMediaCodec
you could useffmpeg
to do the muxing part, which would require only API 16.x264 cpu capabilities
Your
ffmpeg
console output/log shows the following message from libx264:For your device I would expect something like:
You should re-evaluate how you compiled
x264
so it properly supports the capabilities of your CPU. Withnone
it encodes significantly slower.--disable-asm
configure option forx264
../configure
forx264
the console output should showasm: yes
.x264
. I see many users compiling old versions that may miss out on optimizations.ffmpeg
so it uses the newx264
. Make sureffmpeg
does not link to the wrongx264
if you have multiple versions.MediaCodec hardware acceleration
ffmpeg
currently supports hardware assisted H.264 and HEVC decoding via the MediaCodec API in Android which may help decrease the overall processing time. For more info and an up-to-date list of capabilities see FFmpeg Wiki: Hardware Acceleration.To use it ensure your
ffmpeg
is compiled with--enable-jni
and--enable-mediacodec
.