1. 程式人生 > >編譯Android下可執行命令的FFmpeg

編譯Android下可執行命令的FFmpeg

  1. 開啟你養家餬口的Android Studio,嫻熟的新建一個專案;
  2. 編寫一個 native 函式,如果只是測試我們在MainActivity裡面搞就行了:

    public native int ffmpegRun(String[] cmd);
  3. 新建jni目錄,在目錄下新建檔案: jx_ffmpeg_cmd_run.c;

  4. 編碼對應的 JNI 介面:

    #include <jni.h><br>
    JNIEXPORT jint JNICALL
    Java_com_mabeijianxi_jianxiffmpegcmd_MainActivity_ffmpegRun(JNIEnv *env, jobject instance, jobjectArray cmd)
    { // TODO }
  5. 找到我們FFmpeg編譯後的根目錄,然後 copy:
    cmdutils.c cmdutils.h cmdutils_common_opts.h config.h ffmpeg.c ffmpeg.h ffmpeg_filter.c ffmpeg_opt.c(注意需要編譯後才會有config.h)到 jni 目錄下,再進入到我們的編譯後的產物目錄,把include資料夾與所有的 .so 動態庫也 copy 到jni目錄下。完成後你jni目錄結構應該如下圖:


  6. 檔案修改
    修改ffmpeg.c與ffmpeg.h
    找到ffmpeg.c,把int main(int argc, char argv) 改名為 int jxRun(int argc, char argv)
    找到ffmpeg.h, 在檔案末尾新增函式申明: int jxRun(int argc, char **argv);



    1)修改cmdutils.c 和 cmdutils.h
    找到cmdutils.c中的exit_program函式
    修改前:



    修改後:



    2)找到cmdutils.h中exit_program的申明,也把返回型別修改為int。
    修改前:



    修改後:



    很多教程都只修改到這裡,基本沒什麼問題,但是你實際執行的時候會發現如果連續多次執行命令會有問題的,通過原始碼我們可以知道,FFmpeg每次執行完命令後會呼叫 ffmpeg_cleanup 函式清理記憶體,並且會呼叫exit(0)結束當前程序,但是經過我們的修改,exit()的程式碼已經被刪掉,我們在Android中自然不能結束當前程序了,所以有些變數的值還在記憶體中,這樣就會導致下次執行的時候可能會出錯。我也嘗試過fork一個程序給ffmpeg執行,完事後通過 訊號

    來程序間通訊,這樣管用但是很麻煩,我們其實只需要簡單的重設一些變數即可。
    開啟ffmpeg.c找到剛修改的jxRun函式,然後在 return 前加上如下程式碼即可:

         nb_filtergraphs = 0;
         progress_avio = NULL;
    
         input_streams = NULL;
         nb_input_streams = 0;
         input_files = NULL;
         nb_input_files = 0;
    
         output_streams = NULL;
         nb_output_streams = 0;
         output_files = NULL;
         nb_output_files = 0;
  7. 編寫呼叫函式
    我們上面只在jx_ffmpeg_cmd_run.c新建了一個JNI介面函式,還沒有實現邏輯,我們實現後的程式碼如下:

    **
    * Created by jianxi on 2017/6/4.
    * https://github.com/mabeijianxi
    * [email protected]
    *
    #include "ffmpeg.h"
    #include <jni.h>
    JNIEXPORT jint JNICALL
    Java_com_mabeijianxi_jianxiffmpegcmd_MainActivity_ffmpegRun(JNIEnv *env, jobject type,jobjectArray commands){
     int argc = *env)->GetArrayLength(env,commands);
     char *argv[argc];
     int i;
     for (i = 0; i < argc; i++) {
         jstring js = (jstring) (*env)->GetObjectArrayElement(env,commands, i);
         argv[i] = (char *) (*env)->GetStringUTFChars(env,js, 0);
     }
     return jxRun(argc,argv);
    }
  8. 編寫Application.mkAndroid.mk
    1)在jni目錄下新建Application.mkAndroid.mk
    2)編寫Application.mk,內容如下:
    APP_ABI := armeabi-v7a
    APP_PLATFORM := android-14
    3)編碼Android.mk,其內容如下(不明含義的可看Android下玩JNI的新老三種姿勢
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := libavcodec
LOCAL_SRC_FILES := libavcodec.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libavfilter
LOCAL_SRC_FILES := libavfilter.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libavformat
LOCAL_SRC_FILES := libavformat.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libavutil
LOCAL_SRC_FILES := libavutil.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libswresample
LOCAL_SRC_FILES := libswresample.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libswscale
LOCAL_SRC_FILES := libswscale.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := jxffmpegrun
LOCAL_SRC_FILES := cmdutils.c ffmpeg.c ffmpeg_filter.c ffmpeg_opt.c jx_ffmpeg_cmd_run.c

# 這裡的地址改成自己的 FFmpeg 原始碼目錄
LOCAL_C_INCLUDES :=/Users/jianxi/Downloads/code/ffmpeg-3.2.5
LOCAL_LDLIBS := -llog -lz -ldl
LOCAL_SHARED_LIBRARIES :=libavcodec libavfilter libavformat libavutil libswresample libswscale
include $(BUILD_SHARED_LIBRARY)


9. 開始編譯:
我們開啟終端,然後cd 到jni目錄下,然後執行ndk-build,如果你沒配置其環境變數,你選擇寫入ndk-build的全路徑。
如果順利你可以在命令結束後看到如下輸出:



並且你的lib下會有如下產物:



這裡就先不上測試的效果圖了,等後面一起搞

三、cMake編譯

有好多步驟都是很上面一樣的,一會兒我就快樂的copy下來哈

  1. 開啟你養家餬口的Android Studio,版本最好大於2.2,很關鍵。嫻熟的新建一個專案,但是與以往不同,你最好勾選上 C++ 支援與 C++ standard選項時選擇 C++ 11,如下圖:




  2. 新建完成後你會發現幫你生成好了介面,這時我們只需修改native函式即可:
    修改前:

    public native String stringFromJNI();

    修改後

    public native int ffmpegRun(String[] cmd);
  3. 修改native檔案與函式:
    你會發現這時多了一個cpp的資料夾,裡面多了一個native-lib.cpp的檔案,我們修改其名為jx_ffmpeg_cmd_run.c,然後修改裡面的函式,修改後的函式應該如下:

    #include <jni.h>
    JNIEXPORT jint JNICALL
    Java_com_mabeijianxi_jianxiffmpegcmd_MainActivity_ffmpegRun(JNIEnv *env, jobject instance, jobjectArray cmd) {
    
     // TODO
    }
  4. 找到我們FFmpeg編譯後的根目錄,然後 copy:
    cmdutils.c cmdutils.h cmdutils_common_opts.h config.h ffmpeg.c ffmpeg.h ffmpeg_filter.c ffmpeg_opt.c(注意需要編譯後才會有config.h)到 cpp 目錄下,再進入到我們的編譯後的產物目錄,把include資料夾 copy 到cpp目錄下。完成後你cpp目錄結構應該如下圖:

  1. 檔案修改
    修改ffmpeg.c與ffmpeg.h
    找到ffmpeg.c,把int main(int argc, char argv) 改名為 int jxRun(int argc, char argv)
    找到ffmpeg.h, 在檔案末尾新增函式申明: int jxRun(int argc, char **argv);



    1)修改cmdutils.c 和 cmdutils.h
    找到cmdutils.c中的exit_program函式
    修改前:



    修改後:



    2)找到cmdutils.h中exit_program的申明,也把返回型別修改為int。
    修改前:



    修改後:



    很多教程都只修改到這裡,基本沒什麼問題,但是你實際執行的時候會發現如果連續多次執行命令會有問題的,通過原始碼我們可以知道,FFmpeg每次執行完命令後會呼叫 ffmpeg_cleanup 函式清理記憶體,並且會呼叫exit(0)結束當前程序,但是經過我們的修改,exit()的程式碼已經被刪掉,我們在Android中自然不能結束當前程序了,所以有些變數的值還在記憶體中,這樣就會導致下次執行的時候可能會出錯。我也嘗試過fork一個程序給ffmpeg執行,完事後通過 訊號來程序間通訊,這樣管用但是很麻煩,我們其實只需要簡單的重設一些變數即可。
    開啟ffmpeg.c找到剛修改的jxRun函式,然後在 return 前加上如下程式碼即可:

         nb_filtergraphs = 0;
         progress_avio = NULL;
    
         input_streams = NULL;
         nb_input_streams = 0;
         input_files = NULL;
         nb_input_files = 0;
    
         output_streams = NULL;
         nb_output_streams = 0;
         output_files = NULL;
         nb_output_files = 0;
  2. 編寫呼叫函式
    我們上面只在jx_ffmpeg_cmd_run.c新建了一個JNI介面函式,還沒有實現邏輯,我們實現後的程式碼如下:

    \**
    \* Created by jianxi on 2017/6/4.
    \* https://github.com/mabeijianxi
    \* [email protected]
    */
    #include "ffmpeg.h"
    #include <jni.h>
    JNIEXPORT jint JNICALL
    Java_com_mabeijianxi_jianxiffmpegcmd_MainActivity_ffmpegRun(JNIEnv *env, jobject type,jobjectArray commands){
     int argc = (*env)->GetArrayLength(env,commands);
     char *argv[argc];
     int i;
     for (i = 0; i < argc; i++) {
         jstring js = (jstring) (*env)->GetObjectArrayElement(env,commands, i);
         argv[i] = (char *) (*env)->GetStringUTFChars(env,js, 0);
     }
     return jxRun(argc,argv);
    }
  3. 編寫cmake編譯指令碼:
    在沒有編寫指令碼的時候你的程式碼應該是一片紅,沒關係,馬上我們就幹掉它。
    開啟你當前Module下的CMakeLists.txt然後填寫如下指令碼(內容解釋可看Android下玩JNI的新老三種姿勢):
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

add_library( # Sets the name of the library.
             jxffmpegrun

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
              src/main/cpp/cmdutils.c
              src/main/cpp/ffmpeg.c
              src/main/cpp/ffmpeg_filter.c
              src/main/cpp/ffmpeg_opt.c
              src/main/cpp/jx_ffmpeg_cmd_run.c
             )
add_library(
            avcodec
            SHARED
            IMPORTED
            )

add_library(
            avfilter
            SHARED
            IMPORTED
             )


add_library(
            avformat
            SHARED
            IMPORTED
            )


add_library(
            avutil
            SHARED
            IMPORTED
            )

add_library(
            swresample
            SHARED
            IMPORTED
            )

add_library(
            swscale
            SHARED
            IMPORTED
            )


add_library(
            fdk-aac
            SHARED
            IMPORTED
            )

if(${ANDROID_ABI} STREQUAL "armeabi")
set_target_properties(
    avcodec
    PROPERTIES IMPORTED_LOCATION
    ${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi/libavcodec.so
    )

set_target_properties(
        avfilter
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi/libavfilter.so
        )

set_target_properties(
            avformat
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi/libavformat.so
            )

set_target_properties(
            avutil
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi/libavutil.so
            )

set_target_properties(
            swresample
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi/libswresample.so
             )

set_target_properties(
            swscale
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi/libswscale.so
             )


set_target_properties(
            fdk-aac
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi/libfdk-aac.so
             )
endif(${ANDROID_ABI} STREQUAL "armeabi")

if(${ANDROID_ABI} STREQUAL "armeabi-v7a")

set_target_properties(
    avcodec
    PROPERTIES IMPORTED_LOCATION
    ${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi-v7a/libavcodec.so
    )

set_target_properties(
        avfilter
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi-v7a/libavfilter.so
        )

set_target_properties(
            avformat
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi-v7a/libavformat.so
            )

set_target_properties(
            avutil
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi-v7a/libavutil.so
            )

set_target_properties(
            swresample
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi-v7a/libswresample.so
             )

set_target_properties(
            swscale
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi-v7a/libswscale.so
             )


set_target_properties(
            fdk-aac
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi-v7a/libfdk-aac.so
             )

endif(${ANDROID_ABI} STREQUAL "armeabi-v7a")

if(${ANDROID_ABI} STREQUAL "arm64-v8a")
set_target_properties(
    avcodec
    PROPERTIES IMPORTED_LOCATION
    ${CMAKE_SOURCE_DIR}/src/main/jniLibs/arm64-v8a/libavcodec.so
    )

set_target_properties(
        avfilter
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/src/main/jniLibs/arm64-v8a/libavfilter.so
        )

set_target_properties(
            avformat
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/arm64-v8a/libavformat.so
            )

set_target_properties(
            avutil
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/arm64-v8a/libavutil.so
            )

set_target_properties(
            swresample
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/arm64-v8a/libswresample.so
             )

set_target_properties(
            swscale
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/arm64-v8a/libswscale.so
             )


set_target_properties(
            fdk-aac
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/arm64-v8a/libfdk-aac.so
             )
endif(${ANDROID_ABI} STREQUAL "arm64-v8a")

if(${ANDROID_ABI} STREQUAL "x86")
set_target_properties(
    avcodec
    PROPERTIES IMPORTED_LOCATION
    ${CMAKE_SOURCE_DIR}/src/main/jniLibs/x86/libavcodec.so
    )

set_target_properties(
        avfilter
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/src/main/jniLibs/x86/libavfilter.so
        )

set_target_properties(
            avformat
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/x86/libavformat.so
            )

set_target_properties(
            avutil
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/x86/libavutil.so
            )

set_target_properties(
            swresample
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/x86/libswresample.so
             )

set_target_properties(
            swscale
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/x86/libswscale.so
             )

set_target_properties(
            fdk-aac
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/x86/libfdk-aac.so
             )
endif(${ANDROID_ABI} STREQUAL "x86")

if(${ANDROID_ABI} STREQUAL "x86_64")
set_target_properties(
    avcodec
    PROPERTIES IMPORTED_LOCATION
    ${CMAKE_SOURCE_DIR}/src/main/jniLibs/x86_64/libavcodec.so
    )

set_target_properties(
        avfilter
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/src/main/jniLibs/x86_64/libavfilter.so
        )

set_target_properties(
            avformat
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/x86_64/libavformat.so
            )

set_target_properties(
            avutil
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/x86_64/libavutil.so
            )

set_target_properties(
            swresample
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/x86_64/libswresample.so
             )

set_target_properties(
            swscale
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/x86_64/libswscale.so
             )

set_target_properties(
            fdk-aac
            PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/src/main/jniLibs/x86_64/libfdk-aac.so
             )
endif(${ANDROID_ABI} STREQUAL "x86_64")

include_directories(
    /Users/jianxi/Downloads/code/ffmpeg-3.2.5/

)
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

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

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
                       jxffmpegrun
                       fdk-aac
                       avcodec
                       avfilter
                       avformat
                       avutil
                       swresample
                       swscale
                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

當然你還需要修改腳本里面的一些檔案路徑。

8 . 修改當前Module下的build.gradle指令碼:
我所謂的全架構其實是排除了 mips 的,覺得沒什麼卵用,所以我們還需要新增過濾:
修改前:



修改後:


做到這步我們就可以直接點選同步按鈕了:



完成後就不會再爆紅了,這時候是隻能直接執行安裝的,但是還沒有輸入命令,所以沒什麼意義,接下來將開始使用我們做好的工具。

四、測試與使用

我們要用動態庫肯定得放入預設目錄,或者在gradle.build中修改其路徑,這裡我就直接放入
jniLibs 裡面了,如圖:



然後我就是在java裡面呼叫了,搞了一個進度條,一個按鈕。沒有什麼技術含量,直接貼程式碼了哈:

public class MainActivity extends AppCompatActivity {

    static {
        System.loadLibrary("jxffmpegrun");
        System.loadLibrary("avcodec");
        System.loadLibrary("avformat");
        System.loadLibrary("avutil");
        System.loadLibrary("swscale");
        System.loadLibrary("fdk-aac");
    }

    private ProgressBar pb;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        pb = (ProgressBar) findViewById(R.id.pb);

    }

    public void onClick(View v){
        pb.setVisibility(View.VISIBLE);
        new Thread(new Runnable() {
            @Override
            public void run() {
                String basePath = Environment.getExternalStorageDirectory().getPath();

                String cmd_transcoding = String.format("ffmpeg -i %s -c:v libx264 %s  -c:a libfdk_aac %s",
                        basePath+"/"+"girl.mp4",
                        "-crf 40",
                        basePath+"/"+"my_girl.mp4");
                int i = jxFFmpegCMDRun(cmd_transcoding);
                new Handler(Looper.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        pb.setVisibility(View.GONE);
                        Toast.makeText(MainActivity.this,"ok了",Toast.LENGTH_SHORT).show();
                    }
                });
            }
        }).start();
    }
    public  int jxFFmpegCMDRun(String cmd){
        String regulation="[ \\t]+";
        final String[] split = cmd.split(regulation);

        return ffmpegRun(split);
    }
    public native int ffmpegRun(String[] cmd);
}


再上面程式碼中我們指定編碼器壓縮了一個mp4的檔案,壓縮前叫girl.mp4,壓縮後叫my_girl.mp4,如圖所示,我們發現其縮小了近80%


五、總結

這裡輸入路徑不能每次是同一個,不然會報錯,也就是說,運行了一次上面的命令後,輸出的名字不能再叫my_girl.mp4了,你可以叫your_girl.mp4。然後還是那句話推薦用cMake,你看我們通過cMake編譯可以直接debug native



是不是很hi,然後我們在開發中可能會發現有些命令執行不了,這時候你首先需要檢查命令,然後確保沒問題後,你需要確定你在編譯FFmpeg的時候是否開啟了此功能,很關鍵,確定辦法很簡單,一是檢查FFmpeg的編譯指令碼,二是通過FFmpeg的函式獲取編譯資訊,我工程裡面已經內含這個jni介面,有興趣的基友可以下載來try一try。如果有興趣進一步探索FFmpeg在Android上的實戰運用,可以看我的開源專案和其講解部落格,分別是:https://github.com/mabeijianxi/small-video-record利用FFmpeg玩轉Android視訊錄製與壓縮(一)利用FFmpeg玩轉Android視訊錄製與壓縮(二)

相關推薦

編譯Android執行命令FFmpeg

開啟你養家餬口的Android Studio,嫻熟的新建一個專案; 編寫一個 native 函式,如果只是測試我們在MainActivity裡面搞就行了: public native int ffmpegRun(String[] cmd); 新建jni目錄,在目錄下新建檔案: jx_ffmpeg_cm

在windowandroid-ndk編譯android執行程式的方法。

環境,win7,與android-ndk-r13b-windows-x86_64,把android-ndk-r13b-windows-x86_64解壓在目當中就可,不用安裝 1,只用gcc工具 D:\android-ndk\android-ndk-r13b\toolcha

Golang 在windows編譯Linux執行檔案

Golang 支援交叉編譯,在一個平臺上生成另一個平臺的可執行程式,最近使用了一下,非常好用,這裡備忘一下。 Windows 下編譯Linux 64位可執行程式 SET CGO_ENABLED=0 SET GOOS=linux SET GOARCH=amd64 go

JAVA程式在eclipse執行但不能在cmd命令執行的原因

原文在這裡 對我自己而言,是這個原因: (1)把目錄切換到這裡         E:\JavaCodeCYH22\Proj\src (2)執行     java  com/cyh/Main   就可以了 簡單說就是:“目錄”裡面不要加入包,而在java執行時才加入包

android JNI執行NDK編譯成的執行檔案

1.android環境的可執行檔案的生成 所謂的android下的可執行檔案,其實就是一般的c/c++程式碼使用NDK編譯出來的應用程式。它和linux下用gcc編譯出來的程式和windows系統下的.exe檔案是一樣的。要將程式碼編譯成可執行檔案只需要將編譯so的inc

基於Android arm64 執行程式的編譯執行

Android預設編譯的應用程式動態連結的一般都是PIE,前文“基於Android arm64 Linux got 除錯”,每次除錯都要檢視載入地址,於是就想能否編譯生成非PIE的應用程式。 /opt/android-6.0.1_r9/external/hel

maven工程編譯並生成執行JAR包命令

在JAVA持續整合構建中,需要從SVN check out的程式碼編譯並打成可執行JAR包,高手告訴我maven命令如何? 我用mvn compile package或mvn jar:jar都能打成jar包,但不能執行 利用HUDSON+MAVEN編譯打包java mav

android真機執行命令react-native run-android報以錯誤

執行命令react-native run-android報以下錯誤 unable to load script from assets ‘index.android bundle’ ,make sure your bundle is packaged cor

編譯Android可用的全平臺FFmpeg(包含libx264與libfdk-aac)

原始碼或工具版本: ndk :r14FFmpeg 版本:3.2.5libfdk-aac 版本:0.1.5 一、原始碼準備: 這裡假設你已經擁有了ndk環境,沒有的可以先配置,可以參考Android下玩JNI的新老三種姿勢。 二、編寫全平臺指令碼: ffmpe

expect 普通用戶自動輸入密碼到root執行命令

expect案例:當前服務器取消了直接使用root登錄服務器,只能使用普通用戶先登錄,然後再su - root 執行root下的命令。 shell腳本如下: #!/usr/bin/expect -fset password {root_password}spawn su - rootexpect "

Linuxtomcat執行命令

tomcat啟動 [[email protected] webapps]# /usr/local/tomcat7.0/bin/catalina.sh start    startup.sh的原始碼,其實就是執行   catalina.sh sta

AndroidAndroid程式碼中執行命令

Android 在Android程式碼中執行命令列 轉自 https://www.cnblogs.com/lipeineng/p/6078859.html 1.路徑最好不要是自己拼寫的路徑/mnt/shell/emulated/0/wifidog.conf 最好是通過方法獲取的路徑,不然

Android的adb命令大集合

在Android SDK安裝與環境配置隨筆中,已經介紹了一個安裝成功的Android SDK在cmd命令列中輸入adb命令時會顯示一堆資訊。 那麼adb是什麼???adb又有什麼作用呢??? adb(android bridge),是一個通用的命令列工具,它可以允許使用者與模擬器例項或者與連線的Andro

CMakeLists.txt 中設定編譯後的執行程式優先呼叫本地庫

可執行程式查詢不到so庫 庫放在可執行程式目錄下的lib資料夾下,但是可執行程式沒有去呼叫,使用ldd指令  修改ld.so.conf也是無效 是否是CMakeLists.txt設定的問題? 有事找度娘。。。  設定可執行程式優先呼叫本地庫 SET(CMA

VS2010靜態編譯生成.exe執行檔案

VS2010靜態編譯生成的.exe可執行檔案,可以免安裝在其他電腦直接執行   靜態編譯:就是在編譯可執行檔案的時候,將可執行檔案需要呼叫的對應動態連結庫(.so)中的部分提取出來,連結到可執行檔案中去,使可執行檔案在執行的時候不依賴動態連結庫。     編譯方式: 第1種:

編譯通過,執行時找不到類,提示 classLink not found 之類的錯誤

參考:加libar ,libs,基本有用 ,將jar加進 Android private libaries 裡面去 後有提示: Android Error :trouble writing output: already prepared 類重複了,參考: clea

python project 編譯Linux的執行版本-pyinstaller

python project 編譯Linux的可執行版本 --2017.11.18 1.使用工具 pyinstaller 3.編譯方法 (1)編譯main.py p

Linux執行檔案格式詳解

Linux下面,目標檔案、共享物件檔案、可執行檔案都是使用ELF檔案格式來儲存的。程式經過編譯之後會輸出目標檔案,然後經過連結可以產生可執行檔案或者共享物件檔案。Linux下面使用的ELF檔案和Windows作業系統使用的PE檔案都是從Unix系統的COFF檔案格式演化來的

linux執行應用程式not found問題(交叉編譯生成的執行檔案)

[email protected]:~/Desktop/em35x-ezsp$readelf -a build/ZigBee/ZigBee |grep NEEDED  0x00000001 (NEEDED)                     Shared library: [libreadli

windows系統執行程式呼叫lib靜態庫和dll動態庫的方法

#include <stdio.h> #include <Windows.h>   int main() {    HINSTANCE h=LoadLibraryA("newdll.dll");     typedef int (* FunPtr)(int a,int b);//定義函