目前Android端APP视频直播一般使用RTMP协议推流到流媒体服务器,通过CDN加速后,然后在播放端通过HTTP-FLV协议或HLS协议拉流播放。
#RTMP协议介绍
RTMP协议(Real Time Message Protocol,实时信息传输协议),是由Adobe公司提出的一种应用层的协议,可用于实时传递音视频媒体数据。它基于传输层的TCP协议,通过与服务端建立长连接来传递数据。相较于其它同类协议,延迟较低,一般在1~3s,非常适合用于直播场景下的推流。
#RtmpDump介绍
RtmpDump是一个开源工具库,使用c代码编写,实现了用RTMP上传音视频流的相关功能。RTMP协议基于传输层的TCP协议,而在RtmpDump中是使用Socket来建立长连接的。官网地址: RTMPDump
1.RtmpDump使用c代码编写,所以要在Android中使用的话,需要用到NDK开发。
一般需要编写自己的native层业务逻辑代码,引入Rtmpdump库中需要的部分源文件,在自己的native层代码中调用Rtmpdump中的功能。最后打包成.so动态库,供java层调用。NDK开发可参考笔记: Android NDK和JNI简略总结、使用示例_丞恤猿的博客-CSDN博客
2.Rtmpdump全部功能开启时(默认),支持数据加解密,这时候需要依赖openssl和zlib库,打包时要一并打进入。
其中,openssl是用于加密的库,官网地址: https://www. openssl.org/libz是压缩库,版本比较新的NDK中已经包含这个库,官网地址: http://www. zlib.net/。可通过两种方式关闭这部分功能,这时打包就不再需要这两个依赖库:方式1,在cmake脚本中添加:set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNO_CRYPTO")方式2,在rtmp.h(或其它合适位置),添加:#define NO_CRYPTO
#.在native层使用RtmpDump的主要步骤列举
//1.创建 RTMP 对象, 申请内存m_pRtmp = RTMP_Alloc();//2.初始化 RTMPRTMP_Init(m_pRtmp);// 3. 设置 RTMP 推流服务器地址int ret = RTMP_SetupURL(m_pRtmp, (char*)url);// 4. 启用 RTMP 写出功能RTMP_EnableWrite(m_pRtmp);// 5. 连接 RTMP 流媒体服务器ret = RTMP_Connect(m_pRtmp, 0);// 6. 连接 RTMP 流ret = RTMP_ConnectStream(m_pRtmp,0);// 7.将 RTMP 数据包发送到服务器中。在使用过程中需要反复调用这个方法来传输媒体数据包。int nRet = RTMP_SendPacket(m_pRtmp,&packet,0);// 8.关闭与 RTMP 服务器连接、释放资源RTMP_Close(m_pRtmp);RTMP_Free(m_pRtmp);
#.java层的使用要点
##.需要根据自己的业务需求来编写native层代码封装接口供java层调用,一般会有这么几个基本功能接口:
1.根据推流地址建立连接2.发送音/视频流头部数据帧3.发送音/视频流正常数据帧4.关闭连接并释放资源
##.RTMP连接发送音视频数据,首先需要发送音/视频流的头信息,否则服务端和拉流端无法解析音视频流数据。
音/视频流的头信息中包含了解码需要的描述信息,例如视频流的分辨率、码率、帧率、帧顺序、压缩信息等,音频流的采样率、精度、声道、压缩信息等等。一般是通过MediaCodec编码输出H264视频帧、AAC音频帧,再用RtmpDump推流到流媒体服务端。可通过MediaCodec输出缓冲区的info来判断是否为头部信息帧。整个推流处理过程,其实就是建立连接,不断发送MediaCodec输出的数据帧,然后需要结束的时候,关闭连接并释放资源。