文章标题

FFmpeg:初步编译使用[Android]

1.安装NDK:http://dl.google.com/android/ndk/android-ndk-r9-linux-x86.tar.bz2

 sudo gedit ~/.bashrc
 末尾添加:
 #add NDK
 PATH=$PATH:/home/sheldon/Android/android-ndk-r9/

 source ~/.bashrc : 立即生效配置,可以使用”ndk-build”指令

2.FFmpeg官方网站 http://www.ffmpeg.org/ 下载源代码.

3.修改configure,将生成lib的版本号置于.so之前,以防Android无法加载:

SLIBNAME_WITH_MAJOR=’ (SLIBNAME). (LIBMAJOR)’

LIB_INSTALL_EXTRA_CMD=’$$(RANLIB) “$(LIBDIR)/$(LIBNAME)”’

SLIB_INSTALL_NAME=’$(SLIBNAME_WITH_VERSION)’

SLIB_INSTALL_LINKS=’ (SLIBNAMEWITHMAJOR) (SLIBNAME)’

SLIBNAME_WITH_MAJOR=’ (SLIBPREF) (FULLNAME)- (LIBMAJOR) (SLIBSUF)’
LIB_INSTALL_EXTRA_CMD=’$$(RANLIB)”$(LIBDIR)/$(LIBNAME)”’
SLIB_INSTALL_NAME=’$(SLIBNAME_WITH_MAJOR)’
SLIB_INSTALL_LINKS=’$(SLIBNAME)’
VERSION_SCRIPT_POSTPROCESS_CMD=”cat”

4.编写build_android.sh脚本文件,如果从网上直接copy过去可能会是dos格式,使用dos2unix build_android.sh 转换一下,删掉多余空格:

!/bin/bash : 以下三个变量根据自己系统环境配置

NDK=/home/sheldon/Android/android-ndk-r9/
SYSROOT= NDK/platforms/android9/archarm/TOOLCHAIN= NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86

function build_one
{
./configure \
–prefix= PREFIX enableshared disablestatic disabledoc disableffmpeg disableffplay disableffprobe disableffserver disabledoc disablesymver enablesmall crossprefix= TOOLCHAIN/bin/arm-linux-androideabi- \
–target-os=linux \
–arch=arm \
–enable-cross-compile \
–sysroot= SYSROOT extracflags=Osfpic ADDI_CFLAGS” \
–extra-ldflags=” ADDILDFLAGS  ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
}

CPU=arm
PREFIX= (pwd)/android/ CPU
ADDI_CFLAGS=”-marm”
build_one

5.增加执行权限,执行:
chmod a+xbuildandroid.sh ./build_android.sh

生成:[头文件]android/arm/include/.h 和  [动态库文件]android/arm/lib/.so

6.创建Android工程使用lib:
(1)创建一个新的Android工程FFmpeg4android。
(2)在工程目录下创建jni文件夹,与java目录同级。
(3)在jni下创建prebuilt/armeabi目录,然后:
将上面FFmpeg source code编译生成的so文件(带版号的真实库而不是链接文件)放入到该目录下的armeabi目录;
将android/arm/include/下的所有头文件夹拷贝到该jni目录下.
(4)创建包含native方法的类(java层直接调用的接口),先在src/main/java/下创建FFmpegNative.java类文件。主要包括加载so库文件和一个native测试方法两部分,其内容如下:

package com.li.sheldon.ffmpeg4android;

/**
* Created by sheldon on 17-1-4.
*/
public class FFmpegNative {
static{
 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”);
System.loadLibrary(“ffmpegjni”);
}
private native int ffmpeg_h264(int codecID);

public int test_h246(int id){
    return ffmpeg_h264(id);
}

}
(5)用javah创建.头文件:

  -classpath <路径> 用于装入类的路径
  -d <目录> 输出目录
  -jni 生成 JNI样式的头文件(默认)
javah -classpath /FFmpeg4android/app/src/main/java/ -d ./ -jni com.li.sheldon.ffmpeg4android.FFmpegNative
-classpath 后面的路径是指包”com.li.sheldon.ffmpeg4android”所在的根路径
会在当前目录产生com_li_sheldon_ffmpeg4android_FFmpegNative.h的C头文件;

(6)根据头文件名,建立相同名字才C源文件com_li_sheldon_ffmpeg4android_FFmpegNative.c
在这个源文件中实现头文件中定义的方法,核心部分代码如下:

include “com_li_sheldon_ffmpeg4android_FFmpegNative.h”

JNIEXPORT jint JNICALL Java_com_li_sheldon_ffmpeg4android_FFmpegNative_ffmpeg_1h264
(JNIEnv* env, jobject thiz, jint codecID)
{
AVCodec* codec = NULL;
av_register_all();//该函数在所有基于ffmpeg的应用程序中几乎都是第一个被调用的。只有调用了该函数,才能使用复用器,编码器等
 codec = avcodec_find_decoder(codecID);//通过code ID查找一个已经注册的音视频编码器。H264的codecID是28,所以我们java那边传28下来如果检测到H264注册过了这边codec就不为空,返回0
  if(codec != NULL){
 return 0;
}else{
return -1;
}
}

(7)编写Android.mk,内容如下:

APP_ABI := armeabi armeabi-v7a x86

ifeq ($(APP_ABI), x86)
LIB_NAME_PLUS := x86
else
LIB_NAME_PLUS := armeabi
endif

LOCAL_PATH:= $(call my-dir)

include (CLEARVARS)LOCALMODULE:=avcodecprebuilt (LIB_NAME_PLUS)
LOCAL_SRC_FILES:= prebuilt/ (LIBNAMEPLUS)/libavcodec57.soinclude (PREBUILT_SHARED_LIBRARY)

include (CLEARVARS)LOCALMODULE:=avdeviceprebuilt (LIB_NAME_PLUS)
LOCAL_SRC_FILES:= prebuilt/ (LIBNAMEPLUS)/libavdevice57.soinclude (PREBUILT_SHARED_LIBRARY)

include (CLEARVARS)LOCALMODULE:=avfilterprebuilt (LIB_NAME_PLUS)
LOCAL_SRC_FILES:= prebuilt/ (LIBNAMEPLUS)/libavfilter6.soinclude (PREBUILT_SHARED_LIBRARY)

include (CLEARVARS)LOCALMODULE:=avformatprebuilt (LIB_NAME_PLUS)
LOCAL_SRC_FILES:= prebuilt/ (LIBNAMEPLUS)/libavformat57.soinclude (PREBUILT_SHARED_LIBRARY)

include (CLEARVARS)LOCALMODULE:=avutilprebuilt (LIB_NAME_PLUS)
LOCAL_SRC_FILES := prebuilt/ (LIBNAMEPLUS)/libavutil55.soinclude (PREBUILT_SHARED_LIBRARY)

include (CLEARVARS)LOCALMODULE:=swresampleprebuilt (LIB_NAME_PLUS)
LOCAL_SRC_FILES := prebuilt/ (LIBNAMEPLUS)/libswresample2.soinclude (PREBUILT_SHARED_LIBRARY)

include (CLEARVARS)LOCALMODULE:=swscaleprebuilt (LIB_NAME_PLUS)
LOCAL_SRC_FILES := prebuilt/ (LIBNAMEPLUS)/libswscale4.soinclude (PREBUILT_SHARED_LIBRARY)

include (CLEARVARS)ifeq( (APP_ABI), x86)
TARGET_ARCH:=x86
TARGET_ARCH_ABI:=x86
else
LOCAL_ARM_MODE := arm
endif

LOCAL_MODULE := libffmpegjni
LOCAL_SRC_FILES := com_li_sheldon_ffmpeg4android_FFmpegNative.c
LOCAL_LDLIBS := -L (SYSROOT)/usr/liblloglzLOCALSHAREDLIBRARIES:=avcodecprebuilt (LIB_NAME_PLUS) \
avdevice-prebuilt- (LIBNAMEPLUS) avfilterprebuilt (LIB_NAME_PLUS) \
avformat-prebuilt- (LIBNAMEPLUS) avutilprebuilt (LIB_NAME_PLUS) \
swresample-prebuilt- (LIBNAMEPLUS) swscaleprebuilt (LIB_NAME_PLUS)
LOCAL_C_INCLUDES += -L(SYSROOT)/usr/include  
LOCAL_C_INCLUDES +=
(LOCAL_PATH)/include

ifeq ( (APPABI),x86)LOCALCFLAGS:=DUSEX86CONFIGelseLOCALCFLAGS:=DUSEARMCONFIGendifinclude (BUILD_SHARED_LIBRARY)

(8) 编写Application.mk, 指定编译平台[可省略]
APP_PROJECT_PATH := $(call my-dir)/..

APP_MODULES := libffmpegjni

编译so文件:
打开cmd命令行,进入FFmpeg4Android\jni目录下,执行如下命令:
ndk-build  
截止本步骤完成,将在FFmpeg4android/app/src/main/libs/armeabi/下另外生成了libffmpegjni.so文件, cp到FFmpeg4android/app/libs/armeabi/下由java类加载。
ps:共享库将被拷贝到 $PROJECT/obj/local 和 $PROJECT/libs/<abi> (stripped)  主要是用在将已经编译好的第三方库.

————————-如果ndk编译报错,加下面一段

build.greadle(app):

sourceSets.main{
  jniLibs.srcDir ‘libs’
  jni.srcDirs = [] //disable automatic ndk-build call
}

(9)修改layout/main.xml,给TextView增加id,以便在代码中操作它:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值