基本环境:
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
#include
#include
#include
#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结果了。