<android编译ffmpeg+x264+faac> <Android/NDK环境下FFmpeg及AAC,MP3,X264的编译>
2016-03-06 13:57
585 查看
《android编译ffmpeg+x264+faac》
http://blog.csdn.net/vblittleboy/article/details/243163031. 在x264的源码目录下创建b1.sh,内容如下:
点击(此处)折叠或打开
export NDK=/opt/google/android/android-ndk-r8e
export VERSION=4.4.3
export PREBUILT=$NDK/toolchains/arm-linux-androideabi-$VERSION/prebuilt
export PLATFORM=$NDK/platforms/android-8/arch-arm
./configure --enable-static \
--enable-shared \
--enable-pic \
--disable-asm \
--disable-cli \
--host=arm-linux \
--cross-prefix=$PREBUILT/linux-x86_64/bin/arm-linux-androideabi- \
--sysroot=$PLATFORM
2. 在ffmepg的父目录下创建b1.sh,内容如下:并创建目录elib,并把上面生成的lib264.a
拷贝到该目录下
点击(此处)折叠或打开
#!/bin/bash
export VERSION=4.4.3
export NDK=/opt/google/android/android-ndk-r8e
export PREBUILT=$NDK/toolchains/arm-linux-androideabi-$VERSION/prebuilt/linux-x86_64
export PLATFORM=$NDK/platforms/android-9/arch-arm
export FFMPEG_ROOT=/home/test/code/ffmpeg-1.1.5
export X264_ROOT=/home/test/code/x264_and #上面的x264的源码目录
export ELIB="$FFMPEG_ROOT/elib"
function build_one
{
$FFMPEG_ROOT/configure --target-os=linux \
--enable-cross-compile \
--enable-runtime-cpudetect \
--disable-asm \
--arch=arm \
--cc=$PREBUILT/bin/arm-linux-androideabi-gcc \
--cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \
--disable-stripping \
--nm=$PREBUILT/bin/arm-linux-androideabi-nm \
--sysroot=$PLATFORM \
--enable-nonfree \
--enable-version3 \
--disable-everything \
--enable-gpl \
--disable-doc \
--enable-avresample \
--enable-demuxer=rtsp \
--enable-muxer=rtsp \
--disable-ffplay \
--disable-ffserver \
--enable-ffmpeg \
--disable-ffprobe \
--enable-libx264 \
--enable-encoder=libx264 \
--enable-decoder=h264 \
--enable-protocol=rtp \
--enable-hwaccels \
--enable-zlib \
--disable-devices \
--disable-avdevice \
--extra-cflags="-I$X264_ROOT -fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated -mfloat-abi=softfp -mfpu=vfpv3-d16 -marm -march=armv7-a" \
--extra-ldflags="-L$ELIB"
make -j4
}
build_one
$PREBUILT/bin/arm-linux-androideabi-ar d libavcodec/libavcodec.a inverse.o
$PREBUILT/bin/arm-linux-androideabi-ld -rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -L$ELIB -soname libffmpeg.so -shared -nostdlib -z noexecstack -Bsymbolic --whole-archive --no-undefined -o libffmpeg.so libavcodec/libavcodec.a libavfilter/libavfilter.a
libavresample/libavresample.a libavformat/libavformat.a libavutil/libavutil.a libswscale/libswscale.a -lc -lm -lz -ldl -llog -lx264 --warn-once --dynamic-linker=/system/bin/linker $PREBUILT/lib/gcc/arm-linux-androideabi/$VERSION/libgcc.a
到此为止so文件已经编译完毕:
下面编译jni的so文件;
点击(此处)折叠或打开
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
MY_PATH := /home/wanjm/code/binary #上面的so文件的目录
LOCAL_MODULE := ffmpeg
LOCAL_SRC_FILES := $(MY_PATH)/libffmpeg.so #仅支持一个文件;
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := myffmp
LOCAL_SRC_FILES := VideoEncoder.c #jni的c文件;
LOCAL_C_INCLUDES := /home/wanjm/code/ffmpeg-1.2.4
LOCAL_LDLIBS := -llog -lm -lc -ldl -lz -lstdc++
LOCAL_STATIC_LIBRARIES := libffmpeg #引用5处生成的so文件;
include $(BUILD_SHARED_LIBRARY)
上面so方式弄出来的,还是两个文件,在实际的java中,要限价在libffmpeg.so,然后在加载myffmp; 反序后会报告少依赖包, 但是按照该顺序还是加载失败;
然后按照下面的写法,可以生成单个so文件,且可以调试;
点击(此处)折叠或打开
LOCAL_PATH := $(call my-dir)
MY_PATH :=/home/wanjm/code/binary/elib
include $(CLEAR_VARS)
#MY_PATH := /home/wanjm/code/binary
#LOCAL_MODULE := ffmpeg
#LOCAL_SRC_FILES := $(MY_PATH)/libffmpeg.so
#include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := avcodec
LOCAL_SRC_FILES := $(MY_PATH)/libavcodec.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := avformat
LOCAL_SRC_FILES := $(MY_PATH)/libavformat.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := avutil
LOCAL_SRC_FILES := $(MY_PATH)/libavutil.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := x264
LOCAL_SRC_FILES := $(MY_PATH)/libx264.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := swscale
LOCAL_SRC_FILES := $(MY_PATH)/libswscale.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := myffmp
LOCAL_SRC_FILES := VideoEncoder.c
LOCAL_C_INCLUDES := /home/wanjm/code/ffmpeg-1.2.4
LOCAL_LDLIBS := -llog -lm -lc -ldl -lz -lstdc++
LOCAL_STATIC_LIBRARIES := libavformat libavutil libavcodec libswscale libavutil libx264
include $(BUILD_SHARED_LIBRARY)
makefile 脚本: 注意-lgcc 应该放在最后,否则找到__aeabi_idiv等方法;
点击(此处)折叠或打开
VERSION=4.8
NDK_ROOT=/opt/google/android-ndk-r9b
TOOLCHAINS_ROOT=$(NDK_ROOT)/toolchains/arm-linux-androideabi-$(VERSION)/prebuilt/linux-x86_64
TOOLCHAINS_PREFIX=$(TOOLCHAINS_ROOT)/bin/arm-linux-androideabi
TOOLCHAINS_INCLUDE=$(TOOLCHAINS_ROOT)/lib/gcc/arm-linux-androideabi/$(VERSION)/include-fixed
SYSROOT=$(NDK_ROOT)/platforms/android-9/arch-arm
PLATFORM_INCLUDE=$(SYSROOT)/usr/include
PLATFORM_LIB=$(SYSROOT)/usr/lib
FLAGS= -fpic -DANDROID
#如果没有-lc,实际运行时会找不到gettimeofday;
LDFLAGS=-shared -L$(PLATFORM_LIB) --no-undefined -lc -llog -lm -lc -ldl -lz #-nostdlib -ldl -lm -Bdynamic -lc -lstdc++
#FLAGS="-I$(TOOLCHAINS_INCLUDE) -I$(PLATFORM_INCLUDE) " #-L$(PLATFORM_LIB) -nostdlib -lgcc -Bdynamic -lc"
CC=$(TOOLCHAINS_PREFIX)-gcc --sysroot=$(SYSROOT)
LD=$(TOOLCHAINS_PREFIX)-ld
libtime.so: main.o
$(LD) $(LDFLAGS) main.o -o libtime.so -L/home/wanjm/code/binary/elib -lavformat -lavutil -lavcodec -lswscale -lavutil -lx264 -L$(TOOLCHAINS_ROOT)/lib/gcc/arm-linux-androideabi/$(VERSION) -lgcc
cp libtime.so ../libs/armeabi
main.o: VideoEncoder.c
$(CC) -c VideoEncoder.c -o main.o -I/home/wanjm/code/ffmpeg-1.2.4
clean:
rm -rf libtime.so
rm main.o
一步到位的ffmpeg+x264 for android 的编译;
1. 建立目录android,其下放置解压的ffmpeg和x264源码目录;建立install 目录,和make目录;
2. 在make中创建build.sh; 注意此处用的是相对目录,所以只能在make目录下运行;
点击(此处)折叠或打开
#!/bin/bash
export VERSION=4.6
export NDK=/opt/google/android-ndk-r9b
export PREBUILT=$NDK/toolchains/arm-linux-androideabi-$VERSION/prebuilt/linux-x86_64
export PLATFORM=$NDK/platforms/android-9/arch-arm
export FFMPEG_ROOT=../ffmpeg-1.2.4
export X264_ROOT=../x264 #上面的x264的源码目录
export PREFIX=../install
export ELIB="$PREFIX/lib"
export FAAC_ROOT=../faac-1.28
function build_x264
{
cd $X264_ROOT
pwd
./configure --enable-static \
--prefix=$PREFIX \
--enable-shared \
--enable-pic \
--disable-asm \
--disable-cli \
--host=arm-linux \
--cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \
--sysroot=$PLATFORM
make
cp libx264.a $ELIB
cd -
}
function build_faac
{
cd $FAAC_ROOT
pwd
CFLAGS="-fpic -DANDROID -fpic -mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -mthumb -Os -fomit-frame-pointer
-fno-strict-aliasing -finline-limit=64 -DANDROID -Wa,--noexecstack -MMD -MP "
#FLAGS="--host=arm-androideabi-linux --enable-static --disable-shared --prefix=$HOME --enable-armv5e "
CROSS_COMPILE=$PREBUILT/bin/arm-linux-androideabi-
export CPPFLAGS="$CFLAGS"
export CFLAGS="$CFLAGS"
export CXXFLAGS="$CFLAGS"
export CXX="${CROSS_COMPILE}g++ --sysroot=${PLATFORM}"
export LDFLAGS="$LDFLAGS"
export CC="${CROSS_COMPILE}gcc --sysroot=${PLATFORM}"
export NM="${CROSS_COMPILE}nm"
export STRIP="${CROSS_COMPILE}strip"
export RANLIB="${CROSS_COMPILE}ranlib"
export AR="${CROSS_COMPILE}ar"
./configure --program-prefix=$PREFIX \
--host=arm-linux
make
cp ./libfaac/.libs/libfaac.a $ELIB
cd -
}
function build_one
{
$FFMPEG_ROOT/configure --target-os=linux \
--prefix=$PREFIX \
--enable-cross-compile \
--enable-runtime-cpudetect \
--disable-asm \
--arch=arm \
--cc=$PREBUILT/bin/arm-linux-androideabi-gcc \
--cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \
--disable-stripping \
--nm=$PREBUILT/bin/arm-linux-androideabi-nm \
--sysroot=$PLATFORM \
--enable-nonfree \
--enable-version3 \
--enable-gpl \
--disable-doc \
--enable-avresample \
--enable-demuxer=rtsp \
--enable-muxer=rtsp \
--disable-ffplay \
--disable-ffserver \
--enable-ffmpeg \
--disable-ffprobe \
--enable-libx264 \
--enable-libfaac --enable-nonfree \
--enable-encoder=libx264 \
--enable-decoder=h264 \
--enable-protocol=rtp \
--enable-encoder=libfaac \
--enable-decoder=aac \
--enable-hwaccels \
--enable-zlib \
--disable-devices \
--disable-avdevice \
--extra-cflags="-I$X264_ROOT -I$FAAC_ROOT/include -fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated -mfloat-abi=softfp -mfpu=vfpv3-d16 -marm -march=armv7-a" \
--extra-ldflags="-L$ELIB"
make -j4
make install
}
mkdir -p $ELIB
build_faac
build_x264
build_one
《Android/NDK环境下FFmpeg及AAC,MP3,X264的编译》
/article/8245288.html
本篇介绍在Android/Ndk环境下FFmpeg的编译及使用, FFmpeg自带了H264、AAC、MP3的解码器,但却没有(或没有好的)相应的编码器。相应的编码器需要使用第三方库。推荐使用的第三方库为x264(H264编码) 、FDK_AAC(AAC编码),lame(MP3编码)。
在顺序上,应该先编译好第三方库,最后再编译FFmpeg库。
【本书说明:本文作者:邵发,本文选自《FFmpeg视音频编程指南》。有关本书的详细信息请访问官网:http://www.afanihao.cn 】
【权利声明:作者保留本文的全部权利。作者授权任何人都可以自由转载本文,但转载时必须遵守以下限制:①转载时必须全文转载,不得有任何修改,包括“权利声明”和“本书说明”部分 ② 仅限于网络转载,即最终结果公布于网络上。凡是不遵守以上两条的转载行为视为侵权行为。除非本人允许,任何人不得将本文内容用于任何的其他用途。】
1.1 NDK环境的准备
本篇的演示示例使用的是android-ndk-r8e版本,但理论上也适用于更新的NDK版本。为了让你的编译过程极其顺利,应该对NDK作以下改动:进入目录 platforms/android-14/arch-arm/usr/lib
应该可以看到一些文件,例如 crtbegin_dynamic.o ,crtbegin_static.o crtend_so.o , crtbegin_so.o ,crtend_android.o,等等。
把这个目录下的所有文件拷贝到
\toolchains\arm-linux-androideabi-4.6\prebuilt\linux-x86\lib\gcc\arm-linux-androideabi\4.6
否则在链接的时候ld会提示“找不到crtbegin_so.o和crtend_so.o”的错误。
应该把NDK的相关工具都把加PATH环境变量中,例如,
#!/bin/sh export PATH=$PATH:/opt/ndk/android-ndk-r8e/ export PATH=$PATH: /opt/ndk/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/ |
1.2 FDK_AAC库的编译
如果你不打算使用AAC编码的功能,则可以略过本节。目前(2015年3月),fdk_aac的官方发布地址是在source_forge上,也许以后会变,作者可以自行搜索。目前地址为:http://sourceforge.net/projects/opencore-amr/files/fdk-aac/
本文使用的版本是fdk-aac-0.1.3,为减少不必要的麻烦,读者也请下载这个包。
1.2.1 修改configure脚本
修改脚本的目的是去除目标库的版本号,以适应Android/NDK的对库的加载要求。简单地讲,这是因为在Android/NDK项目的java代码中,使用System.loadLibrary()函数来加载so文件时,动态库是不能加版本号的。在fdk_aac的configure脚本里找到如下的行:
# This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${shared_ext} ${libname}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${shared_ext}' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no |
library_names_spec='$libname${shared_ext} $libname.a' |
1.2.2 新建配置脚本
在源码的根目录下建议一个myconfig.sh脚本。这是一个SHELL脚本,要求读者自己稍微了解一些SHELL脚本的写法。在这里只强调一点:SHELL脚本是以\n结尾的,如果你是在windows下面编辑的,那么应该用dos2unix来把文本的换行符转成unix格式。为了避免不必要的麻烦,把NDK解压缩在/opt/ndk/android-ndk-r8e目录,并将FDK的输出目录--prefix设置在/opt/ndk/openlib目录下。读者第一遍操作时,不要擅自修改目录,必须在熟练掌握之后再自行修改目录。
myconfig.sh里面内容为:
#!/bin/sh export CC=arm-linux-androideabi-gcc export CXX=arm-linux-androideabi-g++ export AR=arm-linux-androideabi-ar export LD=arm-linux-androideabi-ld export AS=arm-linux-androideabi-gcc export CFLAGS=" --sysroot=/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 " export CXXFLAGS=" --sysroot=/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 " export LDFLAGS=" -L/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm/usr/lib -march=armv7-a -Wl,--fix-cortex-a8 " ./configure --enable-static --prefix=/opt/ndk/openlib --host=arm-linux |
1.2.3 编译
如果你严格按照以上的操作进行,那么编译过程会非常简单。Linux下的开源软件一般都是分为三步编译 configure , make,make install,而fdk_aac也不例外。1) ./myconfig.sh
执行上述配置脚本,开始配置
2) make
3) make install
一切正常,将在/opt/ndk/openlib下存放输出库及头文件,注意这个库是去掉版本号的libfdk-aac。显然,Android/NDK的程序员会更喜欢不带版本号的库。
1.3 LAME-MP3的编译
如果你不打算在项目中使用mp3编码,则略过本节。本节介绍lame的编译,但遗憾的是,其动态库没有办法去掉版本号。所以本方法生成的目标动态库是带版本号的。
1.3.1 新建配置脚本
新建配置文件myconfig.sh,内容如下,#!/bin/sh export CC=arm-linux-androideabi-gcc export CXX=arm-linux-androideabi-g++ export AR=arm-linux-androideabi-ar export LD=arm-linux-androideabi-ld export CFLAGS=" --sysroot=/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm " export LDFLAGS=" -L/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm/usr/lib " ./configure --enable-static --prefix=/opt/ndk/openlib --host=arm-linux |
1.3.2 编译
1) ./myconfig.sh执行上述配置脚本,开始配置
2) make
3) make install
一切正常,将在/opt/ndk/openlib下存放输出库及头文件。
1.4 x264的编译
x264属于VLC的一部分,当前的源码位置为:ftp://ftp.videolan.org/pub/videolan/x264/snapshots/
本篇使用的源码版本为x264-snapshot-20140723-2245-stable.tar.bz2
1.4.1 修改configure脚本
这一步的目的是使输出的库文件不带版本号。如果你坚持认为版本号不影响你的开发,则忽略本小节。找到这一位置:
else echo "SOSUFFIX=so" >> config.mak echo "SONAME=libx264.so.$API" >> config.mak echo "SOFLAGS=-shared -Wl,-soname,\$(SONAME) $SOFLAGS" >> config.mak fi |
echo "SONAME=libx264.so" >> config.mak |
1.4.2 新建配置脚本
新建myconfig.sh配置脚本,#!/bin/sh export CC=arm-linux-androideabi-gcc export CXX=arm-linux-androideabi-g++ export AR=arm-linux-androideabi-ar export LD=arm-linux-androideabi-ld export AS=arm-linux-androideabi-gcc export CFLAGS=" --sysroot=/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16" export LDFLAGS=" -L/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm/usr/lib -march=armv7-a -Wl,--fix-cortex-a8 " ./configure --enable-static --enable-shared --prefix=/opt/ndk/openlib --host=arm-linux |
1.4.3 编译
1) ./myconfig.sh执行上述配置脚本,开始配置
2) make
3) make install
1.5 FFmpeg的编译
本示例使用的是FFmpeg2.1.3版本,可以从其官网ffmpeg.org上下载。如果不需要x264/aac/lame,可以直接进行本节的编译。
1.5.1 修改configure脚本
本节的目的是让输出的库不含有版本号。先找到configure的如下位置:
SHFLAGS='-shared -Wl,-soname,$$(@F)' LIBPREF="lib" LIBSUF=".a" FULLNAME='$(NAME)$(BUILDSUF)' LIBNAME='$(LIBPREF)$(FULLNAME)$(LIBSUF)' SLIBPREF="lib" SLIBSUF=".so" SLIBNAME='$(SLIBPREF)$(FULLNAME)$(SLIBSUF)' SLIBNAME_WITH_VERSION='$(SLIBNAME).$(LIBVERSION)' SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)' LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"' SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)' SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)' |
SLIBNAME_WITH_VERSION='$(SLIBNAME)' SLIBNAME_WITH_MAJOR='$(SLIBNAME)' LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"' SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)' SLIB_INSTALL_LINKS= |
1.5.2 修改配置脚本
新建myconfig.shexport NDK_ROOT=/opt/ndk export TMPDIR=/tmp ./configure --prefix=$NDK_ROOT/ffmpeg --sysroot=$NDK_ROOT/android-ndk-r8e/platforms/android-14/arch-arm --cross-prefix=arm-linux-androideabi- --target-os=linux --arch=arm --extra-cflags="-I$NDK_ROOT/openlib/include -fPIC " --extra-ldflags=-L$NDK_ROOT/openlib/lib --disable-programs --disable-doc --enable-shared --enable-cross-compile --enable-gpl --enable-nonfree --enable-libx264 --enable-libmp3lame --enable-libfdk-aac |
1.5.3 编译
1) ./myconfig.sh执行上述配置脚本,开始配置
2) make
3) make install
1.6 在Android.mk中引用FFmpeg库
1.6.1 使用静态库
推荐使用静态库。需要注意,FFmpeg库的静态库引用顺序是不能随便写的,为了避免不必要的麻烦,请照抄以下配置。在你的Android.mk中添加以下几行(见黑体字部分)
LOCAL_LDLIBS += -llog -lz # ffmpeg FFMPEG=/opt/ndk LOCAL_CFLAGS += -I$(FFMPEG)/include LOCAL_LDLIBS += -l$(FFMPEG)/lib/libavformat.a LOCAL_LDLIBS += -l$(FFMPEG)/lib/libavcodec.a LOCAL_LDLIBS += -l$(FFMPEG)/lib/libavdevice.a LOCAL_LDLIBS += -l$(FFMPEG)/lib/libswresample.a LOCAL_LDLIBS += -l$(FFMPEG)/lib/libavdevice.a LOCAL_LDLIBS += -l$(FFMPEG)/lib/libswscale.a LOCAL_LDLIBS += -l$(FFMPEG)/lib/libpostproc.a LOCAL_LDLIBS += -l$(FFMPEG)/lib/libavutil.a # fdk_aac LOCAL_LDLIBS += -l/opt/ndk/lib/libfdk-aac.a LOCAL_LDLIBS += -l/opt/ndk/lib/libmp3lame.a LOCAL_LDLIBS += -l/opt/ndk/lib/ libx264.a include $(BUILD_SHARED_LIBRARY) |
1.6.2 使用动态库
不推荐使用动态库,此过程过于复杂。要注意的有两点:①编译的时候,必须去除库的版本号 ② 在Java代码中加载的时候,要注意加载的顺序。以下可以加在Android.mk中,但是仅供参考,遇到自己问题需要自己调试
# ffmpeg FFMPEG=f:/Ndk/ffmpeg LOCAL_CFLAGS += -I$(FFMPEG)/include LOCAL_LDLIBS += -L$(FFMPEG)/lib LOCAL_LDLIBS += -lavformat -lavcodec -lswresample -lswscale -lavutil -lavfilter include $(BUILD_SHARED_LIBRARY) |
1.6.3 在C++中使用ffmpeg
ffmpeg的库是按C编译的,里面的符号都是C格式,因此,若在C++中使用,还是要使用extern "C"这种技术。相关语法请参考《C/C++语法指南》(作者:邵发,官网http://www.afanihao.cn)。为了大家的方便,在/opt/ndk/ffmpeg/include下新建一个ffmpeg.h,内容为:
#ifndef _FFMPEG_H #define _FFMPEG_H #ifdef __cplusplus extern "C" { #define INT64_C(val) val##LL #define UINT64_C(val) val##ULL #endif #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libswscale/swscale.h> #include <libavutil/avutil.h> #include <libavutil/opt.h> #include <libavutil/imgutils.h> #include <libswresample/swresample.h> #include <libavutil/error.h> #include <libavfilter/avfiltergraph.h> #include <libavfilter/avcodec.h> #include <libavfilter/buffersink.h> #include <libavfilter/buffersrc.h> #ifdef __cplusplus } #endif #endif |
第一篇文章我添加rtmp静态库没有遇到问题;但是我用别的ffmpeg的sh文件从新编译就遇到了问题;
后面的文章是讲解,根据github工程,ffmpeg工程的configure文件修改为:
我们可以根据自己的工程修改;
#enabled librtmp && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket
enabled librtmp && require librtmp librtmp/rtmp.h RTMP_Socket -L${LIBRTMP_DIR}/android/${CPU}/lib -lrtmp
sh文件为:
ADDI_CFLAGS="${CPU_CFLAGS} -I${OPENSSL_DIR}/include -I${LIBRTMP_DIR}/android/${CPU}/include -L${LIBRTMP_DIR}/android/${CPU}/lib -lrtmp"
ADDI_LFLAGS="-L${OPENSSL_DIR}/libs/armeabi -L${LIBRTMP_DIR}/android/${CPU}/lib -lrtmp"
所以在下面写出看到的解决方法:
《编译ffmpeg以支持rtmp, librtmp
not found问题》 http://blog.csdn.net/glcdw/article/details/7558303
在mingw下编译ffmpeg,并加上对rtmp的支持,即要先编译librtmp. 编译过程出了个librtmp not found问题,google了一圈,发现有很多类似的问题,但都和我的不完全一样。我的根本问题是mingw下的pkg-config没有正确安装。librtmp经过make和make install后,库文件和头文件都已经分别拷贝到/usr/local/lib和/usr/local/include目录下,ffmpeg在configure时找不到librtmp,为什么找不到呢?百思不得其解,无奈之下google,最终得到提示。
打开configure文件,发现下面一行
enabled librtmp && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket
原来ffmpeg通过pkg-config去找librtmp,难怪找不着了。
解决办法:
以#符号注释掉enabled librtmp一行
在configure时加上参数
./configure \
... ...
--extra-ldflags="-L/usr/local/lib" \
--extra-cflags="-I/usr/local/include" \
--extra-libs="-lrtmp" \
... ...
《ERROR: librtmp not found》 http://stackoverflow.com/questions/9634496/building-ffmpeg-with-librtmp-for-android
I'm trying to build all-in-one static binary of FFMPEG with NDK r7b and everything works fine untill i try to build it with RTMP support. I'm usind sources from https://github.com/guardianproject/android-ffmpeg with librtmp2.4 and custom config like this .configure \ --target-os=linux \ --cross-prefix=arm-linux-androideabi- \ --arch=arm \ --sysroot=/home/andrey/android-ndk-r7b/platforms/android-3/arch-arm \ --enable-static \ --disable-shared \ --disable-symver \ --enable-small \ --disable-devices \ --disable-avdevice \ --enable-gpl \ --enable-librtmp \ --prefix=../build/ffmpeg/armeabi \ --extra-cflags=-I../rtmpdump/librtmp \ --extra-ldflags=-L../rtmpdump/librtmp \ and rtmpdump directory lays on the same level as ffmpeg. As i understand last two strings in my config says where compiler may find sources of librtmp. But all i get is ERROR: librtmp not found I'm not expereienced with NDK and obviosly i missing some important part but i can't find it by myself. android configuration android-ndk ffmpeg rtmp
| ||
add a comment |
1 Answer
activeoldestvotesup vote10down voteaccepted | This is challenging, but I think I have a solution. The problem at configure-time is that FFmpeg wants to detect a proper librtmp installation via the pkg-config management system. I'm assuming your have successfully cross-compiled librtmp in the directory referenced by ../rtmpdump. Edit the FFmpeg configure script and search for the line: enabled librtmp && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket Comment that out (put a '#' at the front of the line). Now, re-run configure, only with these modifications: --extra-cflags="-I/full/path/to/rtmpdump" It may help to have an absolute path here. Also, omit /librtmp/ at the end since the #include directives already prefix the header files with librtmp/. Next: --extra-ldflags="-L/full/path/to/rtmpdump -lrtmp" Again, absolute path, and specify the library to link against since we commented out that logic via configure. Now, configure should succeed and the cross-compilation should also be happy. The final ffmpeg binary should report the family of RTMP modules under protocols: ffmpeg -protocols [...] rtmp rtmpe rtmps rtmpt rtmpte Note that I don't have an NDK dev environment to test this on. But I tested on my desktop Ubuntu system by compiling librtmp (without the package being installed via pkg-config) and then performing the above steps. |
如何使用ndk为ffmpeg编译rtmp+polarssl静态库
如何使用ndk为ffmpeg编译rtmp+polarssl静态库?这个问题花了我整整一天时间。其中遇到很多小问题,这里记录一下,方便自己也方便其他人。1、编译polarssl,查看其Readme文件即可,不需要configure,只需要make时带上必要的参数即可,不过要记得在每一次执行make命令时都带上CC的参数(指向你的arm gcc),因为我试过在make install时没有带上CC的参数,虽然能编译出polarssl但是未能正确被rtmp引用到。
2、因为前面我用的polarssl是当前最新(1.3.7)版本,而librtmp使用的好像是polarssl1.0.0以下版本的api,所以需要修改rtmp部分源码,让其调用新版polarssl的api,这里的修改可以参照《Migrating from PolarSSL-1.2 to the PolarSSL 1.3 branch》和《[rtmpdump] branch master updated. a312ac7 Fix compat with PolarSSL >= 1.1.0》。
3、出现 undefined reference to `havege_random’错误,这里是因为polarssl默认关闭了havege模块,需要你手动开启,主要就是修改include/polarssl/config.h,去掉POLARSSL_HAVEGE_C前的注释,也就是要定义POLARSSL_HAVEGE_C,如下:
#define POLARSSL_HAVEGE_C
4、在编译出上面两个库之后,可以开始编译ffmpeg(2.1.1版本)了,如果遇到下面的问题 check_pkg_config librtmp librtmp/rtmp.h RTMP_Socket
ERROR: librtmp not found
这里有三种解决方法:
第一种,因为是网络上传播最多的,算是比较简便的方法,就是修改ffmpeg的configure,将以下一行:
enabled librtmp && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket
改为:
enabled librtmp && require librtmp librtmp/rtmp.h RTMP_Socket -lrtmp -lpolarssl -lz
或者直接注释掉&& *** 部分,然后再自己加上librtmp的库路径也行
第二种,(比较推荐,因为解决了这个会顺带解决大部分找不到库的错误!)因为这里使用了pkg-config工具查找库,而这个工具ndk并没有附带提供,而出现check_pkg_config相关错误的话,只要稍加注意,会发现在使用configure配置ffmpeg的交叉编译时,已经有相应的pkg-config不存在的警告了。我对这个工具不熟悉,所以我只是简单地加上了一个软链接到系统的pkg-config,如下:
ln -s /usr/bin/pkg-config /home/cidy0106/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-pkg-config
这个时候重新configure的话可能会出现找不到polarssl库的错误提示,需要修改一下librtmp安装目录里的librtmp.pc,把以下内容:
Libs: -L${libdir} -lrtmp -lz
改为:
Libs: -L${libdir} -lrtmp -lz -lpolarssl
至此,就可以正确编译出ffmpeg了
相关文章推荐
- Android Mediaplayer 三种从资源文件中获取数据播放
- 动态输入日期与时间(DatePicker与TimePicker应用)
- 第4章 Android odex文件格式 第四节
- android--List属性
- Android 常用代码
- [android] 采用断点调试的方式观察pull解析的流程
- Android6的Logger日志系统
- Android6的Logger日志系统
- Android数据存储之——内部存储
- 安卓基础
- 颜色标签
- Android实现数据存储技术
- Android apk动态加载机制的研究(二):资源加载和activity生命周期管理【转】
- Android apk动态加载机制的研究【转】
- 自学android——AutoCompleteTextView的使用
- android studio查看logcat日志
- Android SDK在线更新镜像服务器大全
- 谷歌TabLayout的简单例子
- 安装Android的历程
- Android数据存储的三种方式-SharedPrefrences,File,SQLite