分类: Android平台
2013-03-20 11:27:45
环境是ubuntu 10.04LTS 虚拟机是vmware
一、 ffmpeg的安装
1、 下载
a. 安装git。在终端下执行apt-get install git-core,注意是在root 权限下执行。
b. 下载最新版本的ffmpeg。在终端输入git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg
2、 编译
a. 进入前面下载的ffmpeg目录下,创建一个config.sh文件,里面内容如下:
export PREBUILT=/home/android/android-ndk-r8b/toolchains/arm-linux-androideabi-4.6
export PLATFORM=/home/android/android-ndk-r8b/platforms/android-14/arch-arm
export TMPDIR=/home/work/tmp
./configure \
--target-os=linux \
--arch=arm \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-avdevice \
--disable-avfilter \
--disable-postproc \
--disable-swresample \
--disable-avresample \
--disable-symver \
--disable-debug \
--disable-stripping \
--disable-yasm \
--disable-asm \
--enable-gpl \
--enable-version3 \
--enable-nonfree \
--disable-doc \
--enable-static \
--disable-shared \
--enable-cross-compile \
--prefix=/home/android/ffmpeg \
--cc=$PREBUILT/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc \
--cross-prefix=$PREBUILT/prebuilt/linux-x86/bin/arm-linux-androideabi- \
--nm=$PREBUILT/prebuilt/linux-x86/bin/arm-linux-androideabi-nm \
--extra-cflags="-fPIC -DANDROID -I$PLATFORM/usr/include" \
--extra-ldflags="-L$PLATFORM/usr/lib -nostdlib"
c. 改变权限 chmod +x config.sh
d. 执行 ./config.sh 此时会提示有关一些静态变量相关的错误,需要对libavutil/libm.h 进行一些修改:ctrl+f 查找到static ,把带有这个关键字的方法注释掉,再重新./config.sh
e. make
f. make install
以上几步就可以编译出静态库文件libavcodec libavformat libavutil libswscale及其头文件
库和头文件都是在libavcodec libavformat libavutil libswscale 这几个目录下。
二、 ffmpeg在android的使用(编程)
1、建立一个Android应用工程,创建文件TestNDK.java
package com.myprj.testndk;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class TestNDK extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_ndk);
TextView tv=new TextView(this);
tv.setText(stringFromJNI());
setContentView(tv);
}
public native String stringFromJNI();
public native String unimplementedStringFromJNI();
static{
System.loadLibrary("TestNDK"); //注意名称要跟下面生成的模块名称保持一致
}
}
用eclipse编译该工程,生成相应的.class文件,这步必须在下一步之前完成,因为生成.h文件需要用到相应的.class文件。
2. 编写相应的C/C++代码
a. 生成相应.h文件:
首先在终端下进入刚刚建立的tetsandroid工程的目录,然后cd到工程目录文件夹下,
输入javah -classpath bin/classes/ -jni com.myprj.testndk.TestNDK
这一步特别需要注意类的路径,否者很有可能无法生成头文件
成功后生成一个com_myprj_testndk_TestNDK.h文件
我原本是想将该.h文件放在jni目录下的,无耐,不能在jni文件夹下生成,在工程文件下生成,只能将.h文件拷贝到jni目录下。若哪位清楚原因麻烦告知下,谢谢。
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class com_myprj_testndk_TestNDK */
#ifndef _Included_com_myprj_testndk_TestNDK
#define _Included_com_myprj_testndk_TestNDK
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_myprj_testndk_TestNDK
* Method: stringFromJNI
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_myprj_testndk_TestNDK_stringFromJNI
(JNIEnv *, jobject);
/*
* Class: com_myprj_testndk_TestNDK
* Method: unimplementedStringFromJNI
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_myprj_testndk_TestNDK_unimplementedStringFromJNI
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
上面代码中的JNIEXPORT 和 JNICALL 是jni的宏。这个函数名比较长,不过很有规律的, 完全按照:java_pacakege_class_mathod 形式来命名。
b. 编写相应的.c文件:jni/TestNDK.c
#include
#include
#include "avcodec.h"
#include "avformat.h"
#include "avutil.h"
#include "swscale.h"
JNIEXPORT jstring JNICALL Java_com_myprj_testndk_TestNDK_stringFromJNI
(JNIEnv* env, jobject thiz)
{
char str[25];
sprintf(str, "%d", avcodec_version());
return (*env)->NewStringUTF(env,str);
}
3. 编译TestNDK.c 生成相应的库
a. 编写jni/Android.mk文件
Android.mk 文件是Android 的 makefile文件,内容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := avformat
LOCAL_SRC_FILES := libavformat.a
LOCAL_CFLAGS :=-Ilibavformat
LOCAL_EXPORT_C_INCLUDES := libavformat
LOCAL_EXPORT_CFLAGS := -Ilibavformat
LOCAL_EXPORT_LDLIBS := -llog
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := avcodec
LOCAL_SRC_FILES := libavcodec.a
LOCAL_CFLAGS :=-Ilibavcodec
LOCAL_EXPORT_C_INCLUDES := libavcodec
LOCAL_EXPORT_CFLAGS := -Ilibavcodec
LOCAL_EXPORT_LDLIBS := -llog
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := avutil
LOCAL_SRC_FILES := libavutil.a
LOCAL_CFLAGS :=-Ilibavutil
LOCAL_EXPORT_C_INCLUDES := libavutil
LOCAL_EXPORT_CFLAGS := -Ilibavutil
LOCAL_EXPORT_LDLIBS := -llog
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := swscale
LOCAL_SRC_FILES :=libswscale.a
LOCAL_CFLAGS :=-Ilibavutil -Ilibswscale
LOCAL_EXPORT_C_INCLUDES := libswscale
LOCAL_EXPORT_CFLAGS := -Ilibswscale
LOCAL_EXPORT_LDLIBS := -llog -lavutil
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := TestNDK #注意该名称跟上面的一致
LOCAL_C_INCLUDES += $(LOCAL_PATH) \
$(LOCAL_PATH)/include
LOCAL_SRC_FILES := TestNDK.c
LOCAL_LDLIBS := -L$(LOCAL_PATH) -lm -lz
LOCAL_STATIC_LIBRARIES := avformat avcodec avutil swscale
include $(BUILD_SHARED_LIBRARY)
c. 将已编译好的ffmpeg相关的静态库和头文件拷贝到jni目录下,具体有哪些看截图
d.进入到jni目录下进行编译 输入/home/android/android-ndk-r8b/ndk-build
e.生成.so后再对java工程进行编译 run as。我的是用真机调试,截图如下:
其中3604836就是ffmpeg的版本信息。
本例子只是一个简单的测试demo,以后大家要扩展自己的解码器应该查看与ffmpeg相关文档。本人接下来也是继续进行相关开发。
注:本人用此方法并没有像网上说的会出现很多相关问题。
刚开始接触ffmpeg,由于水平有限,若有不当之处望不吝指出。
本文参考的网站有:
http://blog.csdn.net/jacklam200/article/details/8548675