Andriod studio3.5搭建ffmpeg helloworld(動態(tài)庫文件)

環(huán)境

win7或链、jdk8隙畜、Andriod studio3.5尉剩、 NDK21


寫在前

  1. 采用編譯好的ffmpeg動態(tài)庫文件(多個動態(tài)文件)
  2. Android studio3.5創(chuàng)建navtive c++工程已經(jīng)配置好jni demo间坐,不用考慮gradle和cmake協(xié)調配置,非常方便
  3. 不同版本的Android studio創(chuàng)建的C+項目的CMakeLists.txt放置路徑不一樣少孝,多用message命令確認內(nèi)置變量的值

簡單總結

一般NDK開發(fā)時會有三方面報錯

  1. 編輯C/C++代碼時,找不到頭文件熬苍。說明CMakeLists.txt配置有漏
  2. build構建時稍走,鏈接linked報錯。說明CMakeLists.txt配置有漏
  3. 運行時找不到so文件柴底,閃退婿脸,這是外部so文件沒有打包如apk中。說明build.gradle配置有漏柄驻『鳎或者將外部so文件放入main/jniLibs/{ABI版本}中
    具體的解決方案看本文最后

使用靜態(tài)文件 vs 使用動態(tài)文件

  1. 使用靜態(tài)文件在build構建時會編入內(nèi)部so文件中;而使用動態(tài)文件鸿脓,需要把外部so文件打包如spk中
  2. 靜態(tài)文件會缺少uncompress等函數(shù)定義抑钟,需要添加壓縮庫(Z);使用動態(tài)文件則不用

操作步驟-詳細:

  1. AS添加C++工程


    image.png
  2. 拷貝ffmpeg文件到AS工程野哭,目錄結構如下


    image.png
  3. 修改app的gradle.build

apply plugin: 'com.android.application'

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.3"
    defaultConfig {
        applicationId "com.example.mmffndk"
        minSdkVersion 21
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags ""
               abiFilters 'armeabi-v7a'    //ABIs [armeabi] are not supported for platform. Supported ABIs are [arm64-v8a, armeabi-v7a, x86, x86_64].
            
            }
        }

        ndk{                //修改點2
            abiFilters 'armeabi-v7a'
        }

        sourceSets {
            main {
                jniLibs.srcDirs = ['libs']  //jniLibs打包時會查找libs/${ANDROID_ARCH_ABI}/*.so
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
            version "3.10.2"
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}

  1. 修改CMakeLists.txt
  • 需要注意:
    1) 不同版本的android studio生成項目的CMakeLists.txt路徑不同在塔,所以CMAKE_SOURCE_DIR的值不同
    2)使用ffmpeg動態(tài)庫,已經(jīng)包含壓縮等拨黔。所以target_link_libraries不需要添加 -lz
cmake_minimum_required(VERSION 3.4.1)

# 指定引入文件頭路徑 , include文件夾里放置了ffmpeg的.h頭文件
include_directories(${CMAKE_SOURCE_DIR}/ffmpeg/include)

# 指定 .so共享庫目錄 (相當于添加 CXXFLAGS=-Lpath)
link_directories(${PROJECT_SOURCE_DIR}/../../../libs/${CMAKE_ANDROID_ARCH_ABI})

# 指定 c/c++ 源文件目錄
aux_source_directory(${CMAKE_SOURCE_DIR} cpp-list)
message(STATUS "cpp-list = ${cpp-list}")

add_library( # Sets the name of the library.
       native-lib11
       SHARED
       ${cpp-list})

find_library( # Sets the name of the path variable.
       log-lib
       log)

target_link_libraries( # Specifies the target library.
       native-lib11
       avcodec avdevice avfilter avformat avutil swresample swscale
       android
       ${log-lib})
  1. 點擊 build->rebuild project 蛔溃,項目構建完成后,打開 apk分析器(build ->apk analyze然后選擇apk)
    由于我們在app:build.gradle里配置 abiFilters=armeabi-v7a,而且配置了jniLibs.srcDirs = 'libs'贺待。所以apk打包時會在lib下創(chuàng)建armeabi-v7a文件夾徽曲,并且把項目中l(wèi)ibs目錄下armeabi-v7a里所有so文件拷貝過來。 同樣的麸塞,如果配置 abiFilters='armeabi-v7a'和'arm64-v8a'秃臣, 則會在apk的lib下創(chuàng)建armeabi-v7a和arm64-v8a兩個文件夾,并且把項目中的libs目錄下對應的文件夾拷貝過來喘垂。如果項目中沒有l(wèi)ibs/arm64-v8a目錄甜刻,則build的時候會報錯
    image.png

常見錯誤

  1. 頭文件找不到
  • 現(xiàn)象:編輯c/cpp代碼時報錯 cannot find 'libavcodec'


    image.png
  • 原因:頭文件路徑錯誤
  • 解決方案:
    ①先在 CmakeLists.txt 里添加:include_directories(${CMAKE_SOURCE_DIR}/ffmpeg/include)
    ②點擊 build->refresh linked C++ projects
  1. 鏈接錯誤:linker command failed with exit code 1 (use -v to see invocation)
  • 現(xiàn)象:build構建時報錯:undefined reference to 'avutil_configuration'
[2/2] Linking CXX shared library G:\learn\androidlearn\workstation\Mmffndk\app\build\intermediates\cmake\debug\obj\armeabi-v7a\libnative-lib.so
  FAILED: G:/android/workstation/Mmffndk/app/build/intermediates/cmake/debug/obj/armeabi-v7a/libnative-lib.so 
  cmd.exe /C "cd . && G:\learn\androidlearn\studio\sdk\ndk\21.0.6113669\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=armv7-none-linux-androideabi21 --gcc-toolchain=G:/android/studio/sdk/ndk/21.0.6113669/toolchains/llvm/prebuilt/windows-x86_64 --sysroot=G:/android/studio/sdk/ndk/21.0.6113669/toolchains/llvm/prebuilt/windows-x86_64/sysroot -fPIC -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -march=armv7-a -mthumb -Wformat -Werror=format-security   -O0 -fno-limit-debug-info  -Wl,--exclude-libs,libgcc_real.a -Wl,--exclude-libs,libatomic.a -static-libstdc++ -Wl,--build-id -Wl,--fatal-warnings -Wl,--exclude-libs,libunwind.a -Wl,--no-undefined -Qunused-arguments -shared -Wl,-soname,libnative-lib.so -o G:\learn\androidlearn\workstation\Mmffndk\app\build\intermediates\cmake\debug\obj\armeabi-v7a\libnative-lib.so CMakeFiles/native-lib.dir/native-lib.cpp.o  -lavformat -lavcodec -lavfilter -lavutil -lswresample -lswscale -landroid -llog -latomic -lm && cd ."
  G:/android/studio/sdk/ndk/21.0.6113669/toolchains/llvm/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin\ld: error: cannot find -lavformat
  G:/android/studio/sdk/ndk/21.0.6113669/toolchains/llvm/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin\ld: error: cannot find -lavcodec
  G:/android/studio/sdk/ndk/21.0.6113669/toolchains/llvm/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin\ld: error: cannot find -lavfilter
  G:/android/studio/sdk/ndk/21.0.6113669/toolchains/llvm/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin\ld: error: cannot find -lavutil
  G:/android/studio/sdk/ndk/21.0.6113669/toolchains/llvm/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin\ld: error: cannot find -lswresample
  G:/android/studio/sdk/ndk/21.0.6113669/toolchains/llvm/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin\ld: error: cannot find -lswscale
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:27: error: undefined reference to 'avutil_configuration'
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:40: error: undefined reference to 'av_register_all'
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:42: error: undefined reference to 'avformat_alloc_context'
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:52: error: undefined reference to 'av_dict_set'
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:54: error: undefined reference to 'avformat_open_input'
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:62: error: undefined reference to 'avformat_find_stream_info'
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:87: error: undefined reference to 'avcodec_find_decoder'
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:94: error: undefined reference to 'avcodec_open2'
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:102: error: undefined reference to 'sws_getContext'
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:108: error: undefined reference to 'av_malloc'
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:110: error: undefined reference to 'av_init_packet'
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:116: error: undefined reference to 'av_frame_alloc'
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:119: error: undefined reference to 'av_frame_alloc'
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:122: error: undefined reference to 'avpicture_get_size'
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:121: error: undefined reference to 'av_malloc'
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:125: error: undefined reference to 'avpicture_fill'
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:136: error: undefined reference to 'av_read_frame'
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:144: error: undefined reference to 'avcodec_decode_video2'
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:155: error: undefined reference to 'sws_scale'
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:179: error: undefined reference to 'av_free_packet'
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:185: error: undefined reference to 'av_frame_free'
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:186: error: undefined reference to 'av_frame_free'
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:188: error: undefined reference to 'avcodec_close'
  G:/android/workstation/Mmffndk/app/src/main/cpp/native-lib.cpp:189: error: undefined reference to 'avformat_free_context'
  clang++: error: linker command failed with exit code 1 (use -v to see invocation)
  • 原因:so文件沒有引入
  • 解決方法:在 CMakeLists.txt添加
# 指定 .so共享庫目錄 (如果是 .a靜態(tài)文件,需要添加 CXXFLAGS)
link_directories(${PROJECT_SOURCE_DIR}/../../../libs/${CMAKE_ANDROID_ARCH_ABI})
  1. ffmpeg的so文件沒有打入apk包
    現(xiàn)象:打包沒報錯正勒,運行時閃退得院,報錯如下
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.mmffndk, PID: 7253
    java.lang.UnsatisfiedLinkError: dlopen failed: library "libavformat.so" not found: needed by /data/app/~~VZddftg5_hnlp3FkuHdTxg==/com.example.mmffndk-NDSt_nrh6mmjLv39fko4gQ==/lib/arm/libnative-lib.so in namespace classloader-namespace
        at java.lang.Runtime.loadLibrary0(Runtime.java:1087)
        at java.lang.Runtime.loadLibrary0(Runtime.java:1008)
        at java.lang.System.loadLibrary(System.java:1664)
        at com.example.mmffndk.MainActivity.<clinit>(MainActivity.java:25)
        at java.lang.Class.newInstance(Native Method)
        at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:95)
        at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:43)
        at android.app.Instrumentation.newActivity(Instrumentation.java:1253)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3353)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
D/libEGL: loaded /vendor/lib/egl/libEGL_emulation.so

解決方案:
① 打開 apk analyze,確認ffmpeg相關的外部so文件沒有打入apk中


image.png

② 確認app:build.gradle有沒有報錯


image.png
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末章贞,一起剝皮案震驚了整個濱河市祥绞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鸭限,老刑警劉巖蜕径,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異败京,居然都是意外死亡兜喻,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門赡麦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來朴皆,“玉大人,你說我怎么就攤上這事泛粹∷煺。” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵晶姊,是天一觀的道長扒接。 經(jīng)常有香客問我,道長们衙,這世上最難降的妖魔是什么钾怔? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮砍艾,結果婚禮上蒂教,老公的妹妹穿的比我還像新娘。我一直安慰自己脆荷,他們只是感情好凝垛,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布懊悯。 她就那樣靜靜地躺著,像睡著了一般梦皮。 火紅的嫁衣襯著肌膚如雪炭分。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天剑肯,我揣著相機與錄音捧毛,去河邊找鬼。 笑死让网,一個胖子當著我的面吹牛呀忧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播溃睹,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼而账,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了因篇?” 一聲冷哼從身側響起泞辐,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎竞滓,沒想到半個月后咐吼,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡商佑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年锯茄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片茶没。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡撇吞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出礁叔,到底是詐尸還是另有隱情,我是刑警寧澤迄薄,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布琅关,位于F島的核電站,受9級特大地震影響讥蔽,放射性物質發(fā)生泄漏涣易。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一冶伞、第九天 我趴在偏房一處隱蔽的房頂上張望新症。 院中可真熱鬧,春花似錦响禽、人聲如沸徒爹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽隆嗅。三九已至界阁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胖喳,已是汗流浹背泡躯。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留丽焊,地道東北人较剃。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像技健,于是被迫代替她去往敵國和親写穴。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容