Привычная для меня
среда обитания — Windows. И вдруг оказывается,
что компиляция ffmpeg под Android в операционной
системе Windows невозможна. Нет, вести
разработку с применением откомпилированной
библиотеки и заголовочных файлов ffmpeg
можно, но чтобы получить эту библиотеку
придётся развёртывать Linux. Может я
излишне категоричен, и кому-то это
удавалось, но я таких примеров не
встретил. Наоборот есть много повисших
в воздухе вопросов на форумах. Общее
направление рекомендаций сводится к
переходу на Linux.
5. Там же, в jni создаём файл Android.mk:
6. Компилируем динамическую библиотеку libmylib.so с помощью Android NDK. Для этого запускаем терминал, переходим в папку …/MyFfmpegTest/jni и выполняем команду:
~/android-ndk/ndk-build.
Библиотека скомпилирована, для демонстрации осталось немного подкрутить активити нашего Android-приложения. Добавляем несколько строк в активити:
Файл, естественно, укажите какой-нибудь свой. Запускал приложение я сразу на телефоне. В окне LogCat (тег "mylib") проскочили две замечательные строчки, после чего я стал светиться как медный таз:
Путь к этим двум строчкам дался мне с трудом.
В ходе своего поиска пути решения задачи передачи видео от Android к компьютеру, я пытался найти и альтернативные варианты. Они есть и я их рассматривал:
На всякий случай вот ссылки на скрипт build4android.sh конфигурирования и компиляции ffmpeg и тестовый проект MyFfmpegTest.
И последнее, что я обязан сказать... Огромное спасибо Дарье Ряжских за её статью «Собираем ffmpeg для Android» и Guo Mingyu (за прекрасную идею и прообраз моего скрипта конфигурирования и компиляции ffmpeg вместо кучи ручных операций), хоть эти люди меня и не знают. Мой труд сводился только к «осовремениваю» их работы и расширению конфигурации ffmpeg. Но поверьте, мне этого более чем хватило.
Пришлось устанавливать
Ubuntu и настраивать в ней среду разработки.
Об этом я писал в своей статье «Обустройство в Ubuntu».
Установка Android NDK
Загрузка и установка Android NDK подробно описаны тут. Я использовал Android NDK, Revision 7c (April 2012): android-ndk-r7c-linux-x86.tar.bz2
Внутри архива папка «android-ndk-r7c». Можно просто разархивировать её в Домашнюю папку. Я ещё переименовал её в «android-ndk».
Компиляция ffmpeg
В Eclipse надо cоздать новый Android-проект и добавить в него папку jni.
Называю проект «MyFfmpeg». При создании выбираю «build target» Google APIs 2.3.3 (level 10). Затем:
И Finish.
Далее в проект добавляем
папку jni:
Со страницы загрузки ffmpeg я скачал архив стабильного релиза FFmpeg 0.8.11 "Love", разархивировал во временный каталог, переименовал папку «ffmpeg-0.8.11» в «ffmpeg» и прямо drag&drop-ом перенёс её в папку jni моего проекта в Eclipse.
"Love" — самая поздняя версия, которую мне удалось откомпилировать. Я пробовал версии FFmpeg 0.9.1 "Harmony", FFmpeg 0.10 "Freedom" и FFmpeg 0.10.2 "Freedom", но безрезультатно. Получаю ошибку компиляции «error: libavcodec/codec_names.h: No such file or directory». Причём не работает именно компиляция средствами Android NDK. Описание этого бага я нашёл здесь. Решения пока нет (на сегодняшний день уже три месяца). Думаю, эта проблема решаема, но и я не стал сильно упираться — меня вполне устраивает и версия 0.8.11.
Далее файлу …/MyFfmpeg/jni/ffmpeg/configure необходимо установить атрибут разрешения исполнения как программы.
Для конфигурирования ffmpeg и компиляции библиотеки создадим скрипт "build4android.sh" в каталоге «…/MyFfmpeg/jni/ffmpeg». Идею написания такого скрипта я подсмотрел в одном проекте с открытым кодом. Вот текст моего "build4android.sh":
#!/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.
Не забываем установить атрибут исполнения для этого скрипта!
Запускаю терминал и перехожу в каталог …/MyFfmpeg/jni/ffmpeg. Выполняю команду:
./build4android.sh
Sudo запросит пароль пользователя, а дальше жду. Долго. На моём ноутбуке компиляция заняла 13 минут.
В процессе компиляции будет довольно много предупреждений, но с ними надо смириться. Это вопрос к разработчикам ffmpeg, как я понимаю.
Демонстрация работы
Итак, на предыдущем шаге Android NDK откомпилировал нам библиотеку, в результате чего в нашем проекте MyFfmpeg появились папки …/MyFfmpeg/libs и …/MyFfmpeg/obj. Последняя пригодится в дальнейшем. Для демонстрации использования откомпилированной под Android библиотеки, создадим отдельный проект, в котором будем вызывать функции этой библиотеки.
Говорят, желающие могут на этом шаге вернуться в Windows. Я желающий, но пока остался в Ubuntu.
Новый проект пусть будет называться MyFfmpegTest. После его создания выполняем следующие действия:
1. Копируем в него папку obj из проекта MyFfmpeg.
2. Создаём
папку …/MyFfmpegTest/jni. Здесь будет наш
код-обёртка, написанный на C.
3. Копируем
в папку jni заголовочные файлы ffmpeg.
Точнее, я скопировал в jni всю папку
…/MyFfmpeg/jni/ffmpeg, а затем почистил её,
оставив только файлы с расширением h,
S и asm. Для этого в терминале выполнил такую команду:
4. В папке jni создаём файл mylib.c следующего содержания:
find ~/robot-mitya/Android/MyFfmpegTest/jni/ffmpeg/ -type f -not \( -name "*.asm" -or -name "*.h" -or -name "*.S" \) -exec rm {} \;ОСТОРОЖНО: команда удаляет все файлы кроме *.asm, *.h и *.S во всех подкаталогах пути, указанного первым параметром.
4. В папке jni создаём файл mylib.c следующего содержания:
#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; }
5. Там же, в jni создаём файл Android.mk:
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)
6. Компилируем динамическую библиотеку libmylib.so с помощью Android NDK. Для этого запускаем терминал, переходим в папку …/MyFfmpegTest/jni и выполняем команду:
~/android-ndk/ndk-build.
Библиотека скомпилирована, для демонстрации осталось немного подкрутить активити нашего Android-приложения. Добавляем несколько строк в активити:
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"); } }
Файл, естественно, укажите какой-нибудь свой. Запускал приложение я сразу на телефоне. В окне LogCat (тег "mylib") проскочили две замечательные строчки, после чего я стал светиться как медный таз:
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
Путь к этим двум строчкам дался мне с трудом.
Заключение
Сейчас всё выглядит не так уж и сложно, но на компиляцию ffmpeg я потратил уйму сил и времени: пришлось развёртывать невиданную мной ранее Ubuntu, осмысливать Android NDK, искать, искать и искать в интернете крохи информации о компиляции ffmpeg под Android.В ходе своего поиска пути решения задачи передачи видео от Android к компьютеру, я пытался найти и альтернативные варианты. Они есть и я их рассматривал:
- Есть libav. Это «форк» от ffmpeg. Есть мнение, что он лучше, но информации по нему ещё меньше, чем по ffmpeg.
- Я встречал проекты под Android с открытым исходным кодом, реализующие передачу видео и аудио по протоколу SIP. Самый известный — Sipdroid. Он даже самостоятельно реализует протокол RTP. Я, конечно, заглянул в исходники и сразу вернулся к идее об ffmpeg.
- Я нашёл платный SDK под Android, предназначенный для работы с видео, аудио и SIP. Но он использует ffmpeg. Причём старый — я смотрел исходный код. Стоимость я не выяснил, документацию не нашёл, но по крайней мере, есть у кого её запросить.
- Откомпилировать исполняемый файл ffmpeg, а не библиотеку, и работать с ним из моего приложения. Тем более, что работа с ffmpeg из командной строки описана в интернете вполне сносно. Решение какое-то корявое, мне кажется.
- Использовать бесплатное приложение IP Webcam. Прекрасный вариант, но уж больно мне хотелось реализовать всё полностью в моём приложении (ffmpeg не в счёт). Работа с ffmpeg это полезный опыт, который пригодится мне в будущем. Тем более, посмотрите, сколько тем пришлось уже для этого поднять.
- И самый запасной вариант. Если у меня не получится передача видео, я вполне могу организовать передачу изображений. По моим расчётам, на 5 кадров в секунду вполне можно рассчитывать. Но очень уж хочется потокового видео.
На всякий случай вот ссылки на скрипт build4android.sh конфигурирования и компиляции ffmpeg и тестовый проект MyFfmpegTest.
И последнее, что я обязан сказать... Огромное спасибо Дарье Ряжских за её статью «Собираем ffmpeg для Android» и Guo Mingyu (за прекрасную идею и прообраз моего скрипта конфигурирования и компиляции ffmpeg вместо кучи ручных операций), хоть эти люди меня и не знают. Мой труд сводился только к «осовремениваю» их работы и расширению конфигурации ffmpeg. Но поверьте, мне этого более чем хватило.
Дмитрий Дзаховв
спасибо за информацию, давно слежу за ffmpeg для андроида
ОтветитьУдалитьВ скриптах лучше исправить /home/dmitrydzz/ на ~/
ОтветитьУдалить~/ - домашняя папка текущего пользователя. В итоге тем, кто будет использовать твой скрипт не понадобится его править.
проще было использовать cygwin для сборки из под Windows.
ОтветитьУдалитьОчень сомневаюсь. Перед тем, как я решился связаться с Ubuntu, я искал как бы откомпилироваться из-под Windows. Я знаю о Cygwin, но ни одного успешного примера компиляции ffmpeg под Android в Windows я не встретил. Наоборот, только вопросы как бы это сделать и ответы, что это невозможно.
УдалитьСейчас опять погуглил... Кажется, тут что-то изменилось, вот пример: http://ffmpeg.org/pipermail/ffmpeg-user/2012-April/005973.html
Апрель 2012 года. В это время я уже сидел глубоко в Ubuntu. Здорово, если теперь компилировать ffmpeg можно не выходя из Windows. Правда, по-прежнему, статей "как я собрал ffmpeg под Windows" я не вижу.
Добрый день.
ОтветитьУдалитьЕсть вопросик.
Скомпилировать ffmpeg получилось.
Скомпилировать пример тоже получилось.
Но при запуске тестового проекта в эмуляторе ничего похожего на
File was opened
File '/sdcard/VIDEO0050.mp4', Codec mov,mp4,m4a,3gp,3g2,mj2
нет.
Есть только:
05-17 12:18:54.732: D/dalvikvm(336): Trying to load lib /data/data/my.test/lib/libmylib.so 0x405140f8
05-17 12:18:54.830: I/ARMAssembler(70): generated scanline__00000177:03515104_00001002_00000000 [ 87 ipp] (110 ins) at [0x445ed520:0x445ed6d8] in 1531341 ns
05-17 12:18:54.920: D/dalvikvm(336): Added shared lib /data/data/my.test/lib/libmylib.so 0x405140f8
05-17 12:18:54.920: D/dalvikvm(336): No JNI_OnLoad found in /data/data/my.test/lib/libmylib.so 0x405140f8, skipping init
потом куча дебаг сообщений и в конце:
05-17 12:18:57.630: D/Zygote(33): Process 336 terminated by signal (4)
05-17 12:18:57.643: I/ActivityManager(70): Process my.test (pid 336) has died.
Что я делаю не так?
И вопрос, а можно как то использовать ffmpeg как из командной строки? Потому как от С я далек, а описания API толкового так нигде и не нашел :(
Вы знаете, я почему-то не пробовал запускать это тестовое приложение в эмуляторе. Отлаживался сразу на своём аппарате.
УдалитьЕсть ли у Вас возможность проверить на физическом устройстве? Подозреваю, что на провал в эмуляторе могут влиять флаги компиляции ffmpeg. Там есть несколько волшебных слов типа "neon" и "armv7-a". Возможно эмулятор не может справиться с ними.
К сожалению, не могу сейчас проверить эту свою теорию - в ближайшие несколько дней Ubuntu у меня не будет. Я сейчас окопался в другом проекте.
Напишите, пожалуйста, если что-то получится. Мне очень интересно. Если что, я готов буду вернуться к Вашему вопросу. Дело в том, что подобный вопрос мне задали в английском варианте этого поста (по почте, кажется), а посмотреть что к чему возможности сейчас нет.
Пока такой возможности нет :(
УдалитьБуду играться с конфигурацией компиляции ffmpeg.
А не подскажите по второму вопросу?
На stackovrflow по этому поводу вот что есть:
==============================
If you just wanted to make a call to ffmpeg as function rather than a system call, you can do that pretty easily.
in ffmpeg.c, change:
int main(int argc, char **argv) to int ffmpeg((int argc, char **argv)
Then in your call the ffmpeg function and pass in an array that mimics the command line.
==================================
вроде все просто, и все собралось, но вот как вызвать этот ffmpeg и передать ему параметры?
Да, извините, забыл про второй вопрос.
УдалитьНаправление я понимаю, а вот сделать такое самостоятельно пока не пытался. Надо будет с типами данных разбираться.
Так же, как и в примере в посте, Вы должны будете сделать в папке jni файл с расширением С, содержащий функцию-обёртку наподобие функции из примера Java_ru_dzakhov_ffmpeg_test_MainActivity_logFileInfo. Функцию можно добавить в mylib.c. Типы данных в этой функции уже будут из NDK ().
Очень прошу Вас потом поделиться опытом и исходником. Тема довольна актуальна, когда смотрю статистику по блогу у этого поста много просмотров. Я пока не могу продолжить свои изыскания, поэтому буду очень признателен, если Вы поделитесь накопленным опытом здесь в комментариях.
Здравствуйте, вроде разобрался как откомпилировать под эмулятор (я пробовал под 2.1 и под древним HTC Magic)
Удалитьиз скрипта build4android.sh убрать строку
--prefix=./android/armv7-a \
из скрипта android.mk убрать _все_ строки
LOCAL_CFLAGS := -march=armv7-a -mfloat-abi=softfp -mfpu=neon
Если надо, сделать build4android заново.
думаю что это отключит оптимизации, но по крайней мере будет работать везде.
пробовал скомпилировать на ubuntu 64 ничего не получилось, на 32 все ок
ОтветитьУдалитьЗдравствуйте,
ОтветитьУдалитькто нибудь подскажите, как откомпилить ffmpeg так что бы можно было в коде работать как будто с консолью. Например задать что то типа
char *params[] = {"ffmpeg", "-param1",param1,"param2", "param2" ,};
ffmpeg(5, params);
Данный код я взял из головы.
Не получается у меня скомпилировать ffmpeg.c Вываливается с 1000 и одной ошибкой.
Собрал на Cygwin (win7x64)...
ОтветитьУдалитьffmpeg 0.11.1, ndk8
Если кто решится - никому не советую.
Удивительная вещь, которую я обнаружил-это то, что gcc не видит имена в linux-формате, а ld в windows формате. Никак не смог это побороть. Отключил скрипты для линкера (кажется, у автора их тоже нет).
Пришлось вручную генерировать codec_names.h, так как ndk-build не хотел понимать перенаправление ввода-вывода в Android.mk (эта проблема описана в посте).
Плюс ко всему была проблема с #include в avutils. Там есть свой time.h, который и включал компилятор.
You may want to check this project
ОтветитьУдалитьhttp://sourceforge.net/p/ffmpeg4android
спасибо автору и ребятам, которые отвечали
ОтветитьУдалитьЭтот комментарий был удален автором.
ОтветитьУдалитьЭтот комментарий был удален автором.
УдалитьЭтот комментарий был удален автором.
Удалить