基本环境: 1. 操作系统:Windows10 64位; 2. Android Studio 2.3,64位。 3. Android NDK开发包:直接使用Android Studio安装NDK。(需要梯子) 4.按照上述三编译好了ffmpeg相关的.so共享库文件和按照上述二编译好的SDL Demo程序
操作步骤: 第一步:拷贝ffmpeg的include文件和so文件到SDL工程目录中 1、将ffmpeg的include目录下的libavcodec、libavdevice等目录拷贝到android-project\jni\SDL\include目录下。 2、新建目录android-project\jni\src\lib,将编译好的ffmpelibavcodec-57.so、libavdevice-57.so等拷贝到这个目录下。 第二步,编辑android-project\jni\src\Android.mk 1、主要是添加ffmpeg有关库链接的支持,如下:
LOCAL_PATH := $(call my-dir) #begin 预编so模块,后面链接进来 include $(CLEAR_VARS) LOCAL_MODULE := avcodec LOCAL_SRC_FILES := lib/libavcodec-57.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := avdevice LOCAL_SRC_FILES := lib/libavdevice-57.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := avfilter LOCAL_SRC_FILES := lib/libavfilter-6.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := avformat LOCAL_SRC_FILES := lib/libavformat-57.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := avutil LOCAL_SRC_FILES := lib/libavutil-55.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := swresample LOCAL_SRC_FILES := lib/libswresample-2.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := swscale LOCAL_SRC_FILES := lib/libswscale-4.so include $(PREBUILT_SHARED_LIBRARY) #end include $(CLEAR_VARS) LOCAL_MODULE := main SDL_PATH := ../SDL LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include # Add your application source files here... LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.c \ main.c LOCAL_SHARED_LIBRARIES := SDL2 avcodec avdevice avfilter avformat avutil swresample LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog include $(BUILD_SHARED_LIBRARY)【坑】如果这句: LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.c \ main.c 放到前面,随LOCAL_PATH := $(call my-dir)后,这ndk-build编译出来后,将来在机器上执行“SDL App”,就是闪退,必须放到后面才行。
2、修改main.c文件,如下:
#include <stdlib.h> #include <stdio.h> #include <time.h> #include <android/log.h> #include "libavformat/avformat.h" #include "libavcodec/avcodec.h" #include "libswscale/swscale.h" #include "libavutil/imgutils.h" #include "libavutil/avutil.h" #include "SDL.h" #define LOG_TAG "JNILOG" #undef LOG #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) #define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) #define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__) typedef struct Sprite { SDL_Texture* texture; Uint16 w; Uint16 h; } Sprite; /* Adapted from SDL's testspriteminimal.c */ Sprite LoadSprite(const char* file, SDL_Renderer* renderer) { Sprite result; result.texture = NULL; result.w = 0; result.h = 0; SDL_Surface* temp; /* Load the sprite image */ temp = SDL_LoadBMP(file); if (temp == NULL) { fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError()); return result; } result.w = temp->w; result.h = temp->h; /* Create texture from the image */ result.texture = SDL_CreateTextureFromSurface(renderer, temp); if (!result.texture) { fprintf(stderr, "Couldn't create texture: %s\n", SDL_GetError()); SDL_FreeSurface(temp); return result; } SDL_FreeSurface(temp); return result; } void draw(SDL_Window* window, SDL_Renderer* renderer, const Sprite sprite) { int w, h; SDL_GetWindowSize(window, &w, &h); SDL_Rect destRect = {w/2 - sprite.w/2, h/2 - sprite.h/2, sprite.w, sprite.h}; /* Blit the sprite onto the screen */ SDL_RenderCopy(renderer, sprite.texture, NULL, &destRect); } int main(int argc, char *argv[]) { SDL_Window *window; SDL_Renderer *renderer; //char info[10000] = { 0 }; av_register_all(); //sprintf(info, "%s\n", avcodec_configuration()); //printf("%s\n", avcodec_configuration()); LOGI("SDL HelloWorld"); LOGI("%s\n", avcodec_configuration()); if(SDL_CreateWindowAndRenderer(0, 0, 0, &window, &renderer) < 0) exit(2); Sprite sprite = LoadSprite("image.bmp", renderer); if(sprite.texture == NULL) exit(2); /* Main render loop */ Uint8 done = 0; SDL_Event event; while(!done) { /* Check for events */ while(SDL_PollEvent(&event)) { if(event.type == SDL_QUIT || event.type == SDL_KEYDOWN || event.type == SDL_FINGERDOWN) { done = 1; } } /* Draw a gray background */ SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); SDL_RenderClear(renderer); draw(window, renderer, sprite); /* Update the screen! */ SDL_RenderPresent(renderer); SDL_Delay(10); } exit(0); }3、进入到android-project\jni目录,执行ndk-build,将在目录android-project\libs\armeabi-v7a下生成libavcodec-57.so,libavdevice-57.so,libavfilter-6.so,libavformat-57.so,libavutil-55.so,libswresample-2.so,libswscale-4.so,libmain.so,libSDL2.so共9个文件。
第三步,到Android studio编辑生成apk 1、将上述9个文件拷贝到“二、android studio 2.3 编译运行SDL 2.05 Demo”导入的andriod studio的hellosdl工程中的hellpsdl\app\src\main\jniLibs\armeabi-v7a目录中。 2、编辑SDLActivity.java文件,加入引用ffmpeg库文件代码:
public void loadLibraries() { System.loadLibrary("avcodec-57"); System.loadLibrary("avdevice-57"); System.loadLibrary("avfilter-6"); System.loadLibrary("avformat-57"); System.loadLibrary("avutil-55"); System.loadLibrary("swresample-2"); System.loadLibrary("swscale-4"); for (String lib : getLibraries()) { System.loadLibrary(lib); } }
能后编译,到设备执行,就可以在android studio的Andriod Monitor到catlog结果了。