Android音视频——Linux(cygwin)配置ndk,编译FFmpeg、RTMP

一. 准备工作

这里简单说下为什么我都是选择用新版本,因为NDK在r18及以上版本移除了gcc,ffmpeg最新的版本也是针对交叉编译Android平台库,默认使用clang编译,编译方式变了,当然某些文件的路径就变了。这就是为啥我们使用新版本,照着网上博客的编译脚本CV大法搞不定的原因。我这里被坑的也是一言难尽。

  1. linux操作系统 ,你可以选择多种方式:比如Mac,比如树莓派,xshell连接远程服务器等。原谅我是windows笔记本,在MinGW和cygwin俩者间我选择了cygwin。附上cygwin下载地址,关于其繁琐的配置操作这里就不在赘述了,百度一搜一大把,记住把我们是准备干什么的,把插件下载全!!!
  2. NDK,现在网上博客普遍都是用的r17及更低的版本,原谅我这个新版本强迫症患者,我选择有多新用多新,当前最新版本r21。NDK下载地址
  3. ffmpeg 当然是必须的,同样的,选择目前最新版本4.2.2;ffmpeg下载地址

二. 关于操作路径

因为我用的windows下的cygwin,所以我选择偷懒,包括解压,下载等工作我都选择直接操作,命令行这个东西能不敲就不敲。
附上我的文件目录以供参考:
windows下安装目录
如果使用cygwin操作的话,当然不能这么直勾勾输入这个路径,还是需要一些其他操作。例子如下:
进入C盘 c:—— /cygdrive/c
进入D盘 d:—— /cygdrive/c

三. ffmpeg配置文件解析

原谅无比懒惰的我,直接windows下进入ffmpeg目录,直接用记事本或者notepad++都可以,查看里面的config文件。东西很多,只需要看show_help()这个函数里面的内容就行了,其他的东西可以选择性忽略。当然你也可以正了八经的使用命令行掉用帮助信息。
命令行下帮助信息
摘除一些无用信息哈,把有用的东西列出来,我们用vim创建build.sh脚本,加上注释内容如下。

#!/bin/bash
#NDK路径
NDK=/cygdrive/e/1Developer/cygwin/home/heima/android-ndk-r21-linux-x86_64

API=21
#编译平台 arm aarch64 i686 x86_64
ARCH=arm
# 指定目标cpu的架构 armv7a armv8a
PLATFORM=armv7a
#随便定义个路径,方便下面配
TARGET=$PLATFORM-linux-androideabi
# 设置工具链。三种版本的ndk均不同linux:linux-x86_64mac MAC:darwin-x86_64
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin
# 设置编译产物的输出目录,这里表示在当前目录下新建Android_out目录
PREFIX=./AndroidLib/$PLATFORM

CFLAG="-D__ANDROID_API__=$API -U_FILE_OFFSET_BITS -DBIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD -Os -fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated -mfloat-abi=softfp -marm"

build_lib()
{
#执行configure脚本,用于生成makefile
./configure \
--ln_s="cp -rf" \

--prefix=$PREFIX \
# 指定交叉编译工具
--cc=$TOOLCHAIN/$TARGET$API-clang \
--cxx=$TOOLCHAIN/$TARGET$API-clang++ \
--ld=$TOOLCHAIN/$TARGET$API-clang \
--target-os=android \
--arch=$ARCH \
--cpu=$PLATFORM \
--cross-prefix=$TOOLCHAIN/$ARCH-linux-androideabi- \
# 开启交叉编译
--enable-cross-compile \
--enable-shared \
--disable-static \
--enable-runtime-cpudetect \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-doc \
--disable-symver \
# 优化大小
--enable-small \
--enable-gpl \
--enable-nonfree \
--enable-version3 \
--disable-iconv \
--enable-neon \
--enable-hwaccels \
--enable-jni \
--enable-mediacodec \
# 关闭所有编码器(播放不需要编码)
--disable-avdevice  \
--disable-decoders \
--enable-decoder=vp9 \
--enable-decoder=h264 \
--enable-decoder=mpeg4 \
--enable-decoder=aac \
--enable-decoder=h264_mediacodec \
--disable-postproc \
# 会传给clang的参数
--extra-cflags="$CFLAG" \
--extra-ldflags="-marm"
}
#加载函数
build_lib
#make执行脚本
make clean
make install

这个东西呢,我估计你直接粘贴运行会报错,因为有几个坑。

  1. 因为拼接命令行里面的的注释也会被拼进去影响编译,这个坑我已经踩过了,直接把build_lib()里面所有的注释删掉再执行。

  2. 编码格式的问题,因为我是windows下直接用notepad++编译的,所以会出些莫名其妙的错误,比如换行符一类的。建议直接vim命令创建文本,粘贴进去就好。
    错误图示

  3. 不幸的是仍然会有错误,ffmpeg为了提高编译速度,引入了yasm,需要安装yasm的汇编编译器。当然也可以选择不安装,直接按照提示输入./configure --disable-x86asm,也不知道啥子个原因,我家里这台笔记本输入命令后一直卡在这里。等吧。。。。

在这里插入图片描述
最终成功关闭掉了,如下图所示。
在这里插入图片描述

  1. 继续运行安装写好的build.sh脚本,会经过漫长的等待。。。建议还是下载个yasm。。。相信我,我敲这句话时候已经等了半个小时了。

四. 关于优化

1.我实在忍受不了本地cygwin环境的乌龟速度了,恩,云服务器,真香~
2.关于make脚本的执行,看了看资料,其实可以开启多线程的。

make clean
make -j4
make install

五 RTMP编译

我们可以理解为FFmpeg只是一个编解码的库,如果需要视频源,就需要引入rtmp。作为一个实时传输协议(万物皆协议),他用来拉取我们的音视频流,然后才能用ffmpeg处理他。
在librtmp的根目录编写一个build_rtmp.sh,网上随便抄写一个。

#!/bin/bash

NDK_ROOT=/home/android-ndk/android-ndk-r21
CPU=arm-linux-androideabi
TOOLCHAIN=$NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64
export XCFLAGS="-isysroot $NDK_ROOT/sysroot -isystem $NDK_ROOT/sysroot/usr/include/arm-linux-androideabi -D__ANDROID_API__=$API"
export XLDFLAGS="--sysroot=${NDK_ROOT}/platforms/android-$API/arch-arm "
export CROSS_COMPILE=$TOOLCHAIN/bin/arm-linux-androideabi-

make install SYS=android prefix=`pwd`/result CRYPTO= SHARED=  XDEF=-DNO_SSL

执行脚本不出意外会报错:

sh build_rtmp.sh

在这里插入图片描述
看下报错信息,.o链接不出来,-gcc: Command not found其中gcc编译链找不到。如果是自己认真编译过ffmpeg,并且用的是ndk-r17以上版本的一定会熟悉这个错误,新版本的ndk不支持gcc编译链,默认为clang。
理下思路,我们需要找到rtmp编译文件里面设置编译路径的地方。查看rtmp文件夹下的makefile,其中有2行:

CC=$(CROSS_COMPILE)gcc
LD=$(CROSS_COMPILE)ld
AR=$(CROSS_COMPILE)ar

问题原因就在这里,make执行的时候默认去找gcc了。我们依照ffmeg的用到的方式,自己在脚本中添加编译链的路径。添加如下文件之后,发现还是报错,绝望了。

export CC=$TOOLCHAIN/$TARGET$API-clang
export LD=$TOOLCHAIN/$TARGET$API-clang
export AR=$TOOLCHAIN/$TARGET$API-clang

既然不行,也就不执著了,还有2种方式可以选择,

  1. 是换成ndkr17及以下
  2. 或者直接源码放到AS里面编译吧。

1. Android Studio编译

因为我本地有现成的编译so库的工程,并且本地windows环境也便于操作。
简单说,就是copy /home/rtmp/librtmp/librtmp(就是你下载的rtmp路径/librtmp)路径下所有的c/h,自己通过编译器编译。Android编译库文件

cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_VERBOSE_MAKEFILE on)
set(NAME rtmpdump)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc)
#预编译宏
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNO_CRYPTO"  )
file(GLOB rtmp_source src/*.c)
add_library(${NAME} SHARED ${rtmp_source})

set_target_properties(${NAME}
        PROPERTIES
        LIBRARY_OUTPUT_DIRECTORY
        "${CMAKE_CURRENT_SOURCE_DIR}/lib/${ANDROID_ABI}")

camke执行,最终就会生成需要的so
在这里插入图片描述

2. 低版本ndk(r17c)编译

先吐槽一句啊,xshell/xftp超级难用。
因为上面我们发现了新版本(17以上)的ndk移除了gcc,默认clang,我又解决不了,所以我也凑合一下用下老版本的ndk吧。
编译脚本如下

#!/bin/bash

NDK_ROOT=/home/ndk/android-ndk-r17c

CPU=arm-linux-androideabi

TOOLCHAIN=$NDK_ROOT/toolchains/$CPU-4.9/prebuilt/linux-x86_64

export XCFLAGS="-isysroot $NDK_ROOT/sysroot -isystem $NDK_ROOT/sysroot/usr/include/arm-linux-androideabi -D__ANDROID_API__=17"
export XLDFLAGS="--sysroot=${NDK_ROOT}/platforms/android-17/arch-arm "
export CROSS_COMPILE=$TOOLCHAIN/bin/arm-linux-androideabi-

make install SYS=android prefix=`pwd`/result CRYPTO= SHARED=  XDEF=-DNO_SSL

猜你喜欢

转载自blog.csdn.net/ma598214297/article/details/105776914