android-studio使用cmake編譯ffmpeg實踐
阿新 • • 發佈:2018-11-06
本例使用的是合併的libffmpeg庫
,可參考之前的實踐操作 android全平臺編譯ffmpeg合併為單個庫實踐
目錄
配置環境
作業系統: ubuntu 16.05
注意: ffmpeg庫
的編譯使用的是android-ndk-r10e版本
,使用高版本編譯會報錯
而android-studio
工程中配合cmake
使用的版本則是android-ndk-r16b版本
新建工程ffmpeg-single-hello
- 配置
build.gradle
如下
android {
. .....
defaultConfig {
......
externalNativeBuild {
cmake {
cppFlags ""
}
ndk {
abiFilters "armeabi-v7a"
}
}
sourceSets {
main {
//庫地址
jniLibs. srcDirs = ['libs']
}
}
}
......
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
- 新建
CMakeLists.txt檔案
,配置如下
cmake_minimum_required(VERSION 3.4.1)
add_library(ffmpeg-hello
SHARED
src/main/cpp/ffmpeg_hello. c)
find_library(log-lib
log)
#獲取上級目錄的路徑
get_filename_component(PARENT_DIR ${CMAKE_SOURCE_DIR} PATH)
set(LIBRARY_DIR ${PARENT_DIR}/ffmpeg-single)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
set(CMAKE_VERBOSE_MAKEFILE on)
add_library(ffmpeg-single
SHARED
IMPORTED)
set_target_properties(ffmpeg-single
PROPERTIES IMPORTED_LOCATION
${LIBRARY_DIR}/libs/${ANDROID_ABI}/libffmpeg.so
)
#包含標頭檔案
include_directories(${LIBRARY_DIR}/libs/${ANDROID_ABI}/include)
target_link_libraries(ffmpeg-hello ffmpeg-single ${log-lib})
筆者這裡考慮到後續的都是基於同一個
libffmpeg.so庫
,因此不必每個module
都放置一個,因此單獨分離了一個元件ffmpeg-single
,將所需要的標頭檔案和庫
放置在libs
目錄
其他的單個庫例子
則都是依賴這個庫
- 新建類
FFmpegHello.java
package com.onzhou.ffmpeg.hello;
public class FFmpegHello {
static {
System.loadLibrary("ffmpeg");
System.loadLibrary("ffmpeg-hello");
}
public native String urlprotocolinfo();
public native String avformatinfo();
public native String avcodecinfo();
public native String avfilterinfo();
public native String configurationinfo();
}
- 在
src/main/cpp目錄新建原始檔ffmpeg_hello.c
#include <jni.h>
#include <stdio.h>
#include <time.h>
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavfilter/avfilter.h"
#include "libavutil/log.h"
#ifdef ANDROID
#include <android/log.h>
#define LOG_TAG "FFmpegHello"
#define LOGE(format, ...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, format, ##__VA_ARGS__)
#define LOGI(format, ...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, format, ##__VA_ARGS__)
#else
#define LOGE(format, ...) printf(LOG_TAG format "\n", ##__VA_ARGS__)
#define LOGI(format, ...) printf(LOG_TAG format "\n", ##__VA_ARGS__)
#endif
JNIEXPORT jstring JNICALL Java_com_onzhou_ffmpeg_hello_FFmpegHello_urlprotocolinfo
(JNIEnv * env, jobject obj){
char info[40000]={0};
av_register_all();
struct URLProtocol *pup = NULL;
//input
struct URLProtocol **p_temp = &pup;
avio_enum_protocols((void **)p_temp, 0);
while ((*p_temp) != NULL){
sprintf(info, "%s[in ][%10s]\n", info, avio_enum_protocols((void **)p_temp, 0));
}
pup = NULL;
//output
avio_enum_protocols((void **)p_temp, 1);
while ((*p_temp) != NULL){
sprintf(info, "%s[out][%10s]\n", info, avio_enum_protocols((void **)p_temp, 1));
}
LOGE("%s", info);
return (*env)->NewStringUTF(env, info);
}
JNIEXPORT jstring JNICALL Java_com_onzhou_ffmpeg_hello_FFmpegHello_avformatinfo
(JNIEnv * env, jobject obj){
char info[40000] = { 0 };
av_register_all();
AVInputFormat *if_temp = av_iformat_next(NULL);
AVOutputFormat *of_temp = av_oformat_next(NULL);
//input
while(if_temp!=NULL){
sprintf(info, "%s[in ][%10s]\n", info, if_temp->name);
if_temp=if_temp->next;
}
//output
while (of_temp != NULL){
sprintf(info, "%s[out][%10s]\n", info, of_temp->name);
of_temp = of_temp->next;
}
LOGE("%s", info);
return (*env)->NewStringUTF(env, info);
}
JNIEXPORT jstring JNICALL Java_com_onzhou_ffmpeg_hello_FFmpegHello_avcodecinfo
(JNIEnv * env, jobject obj){
char info[40000] = { 0 };
av_register_all();
AVCodec *c_temp = av_codec_next(NULL);
while(c_temp!=NULL){
if (c_temp->decode!=NULL){
sprintf(info, "%s[dec]", info);
}
else{
sprintf(info, "%s[enc]", info);
}
switch (c_temp->type){
case AVMEDIA_TYPE_VIDEO:
sprintf(info, "%s[video]", info);
break;
case AVMEDIA_TYPE_AUDIO:
sprintf(info, "%s[audio]", info);
break;
default:
sprintf(info, "%s[other]", info);
break;
}
sprintf(info, "%s[%10s]\n", info, c_temp->name);
c_temp=c_temp->next;
}
LOGE("%s", info);
return (*env)->NewStringUTF(env, info);
}
JNIEXPORT jstring JNICALL Java_com_onzhou_ffmpeg_hello_FFmpegHello_avfilterinfo
(JNIEnv * env, jobject obj){
char info[40000] = { 0 };
avfilter_register_all();
AVFilter *f_temp = (AVFilter *)avfilter_next(NULL);
while (f_temp != NULL){
sprintf(info, "%s[%10s]\n", info, f_temp->name);
}
LOGE("%s", info);
return (*env)->NewStringUTF(env, info);
}
JNIEXPORT jstring JNICALL Java_com_onzhou_ffmpeg_hello_FFmpegHello_configurationinfo
(JNIEnv * env, jobject obj){
char info[10000] = { 0 };
av_register_all();
sprintf(info, "%s\n", avcodec_configuration());
LOGE("%s", info);
return (*env)->NewStringUTF(env, info);
}
- 編譯打包執行,
輸出如下資訊:
專案地址:
https://github.com/byhook/ffmpeg4android
參考:
https://blog.csdn.net/leixiaohua1020/article/details/47008825