直播--android端推流实现一

首先需要了解推流端需要采集两部分数据,视频和音频,视频是通过摄像头采集的。音频是通过麦克风采集的。对于android设备摄像头采集的数据是没有经过压缩的NV21数据(属于YUV420数据格式,需要了解两者区别的,查看链接:YUV与NV21),由于这样的数据没有经过压缩,数据量很大,想要传给服务器就需要对其进行压缩(编码),采用H264编码。要使用x264工具将NV21数据编码成H264(H264是一种协议)数据

H264编码是得到连续的流,流中有很多帧(I帧称为关键帧,P帧,B帧)。要想传递给服务器的数据是不丢帧的,需要对流进行重新打乱,比如第一段先传I帧数据包,再传B帧数据包等。这个传递给服务器的工具就是rtmpDump,它是真正实现摆放数据的,会将h264数据转成packet,推到服务器。它是遵循rtmp协议的。这种协议就保证了流在传递的过程中不丢帧。

一、android studio集成rtmpDump

1、下载linux环境下的rtmpDump 地址rtmpDump-linux

2、在linux环境解压,将解压得到的librtmp文件夹拷贝到项目中的cpp目录下。

3、在当前librtmp文件夹下创建CMakeLists.txt,编写CMake,生成rtmp静态库,代码如下:
 

cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
#所有的.c文件编译成静态库rtmp
add_library(
        rtmp
        STATIC
        amf.c
        hashswf.c
        log.c
        parseurl.c
        rtmp.c
        )

试着编译,发现编译失败,定位到代码

是因为openssl找不到导致的,openssl一般是使用在视频加密的地方,这里不需要,但是如果手动删除。发现需要很多地方都要做修改,那么我们就需要使编译的时候不编译它。发现系统是通过CRYPTO这个宏来控制是否编译这段代码,而CRYPTO又是通过NO_CRYPTO这个宏来控制的。那么我们就需要定义NO_CRYPTO这个宏,这样CRYPTO这个宏就不会定义,继而就不会编译openssl这段代码。如下:


cmake_minimum_required(VERSION 3.4.1)
#设置编译器为c编译器 -DNO_CRYPTO为定义宏变量NO_CRYPTO
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNO_CRYPTO")
#所有的.c文件编译成静态库rtmp
add_library(
        rtmp
        STATIC
        amf.c
        hashswf.c
        log.c
        parseurl.c
        rtmp.c
        )

4、将我们编译的静态库连接到动态库native-lib中,编写项目的CMakeList.txt,代码如下:


cmake_minimum_required(VERSION 3.4.1)
#将外部编译的文件引入进来
add_subdirectory(librtmp)
#添加动态库
add_library(
        native-lib
        SHARED
        native-lib.cpp)
find_library(
        log-lib
        log)

target_link_libraries(
        native-lib
        #静态库rtmp编译到native-lib中
        rtmp
        ${log-lib})

这样就完成了rtmp的集成。

二、android studio集成x264

x264是一个C语言编写的目前对H.264标准支持最完善的编解码库。与RTMPDump一样同样直接在Android中使用,也可以集成进入FFMpeg。在Android中使用x264,首先需要预编译出x264的静/动态库。

1、linux环境进入x264目录,编写生成静态库编译脚本build.sh。代码如下

#!/bin/bash
PREFIX=./android/armeabi-v7a
NDKROOT=/root/android-ndk-r17c
TOOLCHAIN=$NDKROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64

FLAGS="-isysroot $NDKROOT/sysroot -isystem $NDKROOT/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 不需要命令行工具
#--enable-static 静态库
#和ffmpeg差不多
./configure \
--prefix=$PREFIX \
--disable-cli \
--disable-asm \
--enable-static \
--enable-pic \
--host=arm-linux \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--sysroot=$NDKROOT/platforms/android-17/arch-arm \
--extra-cflags="$FLAGS"

make clean
make install

执行sh build.sh命令,会在当前目录下生成android/armeabi-v7a。

2、将头文件拷贝到cpp目录下的include文件夹下,将静态库拷贝到cpp/libs/armeabi-v7a目录下

3、将我们编译的静态库连接到动态库native-lib中,编写项目的CMakeList.txt,代码如下:


cmake_minimum_required(VERSION 3.4.1)
#将外部编译的文件引入进来
add_subdirectory(librtmp)
#添加动态库
add_library(
        native-lib
        SHARED
        native-lib.cpp)
#-L代表路径
#CMAKE_SOURCE_DIR当前工程目录
#CMAKE_ANDROID_API内置变量指向armeabi-v7a
set(my_lib_path  ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI})
set(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} -L${my_lib_path}")
#导入头文件
include_directories(include)
find_library(
        log-lib
        log)

target_link_libraries(
        native-lib
        #静态库rtmp编译到native-lib中
        rtmp
        x264
        ${log-lib})

这样就完成了x264的集成。

附件:完整的x264与rtmp配置文档

猜你喜欢

转载自blog.csdn.net/qinbin2015/article/details/90670160