- Сборка библиотеки FFmpeg для Android приложения
- Somethings
- воскресенье, 19 сентября 2010 г.
- Собираем ffmpeg для Android
- Требования
- Процесс
- Создаем проект
- Получаем исходники ffmpeg
- Конфигурируем ffmpeg
- config.sh
- Адаптируем к NDK
- /jni/ffmpeg/av.mk
- /jni/Android.mk
- /jni/ffmpeg/Android.mk
- /jni/ffmpeg/libavformat/Android.mk
- /jni/ffmpeg/libavcodec/Android.mk
- Android.mk
- Компилируем
- А дальше?
- mylib.c
- Android.mk
- MainActivity.java
- Заключение
- Ссылки
- 18 комментариев:
- Build FFMPEG under Cygwin in Windows OS for Android
- Build FFmpeg for All Android architecture correctly
Сборка библиотеки FFmpeg для Android приложения
Есть не так много библиотек, которые позволяют добавить функционал ffmpeg в ваше Android приложение. А если говорить про отсутствие в проекте NDK, то количество вариантов практически стремится к нулю. Я давно уже познакомился с ffmpeg-android, которую собственно и использую в приложении Selfie Timelapse App, однако все чаще и чаще приходилось сталкиваться с проблемой практически нулевой поддержки разработчиков.
Так, к примеру, ковыряться с библиотекой пришлось впервые, когда понял, что размер проекта меня не устраивает (чуть меньше 30 мегабайт). Оказалось, что в aar файл зашит скомпилированный ffmpeg для архитектур ARM и x86. Так как последних довольно мало (по крайней мере устройства на этой архитектуре мне лично не встречались), то я решил удалить ее поддержку из проекта.
Размер готового файла при этом стал колебаться в районе 20 мегабайт.
После появилось желание обновиться до последней версии ffmpeg (в библиотеке зашита версия 3.0.1). Пришлось очень сильно гуглить, чтобы получить приемлемый результат.
Ниже предлагаю вашему вниманию пошаговую инструкцию как скомпилировать самому последнюю версию ffmpeg в aar файл, который вы сможете добавить в свой проект. Сразу укажу — я выполнял все на макбуке, какие будут результаты для других систем — не знаю.
- Следуйте инструкциям из этого репозитория https://github.com/Yelp/ffmpeg-android. В результате вы получите бинарник ffmpeg.
- Клонируйте репозиторий https://github.com/WritingMinds/ffmpeg-android-java. С его помощью вы получите готовый aar файл для конкретной архитектуры (бинарник для которой вы сделали на первом шаге).
- После разворачивания проекта выполните команду ./gradlew assembleRelease
- Нужную вам библиотеку AAR вы найдете в папке build/outputs/aar
Если на втором шаге вы получите ошибку
Error:(2, 0) No service of type Factory LoggingManagerInternal available in ProjectScopeServices.
То обновите версию для плагина android-maven-gradle-plugin. Узнать последнюю версию вы сможете в репозитории плагина https://github.com/dcendents/android-maven-gradle-plugin
Кстати, размер AAR библиотеки после всех этих манипуляций еще больше уменьшился, в итоге проект стал весить меньше 10 мегабайт.
Somethings
problems and solutions
воскресенье, 19 сентября 2010 г.
Собираем ffmpeg для Android
Требования
- Какой-нибудь Linux. В моем случае был Ubuntu на VirtualBox. Я убежденный адепт Майкрософта, но на 64-битной винде мне ничего не удалось.
- Android SDK
- Android NDK r04b. Кстати, неплохо бы иметь о нем некоторое представление.
- Eclipse
Процесс
Создаем проект
Получаем исходники ffmpeg
Конфигурируем ffmpeg
config.sh
Адаптируем к NDK
Скрипт нагенерировал нам кучу файликов. Если бы мы писали под Linux, то делать бы ничего не пришлось. Но у нас Android, и поэтому нужно кое-что допилить.
- В файле /jni/ffmpeg/config.h поменять #define restrict restrict на #define restrict .
- В файле /jni/ffmpeg/libavutil/libm.h убрать все static-функции.
- В папках libavcodec , libavcore , libavfilter , libavformat , libavutil , libpostproc , libswscale из всех Makefile удалить строки:
Поместить в /jni/ffmpeg файл av.mk с текстом:
/jni/ffmpeg/av.mk
Создать в /jni/ файл Android.mk :
/jni/Android.mk
Создать в /jni/ffmpeg файл Android.mk :
/jni/ffmpeg/Android.mk
Создать в /jni/ffmpeg/libavformat файл Android.mk :
/jni/ffmpeg/libavformat/Android.mk
Создать в /jni/ffmpeg/libavcodec файл Android.mk
/jni/ffmpeg/libavcodec/Android.mk
Поместить в папки libavcore (к слову, в релизе такой папки нет), libavfilter , libavutil , libpostproc , libswscale по файлу Android.mk
Android.mk
Компилируем
А дальше?
mylib.c
Android.mk
MainActivity.java
Заключение
Ссылки
18 комментариев:
Дарья, вы — гений! Недавно ставилась задача слияния/конвертирования видео и мы не справились. даже как подступиться не придумали. теперь понятно — как надо было идти!
P.S. просто любопытно — а вы код будете открывать под GPL, дабы не нарушить лицензию?
Антон, так ведь: —enable-nonfree
Как я понял, ffmpeg можно собирать и под gpl и нет.
Тут главный момент в том, что ffmpeg распространяется под LGPL. Т.е. библиотеку можно линковать с приложением, распространяемым под любой лицензией
Вставлю свои пять копеек.
Тоже собирал ffmpeg под Android, но его возможности использовал не через API, а сделал обертку вокруг функции main и далее обращался к собранной либе как из командной строки. Это намного удобнее, т.к. документации по командам ffmpeg’а во много раз больше.
Кстати, господа, мне тут недавно сообщили, что по данной инструкции ffmpeg собирается только для NDK r4. А так как править ее я буду не раньше, чем снова столкнусь с подобной задачей, прошу иметь в виду и разбираться самостоятельно.
@darja
Насколько я помню — насчет собирается или нет не знаю, но вот то что уже собрано работало у меня с таким как у вас Abdroid.mk только в NDK 4 версии. Чтобы заработало в 5 вставил такую строку в Android.mk:
LOCAL_LDLIBS += -llog -lavformat -lavcodec -lavutil -lavcore -L/путь к файлам типа libavcodec.a и тд и тп
Вобщем теперь у меня работает в любой НДК:) Если что — надеюсь моя строка поможет
Да уж, попытка собрать по инструкции с ndk5 обошлась мне в 3 дня .
А есть продолжение файлика mylib.c, а то я как явер не знаю С++, а либа эта очень заинтересовала?
Народ, подскажите новичку. В сях я совсем не силен, но придется, похоже, разбираться с ffmpeg для Android.
Мне не понятен такой момент. Если библиотека компилируется для определенной архитектуры процессоров, то как насчет совместимости? Смартфоны то на разных процах постороены.
а где
env->ReleaseStringUTFChars(filename, str);
Вы пробовали запись аудио на OpenAl?
(не удалось alcCaptureOpenDevice с NULL именем)
Добавлю. Для того что бы оно собралось по ndk-r5 надо в файл /jni/ffmpeg/av.mk в флаги добавить -std=c99
полсе этого сам ffmpeg соберется. Далее все получившиеся *.a файлы складываем в папку jni/lib нашего проекта где мы будем использовать ffmpeg и изменяем приведенный в статье Anroid.mk на следующий
LOCAL_PATH := $(call my-dir)
LOCAL_MODULE := libavformat
LOCAL_SRC_FILES := lib/libavformat.a
LOCAL_MODULE := libavcodec
LOCAL_SRC_FILES := lib/libavcodec.a
LOCAL_MODULE := libpostproc
LOCAL_SRC_FILES := lib/libpostproc.a
LOCAL_MODULE := libswscale
LOCAL_SRC_FILES := lib/libswscale.a
LOCAL_MODULE := libavutil
LOCAL_SRC_FILES := lib/libavutil.a
LOCAL_LDLIBS += -llog
LOCAL_STATIC_LIBRARIES := libavformat libavcodec libpostproc libswscale libavutil
LOCAL_C_INCLUDES += $(LOCAL_PATH)/ffmpeg
LOCAL_SRC_FILES := mylib.c
LOCAL_MODULE := mylib
LOCAL_PATH := $(call my-dir)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/ffmpeg
include $(all-subdir-makefiles)
надеюсь кому-нибудь помог
А у кого-нибудь собралось в NDK без опции:
—disable-asm
Дело в том, что эта опция убирает все ARM-оптимизации процессора и код работает в разы медленнее, как минимум в 2 раза медленнее.
У меня, если убирается эта опция не компилится под NDK. Вываливается ошибка что такая-то ассемблерная команда не поддерживается выбранным процессором.
Есть какие-нибудь идеи как этого избежать?
Разобрался, cflags нужно продублировать в av.mk, тогда компилится нормально. С аппаратным ускорением, кстати, работает раз 5-6 быстрее чем в примере с опцией —disable-asm
Dima L. выложите свой конфиг с —disable-asm пожалуйста, никак не получается заставить компилироваться ffmpeg с этим параметром.
Добрый день.
Дарья, спасибо. По вашей статье таки собрал ffmpeg под android.
Но у меня есть вопрос:
jeck_landin пишет что написал обертку и теперь использует ffmpeg как из командной строки. Кто нибудь подскажет как это можно сделать? Что то я не разбирусь 🙁
А то перекопал кучу инфы но с API разбираться тяжело. я далек от СИ.
У меня благодаря Дарье получилось собрать FFMPEG в таком виде, для NDK r5 пришлось ещё пошаманить.
Для сборки с ARM-оптимизациями очень долго плясал с бубном, переделывая config.mak и config.h. Потом для включения ARM-версий исходников для libavcodec потребовалось кусок arm/Makefile переносить на верхний уровень.
Но когда всё собралось и слинковалось, ARM-оптимизация не очень помогла. avcodec_decode_video2() не ускорился и в 2 раза, sws_scale() для YUV->RGB как выполнялся 20 мс для VGA-кадра, так и продолжает (впрочем, в libswscale нет ARM-ветки кода, что странно). А ведь я ещё добавил опцию -ftree-vectorize.
Браво! Не «хило» так, как для убежденного адепта Майкрософта!
Может кому будет интересно в конфигурационном скрипте:
—extra-ldflags=»-Wl,-T,$PREBUILT/arm-eabi/lib/ldscripts/armelf.x -Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib $PREBUILT/lib/gcc/arm-eabi/4.4.0/crtbegin.o $PREBUILT/lib/gcc/arm-eabi/4.4.0/crtend.o -lc -lm -ldl»
Вся «лабуда» нивелируется аргументом -nostdlib, поэтому достаточно только указать эту опцию.
Но это не совсем хороший подход — юзать nostdlib.
Build FFMPEG under Cygwin in Windows OS for Android
For the past couple days, I have been trying hard to build FFMPEG for a Android project on Windows Operating System using android-ndk-14d using Cygwin. I have followed many tutorials out there, and I ahve encountered so many errors while building FFMPEG using build_android.sh.
Here are the steps that I have taken so far.
I downloaded Cygwin and configured all the dependencies that I need for building FFMPEG.
I opened ffmpeg-3.3.1/configure file with a text editor, and changed to the following lines.
my build_android.sh is as below
I ran these commands
and. currently getting this error
c:/users/sonic/appdata/local/android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/p rebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-an droideabi/bin/ld.exe: error: libavutil/libavutil.so:1:1: syntax error, unexpected ‘!’, exp ecting $end
c:/users/sonic/appdata/local/android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/p rebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-an droideabi/bin/ld.exe: error: libavutil/libavutil.so: not an object or archive collect2.exe: error: ld returned 1 exit status make: *** [library.mak:94: libswscale/libswscale-4.so] Error 1 LD
libswscale/libswscale-4.so c:/users/sonic/appdata/local/android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/p rebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-an droideabi/bin/ld.exe: error: libavutil/libavutil.so:1:1: syntax error, unexpected ‘!’, exp ecting $end
c:/users/sonic/appdata/local/android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/p rebuilt/windows-x86_64/bin/../lib/gcc/arm-linux->androideabi/4.9.x/../../../../arm-linux-an droideabi/bin/ld.exe: error: libavutil/libavutil.so: not an object or archive collect2.exe: error: ld returned 1 exit status make: *** [library.mak:94: libswscale/libswscale-4.so] Error 1
From the comments that were commented on the above link, it seems like it is easier to build FFMPEG in Linux/Unix OS. My first can be a dumb question. But If there is anyone who can guide me through this, i will be really appreciated it.
If I build FFMPEG on Linux for Android, could I possibly copy or move those resulted output (The arm/lib folder contains the shared libraries, while arm/include folder contains the header files for libavcodec, libavformat, libavfilter, libavutil, libswscale etc.) to Windows OS and utilize them for my Android project?
Since my company only provides Windows OS for a project, I have to utilize them on Windows OS.
Thank you for your time, and if there is any feedback that you can provide it will definitely be helpful.
Build FFmpeg for All Android architecture correctly
I built ffmpeg libraries for all android architecture. But some details are confusing my mind. First of all let me explain step by step how i built.
- I downloaded latest version of libx264 from https://www.videolan.org/developers/x264.html
- Created and run build_all.sh script (in x264 folder) for creating libs for (almost) all android platforms. Then i got android folder in x264 folder. e.g android/arm android/arm64 android/x86 android/x86_64 in x264 folder.
- I download the ffmpeg3.3.4 from https://ffmpeg.org/download.html
- I created 4 copies of ffmpeg3.3.4 folder. Named them with android architectures names. Like ffmpeg3.3.4-arm64 ffmpeg3.3.4-arm ffmpeg3.3.4-x86 ffmpeg3.3.4-x86_64
- Created build_(architecture-name).sh for each platforms of android. Than move each one of ‘named’.sh files to the named ffmpeg folders according to their architecture names. E.g build_android_x86.sh => ffmpeg3.3.4-x86
- Moved all ffmpeg3.3.4-arm64 ffmpeg3.3.4-arm ffmpeg3.3.4-x86 ffmpeg3.3.4-x86_64 folders to the NDK_PATH ( C:\Users\MyName\AppData\Local\Android\sdk\ndk-bundle )
- Put x264 folder at same level of hierarchy with ffmpeg folders in ( C:\Users\MyName\AppData\Local\Android\sdk\ndk-bundle )
- Run each of build_android_x86.sh , build_android_x86_64.sh .. scripts one by one in their own ffmpeg folder. Then i got android folders in ffmpeg folders. (created android folders have library folders) e.g ffmpeg3.3.4-x86/android/x86/(bin,inlude,lib,share)
Created Android.mk files for all created android folders and moved each one of them to android/armName folder. e.g Android.mk => ffmpeg3.3.4-x86/android/x86/
Create «arm named» folders e.g x86 x86_4 arm64 arm7 in jni folder of my project ( myproject/app/jni/x86 , myproject/app/jni/x86_64 ).
Go to ndk path open named ffmpeg folders one by one and copy ffmpeg.c ffmpeg_filter.c ffmpeg_opt.c cmdutils.c files from ffmpeg folders to the «arm named» folders. e.g ffmpeg.c => myproject/app/jni/x86
Created Android.mk file in my project.
Created Application.mk file in my project.
Created videoEdit.c than run ndk-build build command.
Built with no error. I can run ffmpeg commands but it takes too much time i think. E.g when i try to run hflip it flips the video with 15 seconds.
Code example :
FFmpeg Commands that runs on android, working very fast on emaulator but very slow on real device.
Also another thing to confusing my mind is output of ./configure command. When i open the (e.g) ffmpeg-3.3.4-arm64-v8a folder and run ./configure command in terminal. Output says ARCH x86 (generic) . For all platform output is the same ARCH x86 (generic) .
Output of ./configure command in ffmpeg-3.3.4-arm64-v8a folder
EDIT all of these steps made on ubuntu then moved all folders to the windows. So dont be confuse about paths.
With all of these steps i want to ask is, is there anything wrong on my steps. Should i follow any other way or not ? Why the ffmpeg is running slower on real device. I am wondering one thing badly, how retrica, snapchat, instagram recording video as mirrored flipping ? Are they flipping after recorded (if they are how are they doing this in a second) or are they recording a video as flipped in run time ? I guess building ffmpeg for android is bit messy and making wrong things is very easy. If you look my steps, questions and give me an advice, i will be much appreciated.