[TOC]
参考:https://www.jianshu.com/p/55ffaf8ba0ab
RTMPDump 是一个用来处理RTMP
流媒体的开源工具包,它能够单独使用进行RTMP
的通信,也可以集成到FFmpeg中通过FFmpeg
接口来使用RTMPDump
。
在Android中可以直接借助NDK
在JNI
层调用RTMPDump
来完成RTMP
通信。
在根目录提供了一个
Makefile
与一些.c
源文件,这里的源文件将会编译出一系列的可执行文件。然后我们需要的并不是可执行文件,真正的对RTMP
的实现都在librtmp
子目录中。 在这个子目录中同样包含了一个Makefile
文件,通过阅读Makefile
发现,它的源码并不多:OBJS=rtmp.o log.o amf.o hashswf.o parseurl.o
。 因此我们不进行预编译,即直接放入AS中借助CMakeLists.txt
来进行编译。这么做可以让我们方便地对库本身进行调试或修改(实际上我们确实会稍微修改这个库的源码)。
下载地址:http://rtmpdump.mplayerhq.hu/download
这里我们下载的版本是 rtmpdump-2.3.tgz
在AS中新建项目,复制librtmp
到src/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}
)
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 )
编译测试输出版本信息,修改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: 131840
,131840
对应的16进制为:0x020300
, 也就是2.3版本。
参考:https://www.jianshu.com/p/a99b518f29b9
x264 是一个C
语言编写的目前对H.264
标准支持最完善的编解码库。它与RTMPDump
一样,可以在Android
中直接使用,也可以集成进入FFMpeg
。
需要先下载并配置Android NDK
环境,若已经下载过,可忽略此步骤。
下载地址:https://developer.android.google.cn/ndk/downloads/older_releases.html
可以在Windows
环境下下载,然后通过xshell
的xftp
上传到服务器的Linux
环境。
unzip android-ndk-r17c-linux-x86_64.zip
[root@iZwz9ci7skvj0jj2sfdmqgZ software]# cd android-ndk-r17c/
[root@iZwz9ci7skvj0jj2sfdmqgZ android-ndk-r17c]# pwd
/root/software/android-ndk-r17c
vim /etc/profile # 若没有写权限,请先添加权限
NDKROOT=/root/software/android-ndk-r17c
export PATH=$NDKROOT:$PATH # 添加到环境变量中
source /etc/profile
[root@iZwz9ci7skvj0jj2sfdmqgZ android-ndk-r17c]# echo $NDKROOT
/root/software/android-ndk-r17c
在Linux环境下下载
wget https://code.videolan.org/videolan/x264/-/archive/master/x264-master.tar.bz2
tar -xvf x264-master.tar.bz2
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
chmod +x build_x264.sh
./build_x264.sh
[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
同样可以借助xshell
的xftp
从服务器下载x264.zip
到Windows
环境。
目录结构如下图所示:
修改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 )
修改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"
}
}
}
编译运行成功代码集成成功。
扩展参考:
音视频基础知识
音视频基础知识-图像篇
视频频推流代码完成后,可以在浏览器输入服务器地址查看效果,如下图所示:
可以用ffplay
命令预览直播推流效果:
ffplay -i rtmp://47.115.6.127/myapp/
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
交叉编译步骤
① 下载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
同样可以借助xshell
的xftp
从服务器下载x264.zip
到Windows
环境。