2017-10-22 54 views
13

के लिए FFmpeg बनाएं, मैंने सभी एंड्रॉइड आर्किटेक्चर के लिए ffmpeg लाइब्रेरी बनाई हैं। लेकिन कुछ विवरण मेरे दिमाग को भ्रमित कर रहे हैं। सबसे पहले मुझे चरणबद्ध तरीके से बताएं कि मैंने कैसे बनाया।सभी एंड्रॉइड आर्किटेक्चर के लिए सही ढंग से

  • मैं https://www.videolan.org/developers/x264.html
  • बनाया से libx264 के नवीनतम संस्करण को डाउनलोड किया है और (लगभग) सभी एंड्रॉयड प्लेटफॉर्म के लिए libs बनाने के लिए (x264 फ़ोल्डर में) build_all.sh स्क्रिप्ट चलाने। तो मुझे x264 फ़ोल्डर में android फ़ोल्डर मिला। उदाहरण के लिए x1264 फ़ोल्डर में android/armandroid/arm64android/x86android/x86_64
  • मैं ffmpeg3.3.4https://ffmpeg.org/download.html से
  • मैं ffmpeg3.3.4 फ़ोल्डर की 4 प्रतियां बनाई डाउनलोड करें। उन्हें एंड्रॉइड आर्किटेक्चर नामों के साथ नामित किया गया। ffmpeg3.3.4-arm64ffmpeg3.3.4-armffmpeg3.3.4-x86ffmpeg3.3.4-x86_64
  • एंड्रॉइड के प्रत्येक प्लेटफॉर्म के लिए build_ (आर्किटेक्चर-नाम) .sh बनाया गया। उनके आर्किटेक्चर नामों के अनुसार 'named'.sh files नामित ffmpeg फ़ोल्डरों में से प्रत्येक को स्थानांतरित करने की तुलना में। जैसे build_android_x86.sh =>ffmpeg3.3.4-x86

build_android_arm64.sh उदाहरण

#!/bin/bash 
#Change NDK to your Android NDK location 
NDK=$HOME/Android/Sdk/ndk-bundle 
PLATFORM=$NDK/platforms/android-21/arch-arm64/ 
PREBUILT=$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64 

GENERAL="\ 
--enable-small \ 
--enable-cross-compile \ 
--extra-libs="-lgcc" \ 
--arch=aarch64 \ 
--cc=$PREBUILT/bin/aarch64-linux-android-gcc \ 
--cross-prefix=$PREBUILT/bin/aarch64-linux-android- \ 
--nm=$PREBUILT/bin/aarch64-linux-android-nm \ 
--extra-cflags="-I../x264/android/arm64/include" \ 
--extra-ldflags="-L../x264/android/arm64/lib" " 

MODULES="\ 
--enable-gpl \ 
--enable-libx264" 



function build_arm64 
{ 
    ./configure \ 
    --logfile=conflog.txt \ 
    --target-os=linux \ 
    --prefix=./android/arm64-v8a \ 
    ${GENERAL} \ 
    --sysroot=$PLATFORM \ 
    --extra-cflags="" \ 
    --extra-ldflags="-lx264 -Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib -lc -lm -ldl -llog" \ 
    --enable-shared \ 
    --disable-static \ 
    --disable-doc \ 
    --enable-zlib \ 
    ${MODULES} 

    make clean 
    make 
    make install 
} 

build_arm64 


echo Android ARM64 builds finished 
  • ffmpeg फ़ोल्डरों के साथ पदानुक्रम के एक ही स्तर पर NDK_PATH (C:\Users\MyName\AppData\Local\Android\sdk\ndk-bundle)
  • रखो x264 फ़ोल्डर में सभी ffmpeg3.3.4-arm64ffmpeg3.3.4-armffmpeg3.3.4-x86ffmpeg3.3.4-x86_64 फ़ोल्डरों ले जाया गया में (C:\Users\MyName\AppData\Local\Android\sdk\ndk-bundle)
  • build_android_x86.sh, build_android_x86_64.sh प्रत्येक को चलाएं .. अपने स्वयं के ffmpeg फ़ोल्डर में एक-एक करके स्क्रिप्ट करें। तो मुझे ffmpeg फ़ोल्डर्स में android फ़ोल्डर्स मिला। (बनाया android फ़ोल्डरों पुस्तकालय फ़ोल्डर) , उदा, ffmpeg3.3.4-x86/android/x86/(bin,inlude,lib,share)
  • बनाया Android.mk सभी के लिए फ़ाइलों android फ़ोल्डरों बनाया है और उनमें से हर एक में ले जाया गया Android के लिए/armName फ़ोल्डर। उदाहरण के लिए: Android.mk =>ffmpeg3.3.4-x86/android/x86/

    LOCAL_PATH:= $(call my-dir) 
    
    include $(CLEAR_VARS) 
    LOCAL_MODULE:= libavcodec 
    LOCAL_SRC_FILES:= lib/libavcodec-57.so 
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include 
    include $(PREBUILT_SHARED_LIBRARY) 
    
    include $(CLEAR_VARS) 
    LOCAL_MODULE:= libavformat 
    LOCAL_SRC_FILES:= lib/libavformat-57.so 
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include 
    include $(PREBUILT_SHARED_LIBRARY) 
    
    include $(CLEAR_VARS) 
    LOCAL_MODULE:= libswscale 
    LOCAL_SRC_FILES:= lib/libswscale-4.so 
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include 
    include $(PREBUILT_SHARED_LIBRARY) 
    
    include $(CLEAR_VARS) 
    LOCAL_MODULE:= libavutil 
    LOCAL_SRC_FILES:= lib/libavutil-55.so 
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include 
    include $(PREBUILT_SHARED_LIBRARY) 
    
    include $(CLEAR_VARS) 
    LOCAL_MODULE:= libavfilter 
    LOCAL_SRC_FILES:= lib/libavfilter-6.so 
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include 
    include $(PREBUILT_SHARED_LIBRARY) 
    
    include $(CLEAR_VARS) 
    LOCAL_MODULE:= libswresample 
    LOCAL_SRC_FILES:= lib/libswresample-2.so 
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include 
    include $(PREBUILT_SHARED_LIBRARY) 
    
    include $(CLEAR_VARS) 
    LOCAL_MODULE := postproc 
    LOCAL_SRC_FILES := lib/libpostproc-54.so 
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include 
    include $(PREBUILT_SHARED_LIBRARY) 
    
    include $(CLEAR_VARS) 
    LOCAL_MODULE := avdevice 
    LOCAL_SRC_FILES := lib/libavdevice-57.so 
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include 
    include $(PREBUILT_SHARED_LIBRARY) 
    
  • बनाना फ़ोल्डरों, उदा, x86x86_4arm64arm7 JNI में अपने प्रोजेक्ट के फ़ोल्डर (myproject/app/jni/x86, myproject/app/jni/x86_64) "का नाम शाखा"।

  • जाओ पथ खुला नामित ffmpeg फ़ोल्डरों एक के बाद एक NDK और "बांह नाम" फ़ोल्डर में कॉपी ffmpeg फ़ोल्डरों से ffmpeg.cffmpeg_filter.cffmpeg_opt.ccmdutils.c फ़ाइलों के लिए। उदाहरण के लिए ffmpeg.c =>myproject/app/jni/x86

  • मेरी परियोजना में Android.mk फ़ाइल बनाई गई।

    LOCAL_PATH := $(call my-dir) 
    #$(warning $(LOCAL_PATH)) 
    
    include $(CLEAR_VARS) 
    LOCAL_MODULE := videoEdit 
    LOCAL_LDLIBS := -llog -ljnigraphics -lz -landroid 
    LOCAL_CFLAGS := -Wdeprecated-declarations 
    ANDROID_LIB := -landroid 
    
    $(info $(TARGET_ARCH_ABI)) 
    
    ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) 
        LOCAL_C_INCLUDES:=/Users/MyName/AppData/Local/Android/sdk/ndk-bundle/sources/ffmpeg-3.3.4-armeabi 
        LOCAL_SRC_FILES := videoEdit.c arm7/ffmpeg.c arm7/ffmpeg_filter.c arm7/ffmpeg_opt.c arm7/cmdutils.c 
        LOCAL_CFLAGS += -lx264 -Wl,--no-merge-exidx-entries 
    else 
    
        ifeq ($(TARGET_ARCH_ABI),arm64-v8a) 
          LOCAL_C_INCLUDES:=/Users/MyName/AppData/Local/Android/sdk/ndk-bundle/sources/ffmpeg-3.3.4-arm64-v8a 
          LOCAL_SRC_FILES := videoEdit.c arm64/ffmpeg.c arm64/ffmpeg_filter.c arm64/ffmpeg_opt.c arm64/cmdutils.c 
          LOCAL_CFLAGS += -funwind-tables -Wl,--no-merge-exidx-entries 
        else 
    
         ifeq ($(TARGET_ARCH_ABI),x86_64) 
           LOCAL_C_INCLUDES:=/Users/MyName/AppData/Local/Android/sdk/ndk-bundle/sources/ffmpeg3.3.4-x86_64 
           LOCAL_SRC_FILES := videoEdit.c x86_64/ffmpeg.c x86_64/ffmpeg_filter.c x86_64/ffmpeg_opt.c x86_64/cmdutils.c 
         else 
           LOCAL_C_INCLUDES:=/Users/MyName/AppData/Local/Android/sdk/ndk-bundle/sources/ffmpeg3.3.4-x86 
           LOCAL_SRC_FILES := videoEdit.c x86/ffmpeg.c x86/ffmpeg_filter.c x86/ffmpeg_opt.c x86/cmdutils.c 
         endif 
    
        endif 
    
    endif 
    
    LOCAL_SHARED_LIBRARIES := libavformat libavcodec libswscale libavutil libswresample libavfilter libavdevice libpostproc 
    
    include $(BUILD_SHARED_LIBRARY) 
    
    ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) 
    
        $(call import-module,ffmpeg-3.3.4-armeabi/android/armeabi-v7a) 
    
    else 
    
        ifeq ($(TARGET_ARCH_ABI),arm64-v8a) 
          $(call import-module,ffmpeg-3.3.4-arm64-v8a/android/arm64-v8a) 
        else 
    
         ifeq ($(TARGET_ARCH_ABI),x86_64) 
           $(call import-module,ffmpeg3.3.4-x86_64/android/x86_64) 
         else 
          $(call import-module,ffmpeg3.3.4-x86/android/i686-diasm) 
         endif 
    
        endif 
    
    endif 
    
  • मेरी परियोजना में application.mk फ़ाइल बनाई गई।

    APP_ABI := armeabi-v7a, arm64-v8a, x86_64, x86 
    APP_PLATFORM := android-14 
    
  • बनाया videoEdit.c से ndk-build निर्माण आदेश चला।

कोई त्रुटि के साथ बनाया गया। मैं ffmpeg कमांड चला सकता हूं लेकिन मुझे लगता है कि इसमें बहुत अधिक समय लगता है। उदा। जब मैं hflip चलाने की कोशिश करता हूं तो यह वीडियो को 15 सेकंड के साथ फ़्लिप करता है।

कोड उदाहरण:

JNIEXPORT jint JNICALL Java_com_name_app_library_VideoEditer_natives_VideoEditer_flipHorizontally 
(JNIEnv *env, jclass someclass, jstring inputFile, jstring outFile) { 

    int numberOfArgs = 14; 

    char** arguments = calloc(numberOfArgs, sizeof(char*)); 
    const char *in, *out; 

    in = (*env)->GetStringUTFChars(env, inputFile, 0); 
    out = (*env)->GetStringUTFChars(env, outFile, 0); 

    arguments[0] = "ffmpeg"; 
    arguments[1] = "-i"; 
    arguments[2] = in; 
    arguments[3] = "-c:v"; 
    arguments[4] = "libx264"; 
    arguments[5] = "-preset"; 
    arguments[6] = "ultrafast"; 
    arguments[7] = "-threads"; 
    arguments[8] = "5"; 
    arguments[9] = "-c:a"; 
    arguments[10] = "copy"; 
    arguments[11] = "-vf"; 
    arguments[12] = "hflip"; 
    arguments[13] = out; 

    int i; 
    for (i = 0; i < numberOfArgs; i++) { 
     log_message(arguments[i]); 
    } 
    log_message("Printed all"); 

    main(numberOfArgs, arguments); 
    free(arguments); 
    (*env)->ReleaseStringUTFChars(env, inputFile, in); 
    (*env)->ReleaseStringUTFChars(env, outFile, out); 

    return 0; 
} 

FFmpeg आदेश है कि एंड्रॉयड पर चलता है, emaulator पर बहुत तेजी से काम कर रहा है, लेकिन वास्तविक डिवाइस पर बहुत धीमी गति से।

मेरे दिमाग को भ्रमित करने के लिए एक और चीज ./configure कमांड का आउटपुट है। जब मैं (उदा। ffmpeg-3.3.4-arm64-v8a फ़ोल्डर खोलता हूं और टर्मिनल में ./configure आदेश चलाता हूं। आउटपुट ARCH x86 (generic) कहता है। सभी प्लेटफार्म आउटपुट के लिए एक ही ARCH x86 (generic) है।

./configure आदेश के आउटपुट में ffmpeg-3.3.4-arm64-v8a फ़ोल्डर

install prefix   /usr/local 
source path    . 
C compiler    gcc 
C library     glibc 
ARCH      x86 (generic) 
big-endian    no 
runtime cpu detection  yes 
yasm      yes 
MMX enabled    yes 
MMXEXT enabled   yes 
3DNow! enabled   yes 
3DNow! extended enabled yes 
SSE enabled    yes 
SSSE3 enabled    yes 
AESNI enabled    yes 
AVX enabled    yes 
XOP enabled    yes 
FMA3 enabled    yes 
FMA4 enabled    yes 
i686 features enabled  yes 
CMOV is fast    yes 
EBX available    yes 
EBP available    yes 
debug symbols    yes 
strip symbols    yes 
optimize for size   no 
optimizations    yes 
static     yes 
shared     no 
postprocessing support no 
network support   yes 
threading support   pthreads 
safe bitstream reader  yes 
texi2html enabled   no 
perl enabled    yes 
pod2man enabled   yes 
makeinfo enabled   no 
makeinfo supports HTML no 

External libraries: 
iconv   xlib 

संपादित ubuntu पर किए गए इन सभी चरणों को तो खिड़कियों के सभी फ़ोल्डर में ले जाया गया। तो पथ के बारे में भ्रमित मत हो।

इन सभी चरणों के साथ मैं पूछना चाहता हूं, क्या मेरे कदमों में कुछ भी गलत है। क्या मुझे किसी अन्य तरीके का पालन करना चाहिए या नहीं? असली डिवाइस पर ffmpeg धीमा क्यों चल रहा है। मैं एक बात बुरी तरह सोच रहा हूं, कैसे रेट्रीका, स्नैपचैट, इंस्टाग्राम रिकॉर्डिंग वीडियो प्रतिबिंबित फ्लिपिंग के रूप में? क्या वे रिकॉर्ड किए जाने के बाद फिसल रहे हैं (अगर वे एक दूसरे में ऐसा कर रहे हैं) या वे एक वीडियो रिकॉर्ड कर रहे हैं जैसे रन टाइम में फ़्लिप किया गया है? मुझे लगता है कि एंड्रॉइड के लिए ffmpeg का निर्माण थोड़ा गन्दा है और गलत चीजें बनाना बहुत आसान है। यदि आप मेरे कदम, प्रश्न देखते हैं और मुझे सलाह देते हैं, तो मुझे बहुत सराहना की जाएगी।

+0

मैं बिल्ड फ़ाइलों के आर्क में देखता हूं। साथ ही, क्या आप '$ (कॉल आयात-मॉड्यूल, एंड्रॉइड/cpufeatures) कॉल कर रहे हैं? आईआईआरसी, एनईओएन अनुकूलित कोड चालू करने के लिए इसकी आवश्यकता है। Https://github.com/DrKLO/Telegram/blob/master/TMessagesProj/jni/Android.mk –

+0

कौन सी फ़ाइल का निर्माण करें, क्षमा करें समझ में नहीं आया। क्या आपका मतलब libx264 की फाइल बनाना या ffmpeg फ़ाइल की फाइल बनाना है? – fthopkins

+0

आप सच हैं कि यह गायब है। मैं '$ (कॉल आयात-मॉड्यूल, एंड्रॉइड/cpufeatures) जोड़ दूंगा 'देखते हैं कि यह कैसे प्रभाव डालता है। – fthopkins

उत्तर

3
ARCH      x86 (generic) 

यह निश्चित रूप से गलत है, यह विशिष्ट वास्तुकला सूचीबद्ध करना चाहिए।

मुझे लगता है कि https://github.com/IljaKosynkin/FFmpeg-Development-Kit आपकी मदद करेगा, मैं पहले सभी प्रयासों पर सही ढंग से सभी आर्किटेक्चर बनाने में सक्षम था। आप कमांड लाइन ffmpeg का उपयोग कर रहे हैं ताकि आपको प्रोग्राम को सक्षम करने की आवश्यकता पड़े।

+0

यह उत्तर मेरी समस्या का सबसे अच्छा तरीका है। धन्यवाद। – fthopkins

+0

@fthopkins कृपया हमें बताएं कि आप क्या गलत कर रहे थे और आप इस मुद्दे को कैसे ठीक करते हैं। क्या आपने समस्या को ठीक करने के लिए https://github.com/IljaKosynkin/FFmpeg- विकास-किट का पालन किया था? समस्या को हल करने के लिए आपने वास्तव में क्या अपडेट किया? –

संबंधित मुद्दे