利用ffmpeg框架扩展Android平台解码器

Andorid平台本身的多媒体框架opencore支持音频格式有:3GPP(.3gp)、MPEG-4(.mp4,.m4a)、mp3、Type 0 and 1(.mid,.xmf,.mxmf).Also RTTTL/RTX(.rtttl,.rtx), OTA(.ota),andiMelody(.imy)、Ogg(.ogg) (普遍用的比较多的一种)、WAVE(.wav),支持的视频格式只有两种:3gp、MP4两种;很显然支持的视频格式太少,如果我们要做一个通用的多媒体播放器的话是远远不够的。像rm,rmvb,avi等这些格式都是最常见的视频格式。我们可以通过开源框架ffmpeg通过ndk框架的jni的编程方式来实现以上三种视频的解码。FFmpeg是一个集录制、转换、音/视频编码解码功能为一体的完整的开源解决方案。FFmpeg的开发是基于Linux操作系统,但是可以在大多数操作系统中编译和使用。FFmpeg支持MPEG、DivX、MPEG4、AC3、DV、FLV等40多种编码,AVI、MPEG、OGG、Matroska、ASF等90多种解码.TCPMP,VLC,MPlayer等开源播放器都用到了FFmpeg。

下面开始我们的学习:

第一步:我们要下载ffmpeg源码并利用andorid ndk框架对ffmpeg编译为ffmpeg.so类库。源码下载地址大家可以查看http://www.ffmpeg.org/download.html有git和svn等几种下载方式。推荐大家用git方式下载,Git下载地址(git://git.videolan.org/ffmpeg.git)编译完成后会生成一个libffmpeg.so文件该动态链接库文件就是我们后边要用到的ffmpeg框架;这个so里的是jni方法,可以由java层调用的,而这些jni方法里用到的函数则就是来至libffmpeg.so

第二步:利用andorid提供的ndk框架编写自己用于解码的c文件具体操作步骤如下。拿一个标准的ndk例子来做的测试就是ndk samples文件夹里的hello-jni工程。进入该工程的jni目录,将ffmpeg的源代码拷到该目录下,做这部的原因是你要编译的so文件里需要调用ffmpeg的方法,自然要引用ffmpeg里的h文件,然后将libffmpeg.so文件拷到ndk目录下的platforms/Android-5/arch-arm/usr/lib目录下因为等等系统编译的时候要用。接下来就编辑android.mk和hello-jni.c文件

android.mk

#Copyright(C)2009 The Android Open SourceProject

#Licensed under the Apache License,Version2.0(the"License");

#you may not use this file except incompliance with the License.

#You may obtain a copy of the License at

#http://www.apache.org/licenses/LICENSE-2.0

#Unless required by applicable law oragreed to in writing,software

#distributed under the License isdistributed on an"AS IS"BASIS,

#WITHOUT WARRANTIES OR CONDITIONS OF ANYKIND,either express or implied.

#See the License for the specific languagegoverning permissions and

#limitations under the License.

#

LOCAL_PATH:=$(call my-dir)

include$(CLEAR_VARS)

PATH_TO_FFMPEG_SOURCE:=$(LOCAL_PATH)/ffmpeg

LOCAL_C_INCLUDES+=$(PATH_TO_FFMPEG_SOURCE)

LOCAL_LDLIBS:=-lffmpeg

LOCAL_MODULE:=hello-jni

LOCAL_SRC_FILES:=hello-jni.c

include$(BUILD_SHARED_LIBRARY)

PATH_TO_FFMPEG_SOURCE:=$(LOCAL_PATH)/ffmpeg

这行是定义一个变量,也就是ffmpeg源码的路径

LOCAL_C_INCLUDES+=$(PATH_TO_FFMPEG_SOURCE)

 

这行是指定源代码的路径,也就是刚才拷过去的ffmpeg源码,$(LOCAL_PATH)是根目录,如果没有加这行那么引入ffmpeg库中的h文件编译就会出错说找不到该h文件。

LOCAL_LDLIBS:=-lffmpeg

这行很重要,这是表示你这个so运行的时候依赖于libffmpeg.so这个库,再举个例子:如果你要编译的so不仅要用到libffmpeg.so这个库还要用的libopencv.so这个库的话,你这个参数就应该写成

LOCAL_LDLIBS:=-lffmpeg-lopencv

hello-jni.c

 利用ffmpeg框架扩展Android平台解码器

#include<ffmpeg/libavcodec/avcodec.h>

这行是因为下面要用到avcodec_version()这个函数。

改完这两个文件以后就可以编译了~~用ndk-build命令编译完后在工程的libs/armeabi目录底下就会有一个libhello-jni.so文件了!(两行眼泪啊~终于编译成功了)编译完成后就可以进行测试了,记得将libffmpeg.so也拷到armeabi目录底下,并在java代码中写上

static{

System.loadLibrary("ffmpeg");

System.loadLibrary("hello-jni");

}

HelloJni.java

利用ffmpeg框架扩展Android平台解码器

到此就完成了,将程序装到手机可看到打印出“3426306”,google搜索“ffmpeg 3426306”得知果然是ffmpeg的东西,证明成功的调用了libffmpeg.so库里的方法了。本例子只是一个测试的ffmpeg框架的测试demo,以后大家要扩展自己的解码器必须查看与ffmpeg的开发文档。