Coder Social home page Coder Social logo

nelivepushclient's Introduction

NeLivePushClient 直播推流-客户端准备工作

[TOC]

一、librtmp编译集成

参考:https://www.jianshu.com/p/55ffaf8ba0ab

1.1 简介

RTMPDump 是一个用来处理RTMP流媒体的开源工具包,它能够单独使用进行RTMP的通信,也可以集成到FFmpeg中通过FFmpeg接口来使用RTMPDump

在Android中可以直接借助NDKJNI层调用RTMPDump来完成RTMP通信。

在根目录提供了一个Makefile与一些.c源文件,这里的源文件将会编译出一系列的可执行文件。然后我们需要的并不是可执行文件,真正的对RTMP的实现都在librtmp子目录中。 在这个子目录中同样包含了一个Makefile文件,通过阅读Makefile发现,它的源码并不多:OBJS=rtmp.o log.o amf.o hashswf.o parseurl.o。 因此我们不进行预编译,即直接放入AS中借助CMakeLists.txt来进行编译。这么做可以让我们方便地对库本身进行调试或修改(实际上我们确实会稍微修改这个库的源码)。

1.2 编译集成步骤

1.2.1 下载源码

下载地址:http://rtmpdump.mplayerhq.hu/download

这里我们下载的版本是 rtmpdump-2.3.tgz

1.2.2 复制librtmp并编写CMakeLists.txt

在AS中新建项目,复制librtmpsrc/main/cpp/librtmp,并在该目录下为其编写CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)
#所有源文件放入`rtmp_srcs`变量
file(GLOB rtmp_srcs *.c)
#编译静态库
add_library( # Sets the name of the library.
             rtmp
             # Sets the library as a shared library.
             STATIC
             # Provides a relative path to your source file(s).
             ${rtmp_srcs}
        )

1.2.3 在app/CMakeLists.txt中导入这个CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)
#引用指定目录下的CMakeLists.txt
add_subdirectory(librtmp) 
#指定头文件查找路径
include_directories(librtmp) 

add_library( # Sets the name of the library.
             native-lib
             # Sets the library as a shared library.
             SHARED
             # Provides a relative path to your source file(s).
             native-lib.cpp )

target_link_libraries( # Specifies the target library.
                       native-lib
                       rtmp
                       log )

1.2.4 编译测试

编译测试输出版本信息,修改native-lib.cpp文件:

#include <jni.h>
#include <string>
#include <rtmp.h>

extern "C" JNIEXPORT jstring JNICALL
Java_com_sty_ne_livepushclient_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    char version[100];
    sprintf(version, "rtmp version : %d", RTMP_LibVersion());
    return env->NewStringUTF(version);
}

编译报错如下:

E:\xxx\xxx\NeLivePushClient\app\src\main\cpp\librtmp\hashswf.c:56:10: fatal error: 'openssl/ssl.h' file not found

问题排查:

打开rtmp.c,我们发现这里有一段宏定义:

#ifdef CRYPTO
#ifdef USE_POLARSSL
#include <polarssl/havege.h>
#elif defined(USE_GNUTLS)
#include <gnutls/gnutls.h>
#else	/* USE_OPENSSL */
#include <openssl/ssl.h>
#include <openssl/rc4.h>
#endif
TLS_CTX RTMP_TLS_ctx;
#endif

最终只有CRYPTO这个宏被定义了才会#include <openssl/ssl.h>,那么我们继续查找CRYPTO定义的地方,在rtmp.h中又有这样一段:

#if !defined(NO_CRYPTO) && !defined(CRYPTO)
#define CRYPTO
#endif

我们只需要编译时添加定义NO_CRYPTO这个预编译宏就可以了。修改librtmp中的CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)
#预编译宏: -D 定义宏
#纯C的第三方库就用CMAKE_C_FLAGS,否则只要有一个cpp文件就需要用CMAKE_CXX_FLAGS
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNO_CRYPTO")
#所有源文件放入`rtmp_srcs`变量
file(GLOB rtmp_srcs *.c)
#编译静态库
add_library( # Sets the name of the library.
             rtmp
             # Sets the library as a shared library.
             STATIC
             # Provides a relative path to your source file(s).
             ${rtmp_srcs}
        )

重新编译运行,输出rtmp version: 131840131840对应的16进制为:0x020300, 也就是2.3版本。

二、x264交叉编译

参考:https://www.jianshu.com/p/a99b518f29b9

2.1 简介

x264 是一个C语言编写的目前对H.264标准支持最完善的编解码库。它与RTMPDump一样,可以在Android中直接使用,也可以集成进入FFMpeg

2.2 准备工作

需要先下载并配置Android NDK环境,若已经下载过,可忽略此步骤。

2.2.1 下载NDK r17版本

下载地址:https://developer.android.google.cn/ndk/downloads/older_releases.html

可以在Windows环境下下载,然后通过xshellxftp 上传到服务器的Linux环境。

2.2.2 解压

unzip android-ndk-r17c-linux-x86_64.zip

2.2.3 进入NDK解压目录,查看当前路径

[root@iZwz9ci7skvj0jj2sfdmqgZ software]# cd android-ndk-r17c/
[root@iZwz9ci7skvj0jj2sfdmqgZ android-ndk-r17c]# pwd
/root/software/android-ndk-r17c

2.2.4 修改配置文件

vim /etc/profile # 若没有写权限,请先添加权限

2.2.5 添加NDK路径到配置文件中

NDKROOT=/root/software/android-ndk-r17c
export PATH=$NDKROOT:$PATH  # 添加到环境变量中

2.2.6 使配置生效

source /etc/profile

2.2.7 验证是否配置成功

[root@iZwz9ci7skvj0jj2sfdmqgZ android-ndk-r17c]# echo $NDKROOT
/root/software/android-ndk-r17c

2.3 交叉编译步骤

2.3.1 下载

在Linux环境下下载

wget https://code.videolan.org/videolan/x264/-/archive/master/x264-master.tar.bz2

2.3.2 解压

tar -xvf x264-master.tar.bz2

2.3.3 进入x264目录并编写编译脚本

cd x264-master/
vim build_x264.sh

可以通过查看configure文件命令来查看我们可以配置的参数: ./configure --help

我们要编写的build_x264.sh脚本内容如下:

#!/bin/bash

NDK_ROOT=/root/software/android-ndk-r17c

PREFIX=./output/livepush/armeabi-v7a

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

CFLAGS="-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="$CFLAGS"

make clean
make install

2.3.4 编译

chmod +x build_x264.sh
./build_x264.sh

2.3.5 将编译产物打包并传给Windows

[root@iZwz9ci7skvj0jj2sfdmqgZ x264-master]# cd ./output/livepush/
[root@iZwz9ci7skvj0jj2sfdmqgZ livepush]# ls
armeabi-v7a
[root@iZwz9ci7skvj0jj2sfdmqgZ livepush]# zip -r x264.zip *
[root@iZwz9ci7skvj0jj2sfdmqgZ livepush]# ls
armeabi-v7a  x264.zip

同样可以借助xshellxftp 从服务器下载x264.zipWindows环境。

2.4 AS中集成x264

2.4.1 拷贝2.3.5下载的文件到AS

目录结构如下图所示:

image

修改app/src/main/cpp根目录下的CMakeLists.txt文件:

cmake_minimum_required(VERSION 3.4.1)
#引用指定目录下的CMakeLists.txt
add_subdirectory(librtmp)
#指定头文件查找路径
include_directories(librtmp)
include_directories(x264/include)

#这里只能用CMAKE_CXX_FLAGS
#指定库的查找路径
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/x264/libs/${CMAKE_ANDROID_ARCH_ABI}")
add_library( # Sets the name of the library.
             native-lib
             # Sets the library as a shared library.
             SHARED
             # Provides a relative path to your source file(s).
             native-lib.cpp )

target_link_libraries( # Specifies the target library.
                       native-lib
                       rtmp
                       x264
                       log )

2.4.2 测试

修改app/src/main/cpp目录下的native-lib.cpp文件:

#include <jni.h>
#include <string>
#include <rtmp.h>
#include <x264.h>

extern "C" JNIEXPORT jstring JNICALL
Java_com_sty_ne_livepushclient_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    char version[100];
    sprintf(version, "rtmp version : %d", RTMP_LibVersion());
    //测试x264
    x264_picture_t *pic = new x264_picture_t;
    x264_picture_init(pic);
    return env->NewStringUTF(version);
}

注意要在app/build.gradle文件中添加abiFilters

android {
    compileSdkVersion 28
    buildToolsVersion "29.0.2"

    defaultConfig {
        applicationId "com.sty.ne.livepushclient"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

        externalNativeBuild {
            cmake {
                cppFlags ""
                abiFilters "armeabi-v7a"
            }
        }
        ndk {
            abiFilters "armeabi-v7a"
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
            version "3.10.2"
        }
    }
}

编译运行成功代码集成成功。

三、视频推流

3.1 参考资料

扩展参考:
音视频基础知识 音视频基础知识-图像篇

3.2 代码效果预览

视频频推流代码完成后,可以在浏览器输入服务器地址查看效果,如下图所示:
image
可以用ffplay命令预览直播推流效果:

ffplay -i rtmp://47.115.6.127/myapp/

四、音频推流

4.1 FAAC交叉编译、集成

4.1.1 简介

FAAC(Freeware Advanced Audio Coder)官网:https://www.audiocoding.com/

下载地址为:https://www.audiocoding.com/downloads.html (FAAD2是解码库)

FLV文件分析器在resource目录下:flvAnalyser v0.0.1.002.7z,可以把Calorie.flv拖进去查看。

4.1.2 FAAC交叉编译步骤

参考:RTMP 音频推流(一)FAAC 交叉编译

① 下载FAAC编码库源码:

wget https://ayera.dl.sourceforge.net/project/faac/faac-src/faac-1.29/faac-1.29.9.2.tar.gz

② 解压:

tar -xvf faac-1.29.9.2.tar.gz 

③ 进入解压目录,编写编译脚本build_faac.sh

[root@iZwz9ci7skvj0jj2sfdmqgZ software]# cd faac-1.29.9.2/
[root@iZwz9ci7skvj0jj2sfdmqgZ faac-1.29.9.2]# vim build_faac.sh
#!/bin/bash

NDK_ROOT=/root/software/android-ndk-r17c
PREFIX=`pwd`/android/armeabi-v7a

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

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 -std=c++11  -O0  -fPIC"

export CC="$CROSS_COMPILE-gcc --sysroot=$NDK_ROOT/platforms/android-17/arch-arm"
export CFLAGS="$FLAGS"

./configure \
	--prefix=$PREFIX \
	--host=arm-linux \
	--with-pic \
	--enable-shared=no  

make clean
make install

④ 执行脚本,开始编译:

chmod 777 build_faac.sh
./build_faac.sh

编译产物输出在./android/armeabi-v7a目录下。

⑤ 将编译产物打包并传给Windows

[root@iZwz9ci7skvj0jj2sfdmqgZ faac-1.29.9.2]# cd ./android
[root@iZwz9ci7skvj0jj2sfdmqgZ android]# ls
armeabi-v7a
[root@iZwz9ci7skvj0jj2sfdmqgZ android]# zip -r faac.zip *
[root@iZwz9ci7skvj0jj2sfdmqgZ android]# ls
armeabi-v7a  faac.zip

同样可以借助xshellxftp 从服务器下载x264.zipWindows环境。

4.2 音频数据编码

4.3 音频推流

nelivepushclient's People

Contributors

tianyalu avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.