First, compile
Refer to Dashen's post and test the compilation successfully: https://blog.csdn.net/bobcat_kay/article/details/80889398
In view of previous experience in documentation, here is the time for writing examples: 22 July 2018.
I use ubantu. Notes:
1. The path here, home/ndk is wrong, the real path is home/computer name/ndk, specifically based on the cd ls command.
2. Documents must be downloaded in ubantu. The first time I downloaded them in win, and then passed them through VMware. The result was that something went wrong. Then Baidu found the problem and downloaded one directly from ubantu. Then it was OK.
3. When editing these two files, build.sh and confinger, make sure that the format of the text is not doc but unit (the word should be wrong).
Two. Transplantation
The god's post uses mk, but I prefer cmake here.
The process is basically the same, but there are some minor details. Maybe Dashen has deep skills and has not encountered any problems. I have been stuck in this step for most of the night.
1. Create new projects
(1) Environment
Android Studio 3.2
NDK 17.1.4828580
SDK 28
(2) New projects
Look at the screenshots. The main thing is to tick this thing. Everything else is default.
2. Copy files
(1) copy so file
I created a new folder ffmpeg/armeabi-v7a under the cpp directory, and copied all so packages in.
(2) Copy fftools code
Create a new folder included under the ffmpeg folder, then copy some files in the folder fftools into the include folder, and copy config.h in the outermost layer of the source code.
(3) Copy source code
In line with the principle of killing the wrong, I copied all the folders (except fftools) in the source directory into include. (Referring to God's practice, many files are missing header files, and then have been compiled incorrectly.)
3. Create jni's call class
(1) Java classes
Create FFmpegCmd class
(2) Create class c
Look at the picture above. Direct alt+enter can create related methods. Android Studio is very smart.
Then rename class C ffmpeg_cmd_utils.c
(3) Special description
The reason is that c is not cpp, I am also helpless, if it is cpp, compiling time exploded a lot of warnings, and not compiled, at present, no problem has been found, after all, my level is limited.
4, configuration
(1)build.gradle
Major areas have been marked.
(2) CMakeLists.txt file
The main thing is to load all so packages, and there are ffmpeg_cmd_utils.c and ffmpeg.c and other classes in the fftools folder (not all of them need to be used, if all of them are loaded, they will report some inexplicable errors, depending on the cmake file).
If I remember the steps correctly, I can basically compile through this step, and the next step is to start with the cmd tool.
cmake_minimum_required(VERSION 3.4.1) add_library( # Sets the name of the library. ffmpegcmd # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). src/main/cpp/ffmpeg/include/cmdutils.c src/main/cpp/ffmpeg/include/ffmpeg.c src/main/cpp/ffmpeg/include/ffmpeg_filter.c src/main/cpp/ffmpeg/include/ffmpeg_hw.c src/main/cpp/ffmpeg/include/ffmpeg_opt.c src/main/cpp/ffmpeg_cmd_utils.c ) #Add libavcodec-57.so add_library( avcodec SHARED IMPORTED) set_target_properties( avcodec PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/cpp/ffmpeg/armeabi-v7a/libavcodec.so) #Add libavdevice-57.so add_library( avdevice SHARED IMPORTED) set_target_properties( avdevice PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/cpp/ffmpeg/armeabi-v7a/libavdevice.so) add_library( avfilter SHARED IMPORTED) set_target_properties( avfilter PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/cpp/ffmpeg/armeabi-v7a/libavfilter.so) add_library( avformat SHARED IMPORTED) set_target_properties( avformat PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/cpp/ffmpeg/armeabi-v7a/libavformat.so) add_library( avutil SHARED IMPORTED) set_target_properties( avutil PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/cpp/ffmpeg/armeabi-v7a/libavutil.so) add_library( swresample SHARED IMPORTED) set_target_properties( swresample PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/cpp/ffmpeg/armeabi-v7a/libswresample.so) add_library( swscale SHARED IMPORTED) set_target_properties( swscale PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/cpp/ffmpeg/armeabi-v7a/libswscale.so) include_directories(src/main/cpp/ffmpeg/include) 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 ) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") target_link_libraries( # Specifies the target library. ffmpegcmd avcodec avdevice avfilter avformat avutil swresample swscale # Links the target library to the log library # included in the NDK. ${log-lib} )
5. Modify the code
(1)cmdutils.c
Comment out the exit_program method:
(2)cmdutils.h
void show_help_children(const AVClass *class, int flags);
Change to:
void show_help_children(const AVClass *clazz, int flags);
(3)ffmpeg.c
The entrance is the main function, renamed, followed by the God ffmpeg_exec
Comment out the code at the end of the ffmpeg_exec function:
Find the ffmpeg_cleanup function and add:
nb_filtergraphs = 0; nb_output_files = 0; nb_output_streams = 0; nb_input_files = 0; nb_input_streams = 0;
Add the following as follows:
The nb_filtergraphs declaration is assigned a value of 0 for insurance purposes.
Add at the end of the ffmpeg_exce function, or your phone will explode the second time you run the command line.
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;
The following step can be exempted on demand, mainly for printing the output information after the command line runs:
Add a statement:
#include "android/log.h" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , "ffmpeg.c", __VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR , "ffmpeg.c", __VA_ARGS__)
Add content to the log_callback_null function:
static void log_callback_null(void *ptr, int level, const char *fmt, va_list vl) { static int print_prefix = 1; static int count; static char prev[1024]; char line[1024]; static int is_atty; av_log_format_line(ptr, level, fmt, vl, line, sizeof(line), &print_prefix); strcpy(prev, line); //sanitize((uint8_t *)line); if (level <= AV_LOG_WARNING) { LOGE("Output:%s", line); } else { LOGE("Output:%s", line); } }
(4)ffmpeg.h
Add the function declaration of ffmpeg_exec function at the end
(5)ffmpeg_cmd_utils.c
Call code directly
#include <android/log.h> #include <ffmpeg.h> #define LOGE(FORMAT,...) __android_log_print(ANDROID_LOG_ERROR,"8858",FORMAT,##__VA_ARGS__); JNIEXPORT jint JNICALL Java_com_imxiaoyu_test_FFmpegPlayer_playMyMedia(JNIEnv *env, jobject instance,jint cmdLen, jobjectArray cmd) { int argc = (*env)->GetArrayLength(env, cmd); char *argv[argc]; int i; for (i = 0; i < argc; i++) { jstring js = (jstring) (*env)->GetObjectArrayElement(env, cmd, i); argv[i] = (char*) (*env)->GetStringUTFChars(env, js, 0); LOGE("command line argCmd=%s",argv[i]); } ffmpeg_exec(argc, argv); return 1; }
If you remember correctly, that's ok ay.
6. Call
(1) Authority
The right to read and write the memory of the cell phone must be tucking out. I am a millet 6 in my cell phone. In line with the principle of laziness, after clicking the permission management to app permissions on the application details page, it will not work. If the command line runs, it will crash. It must be the application of the code to be useful. I thought it was a compilation or code problem, at least here. Three or four hours were wasted in one step. I'm not sure if it's MIUI or Android 8.0. Do your best to do your job and not be lazy.
Later, when I ran up, you should all know my mood at that time. You can't laugh or cry with joy.
I won't post the code to apply for permission.
(2) Call
final String cmd[]=str.split(" ");// new Thread(){ @Override public void run() { PathUtils pathUtils=new PathUtils(); String str="ffmpeg -i "+pathUtils.getMusicCacheEditorPath()+"/12.mp3 -y "+pathUtils.getMusicCacheEditorPath()+"/haha1.wav";//Specific path, free play long startTime = System.currentTimeMillis(); try { fFmpegPlayer.playMyMedia(cmd.length,cmd); }catch (Exception e){ Log.e("Wrong:",e.toString()); } Log.e("FFmpegTest", "run: Time consuming:"+(System.currentTimeMillis()-startTime)); } }.start();
(3) Results
(4) Notes
The names of all files on the command line should not be given special characters, such as spaces, newlines, emoji, etc.
I always feel that I have left out nothing to say, no matter what, when I encounter problems, remember that the problems will always be solved if I grow up indecently and keep quiet.
Crap
To be honest, I've been interested in this since ffmpeg 3.0, but I've been stuck in compiling so package. I'm not familiar with linux system, and I can't get the gist. This time, I compiled so package directly according to God's footsteps, once or twice, and I knew it was a good time.
The command-line tools of ffmpeg can actually do a lot of interesting things, I wish you all a happy time.