Android摄像头采集到的数据格式是NV21(YUV的一种),称为原始数据,这种格式的数据量比较大,不利于传输,需要对数据进行压缩,这里需要通过H264编码达到压缩目的。x264是把原始数据转化为H264的工具,x264是工具,h264是协议。

FAAC和X264功能类似,X264是做视频编码的,FAAC是做音频编码的。

H264的流需要一个载体把流中一段段传输到服务器,这个载体就是RTMPDump。RTMPDump是个工具,实现了rtmp协议,通过RTMPDump把数据流中的每一帧转换成一个packet传输到服务器。

集成RTMPDump:

RTMPDump下载地址

  1. 下载完直接copy到项目中(在cpp 目录下创建librtmp 目录,全都丢进去)
  2. 根据其中Mmakefile可看出哪些文件有用,把删除没用的删掉。
    Mmakefile:

...

OBJS=rtmp.o log.o amf.o hashswf.o parseurl.o

...

librtmp.a: $(OBJS)
    $(AR) rs $@ $?

...

可以看出需要的是rtmp.o log.o amf.o hashswf.o parseurl.o对应的.c文件,把其他文件都删掉,然后会发现这些.c中有些会报错,因为我们多删除了已引入的.h文件,然后看需要哪些.h再重新copy进来。( 对于这个库最后发现其实没删多少,下面的贴图没做删除,这里只是删除无用代码的方式)。

  1. Cmakelist中引入:
    这里采用Cmakelist嵌套的方式导入,在librtmp目录下创建Cmakelist.txt:


cmake_minimum_required(VERSION 3.4.1)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") #CMAKE_C_FLAGS:用C的方式去编译,  -D传入参数
add_library(
        rtmp    #生成库的名称
        STATIC  #静态库
        amf.c   #下面是需要的.c文件,可以在Makefile中看到
        hashswf.c
        log.c
        parseurl.c
        rtmp.c
)

然后在工程的Cmakelist文件中添加这个Cmakelist:


...

add_subdirectory(librtmp)#这个路径是相对该CMakeLists.text的dir,不同版本AS中初始CMakeLists路径不同,这里有可能不同,比如会是add_subdirectory(src/main/cpp/librtmp)

add_library( ...)

find_library( ...)

target_link_libraries(
        ...
        rtmp)

目录结构贴一下,参考下add_subdirectory()的参数路径(打码的不用看),这里没有删除RTMPdump中没用的代码:

 
librtmp目录参考
  1. 当感觉一切OK的时候,编译一下—->“找不到openssl”
    openssl是用来加密的,现在不需要加密,看他的上下逻辑发现如果有定义NO_CRYPTO这个宏宏,就不会走#include <openssl/ssl.h>这一句,那直接在cmakelist中传入这个宏,编译时加个参数:

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNO_CRYPTO") #CMAKE_C_FLAGS:用C的方式去编译,  -D传入参数。

这个不报错的方式有很多,比如删掉,注释掉什么什么的,这里为了以后万一要用ssl,还是用传入参数的方式好。

  1. 编译成功,成功引入Rtmpdump。

集成x264:

这个库比较大,就不采用copy到as中编译了。
这里先在linux环境交叉编译出x264的库。然后再导入AS中使用。
x264下载地址

  1. 解压并进入目录,调用./configure就可以编译,但是需要传一些参数,输入./configure –help可以看到参数说明。
  2. 直接用./configure –参数 –参数 –参数, 肯定是扯了点,这里写一个脚本去执行:
    在x264目录下 vim build.sh,这里把编译armeabi-v7a和arm64-v8a的脚本贴一下(这个shell语法我用的不熟练,其实可以把这些写到一个脚本里)
    arm64-v8a:

#!/bin/bash

PREFIX=./android/arm64-v8a

TOOLCHAIN=$NDK_ROOT/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64

FLAGS="-isysroot $NDK_ROOT/sysroot -isystem $NDK_ROOT/sysroot/usr/include/aarch64-linux-android -D__ANDROID_API__=21 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -Wa,--noexecstack -Wformat -Werror=format-security  -O0 -fPIC" 

# --disable-cli : 关闭命令行
# 其他和ffmpeg一样
./configure \
--prefix=$PREFIX \
--disable-cli \
--enable-static \
--enable-pic \
--host=aarch64-linux \
--cross-prefix=$TOOLCHAIN/bin/aarch64-linux-android- \
--sysroot=$NDK_ROOT/platforms/android-21/arch-arm64 \
--extra-cflags="$FLAGS" 



make clean
make install

armeabi-v7a:

#!/bin/bash

PREFIX=./android/armeabi-v7a

TOOLCHAIN=$NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64

FLAGS="-isysroot $NDK_ROOT/sysroot -isystem $NDK_ROOT/sysroot/usr/include/arm-linux-androideabi -D__ANDROID_API__=17 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb -Wa,--noexecstack -Wformat -Werror=format-security  -O0 -fPIC"

# --disable-cli : 关闭命令行
# 其他和ffmpeg一样
./configure \
--prefix=$PREFIX \
--disable-cli \
--enable-static \
--enable-pic \
--host=arm-linux \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--sysroot=$NDK_ROOT/platforms/android-17/arch-arm \
--extra-cflags="$FLAGS" 



make clean
make install

其中一些路径相关的参数,一定要确定该路径是对的,可以去ndk目录下查看都否有该文件,比如armeabi-v7a用的android-17,而arm64-v8a中要用android-21,因为android-17中没有arch-arm64。

  • NDK_ROOT:环境变量中配置的NDK路径
  • prefix:输出目录
  • static:静态库
  • tra-cflags:这个可以在AS工程目录下⁨app⁩/⁨.externalNativeBuild⁩/cmake⁩/debug⁩/arm64-v8a⁩/build.ninja中找到,这个是AS编译时产生的,要确保AS中使用的ndk版本和Linux现在用的ndk版本一样,然后把copy出来的字符串其中的ndk路径换成Linux当前环境的ndk路径。(可能还会有一些其他的小改动,可以参考上看的尝试一下,或者百度一下)

但是编译x264我们需要注意一点,x264在进行环境检测的时候,使用的是比较宽松的方式,对于我们目前需要编译的android-17为目标来说,编译出的库在使用上会出现问题(对于18以上不会)。
我们需要修改configure脚本,在脚本中搜索cc_check
vim如何搜索:在vim里底线命令模式,输入 /cc_check

cc_check() {
    ......
    if [ $compiler_style = MS ]; then
        cc_cmd="$CC conftest.c -Werror=implicit-function-declaration  $(cc_cflags $CFLAGS $CHECK_CFLAGS $2) -link $(cl_ldflags $2 $LDFLAGSCLI $LDFLAGS)"
    else
        cc_cmd="$CC conftest.c -Werror=implicit-function-declaration  $CFLAGS $CHECK_CFLAGS $2 $LDFLAGSCLI $LDFLAGS -o conftest"
    fi
    ......
}  

cc_cmd内添加 -Werror=implicit-function-declaration

  1. 执行 sh build.sh 因为脚本中写了输出目录,所以如果编译成功,当前目录下应该是多出了个android目录,其中有个arm64-v8a(假设编译的是arm64-v8a)。
  2. 压缩arm64-v8a:zip -r arm64-v8 arm64-v8/
  3. 下载该文件到本地 scp ……….. 并解压
  4. 解压后的x264把include文件夹直接放到main/cpp目录下,把libx264.a放到main/cpp/libs/arm64-v8中(目录随便放,这样看起来比较直观,没有目录就创建),贴下目录结构:
     
    x264目录

    打马的是上面导入的librtmp

  5. CmakeList中添加:

...
add_library( ...)

include_directories(include) #这个路径是相对CMakeLists.text的dir,不同版本AS中初始CMakeLists路径不同,这里有可能不同,比如会是include_directories(src/main/cpp/include)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}" ) #CMAKE_CXX_FLAGS会被添加到build.ninja的FLAGS中,ANDROID_ABI是内置变量,不要直接写死armeabi-v7a或arm64-v8

find_library(...)


target_link_libraries( 
        ...
        x264)

目录问题导入librtmp时提到过,是相对此CMakeLists.text的dir

集成FAAC:

FAAC下载地址
这个集成跟X264基本一样,先服务器上编译成静态库,然后copy到项目里。过程不再详细写。把v8a的变异脚本贴一下。

#!/bin/bash                                                                                                                 
                                                                                                                            
PREFIX=`pwd`/android/arm64-v8a                                                                                              
                                                                                                                            
TOOLCHAIN=$NDK_ROOT/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64                                              
                                                                                                                            
CROSS_COMPILE=$TOOLCHAIN/bin/aarch64-linux-android                                                                          
                                                                                                                            
FLAGS="-isysroot $NDK_ROOT/sysroot -isystem $NDK_ROOT/sysroot/usr/include/aarch64-linux-android -D__ANDROID_API__=21 -g -DAN
DROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -Wa,--noexecstack -Wformat -Werror
=format-security  -O0 -fPIC"                                                                                                
                                                                                                                            
export CC="$CROSS_COMPILE-gcc --sysroot=$NDK_ROOT/platforms/android-21/arch-arm64"                                          
export CFLAGS="$FLAGS"                                                                                                      
                                                                                                                            
                                                                                                                            
./configure \                                                                                                               
--prefix=$PREFIX \                                                                                                          
--host=aarch64-linux \                                                                                                      
--with-pic \                                                                                                                
--enable-shared=no                                                                                                          
                                                                                                                            
                                                                                                                            
                                                                                                                            
make clean                                                                                                                  
make install                                                                                                                

如果需要v7a,对应改一下就哦了。
编译好之后把.h文件和.a文件copy到AS工程目录下。OJBK!!!!

 
转自:https://www.jianshu.com/p/8a4ee686c38a