Clone
26
v1_CN_SrsLibrtmp
winlin edited this page 2022-01-06 11:57:15 +08:00
This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

HOME > CN > Librtmp

SRS提供的librtmp

librtmp是一个客户端库好像是rtmpdump提供的一个客户端RTMP库。

应用场景

librtmp的主要应用场景包括

  • 播放RTMP流譬如rtmpdump将服务器的流读取后保存为flv文件。
  • 推流提供推流到RTMP服务器。
  • 基于同步阻塞socket客户端用可以了。
  • arm编译出来给arm-linux用譬如某些设备上采集后推送到RTMP服务器。

备注关于链接ssl握手协议简单握手和复杂握手参考RTMP握手协议

备注ARM上使用srs-librtmp需要交叉编译参考srs-arm即使用交叉编译环境编译srs-librtmp可以不依赖于其他库ssl/st都不需要

librtmp做Server

群里有很多人问librtmp如何做server实在不胜其骚扰所以单列一章。

server的特点是会有多个客户端连接至少有两个一个推流连接一个播放连接。所以server有两种策略

  • 每个连接一个线程或进程像apache。这样可以用同步socket来收发数据同步简单。坏处就是没法支持很高并发1000个已经到顶了得开1000个线程/进程啊。
  • 使用单进程但是用异步socket像nginx这样。好处就是能支持很高并发。坏处就是异步socket麻烦。

rtmpdump提供的librtmp当然是基于同步socket的。所以使用librtmp做server只能采取第一种方法即用多线程处理多个连接。多线程多麻烦啊要锁同步而且还支持不了多少个。

librtmp的定位就是客户端程序偏偏要超越它的定位去使用这种大约只有中国人才能这样“无所畏惧”。

嵌入式设备上做rtmp server当然可以用srs/crtmpd/nginx-rtmp轮也轮不到librtmp。

SRS为何提供librtmp

srs提供的客户端srs-librtmp的定位和librtmp不一样主要是

  • librtmp的代码确实很烂毋庸置疑典型的代码堆积。
  • librtmp接口定义不良好这个对比srs就可以看出使用起来得看实现代码。
  • 没有实例接口的使用最好提供实例srs提供了publish/play/rtmpdump实例。
  • 最小依赖关系srs调整了模块化只取出了core/kernel/rtmp三个模块其他代码没有编译到srs-librtmp中避免了冗余。
  • 最少依赖库srs-librtmp只依赖c/c++标准库若需要复杂握手需要依赖opensslsrs也编译出来了只需要加入链接即可
  • 不依赖stsrs-librtmp使用同步阻塞socket没有使用stst主要是服务器处理并发需要
  • SRS提供了测速函数直接调用srs-librtmp就可以完成到服务器的测速。参考Bandwidth Test
  • SRS提供了日志接口可以获取服务器端的信息譬如版本对应的session id。参考Tracable log

一句话srs为何提供客户端开发库因为rtmp客户端开发不方便不直观不简洁。

编译srs-librtmp

编译SRS时会自动编译srs-librtmp譬如

./configure --with-librtmp --without-ssl

编译会生成srs-librtmp和对应的实例

备注支持librtmp只需要打开--with-librtmp但推荐打开--without-ssl不依赖于ssl对于一般客户端不需要模拟flash足够了。这样srs-librtmp不依赖于任何其他库在x86/x64/arm等平台都可以编译和运行

备注:就算打开了--with-sslsrslibrtmp也只提供simple_handshake函数不提供complex_handshake函数。所以推荐关闭ssl不依赖于ssl没有实际的用处。

SRS编译成功后用户就可以使用这些库开发

Windows下编译srs-librtmp

srs-librtmp可以只依赖于c++和socket可以在windows下编译。不过srs没有提供直接编译的方法可行的方法是

  • 先在linux下编译通过./configure --disable-all --with-librtmp && make
  • 头文件就是src/libs/srs_librtmp.hpp将以下文件拷贝到windows下编译
objs/srs_auto_headers.hpp
src/core/*
src/kernel/*
src/rtmp/*
src/libs/*

注意srs-librtmp客户端推流和抓流不需要ssl库。代码都是c++/stl网络部分用的是同步socket。 备注SRS2.0提供将srs-librtmp导出为一个project或者文件参考导出srs-librtmp。SRS1.0不支持导出可以自己合并2.0的修改到1.0。

数据格式

srs-librtmp提供了一系列接口函数就数据按照一定格式发送到服务器或者从服务器读取音视频数据。

数据接口包括:

  • 读取数据包int srs_read_packet(int* type, u_int32_t* timestamp, char** data, int* size)
  • 发送数据包int srs_write_packet(int type, u_int32_t timestamp, char* data, int size)

接口接受的的数据(char* data)音视频数据格式为flv的Video/Audio数据。参考srs的doc目录的规范文件video_file_format_spec_v10_1.pdf

  • 音频数据格式参考:E.4.2.1 AUDIODATAp76譬如aac编码的音频数据。
  • 视频数据格式参考:E.4.3.1 VIDEODATAp78譬如h.264编码的视频数据。
  • 脚本数据格式参考:E.4.4.1 SCRIPTDATAp80譬如onMetadata流的信息宽高码率分辨率等

数据类型(int type)定义如下(E.4.1 FLV Tagpage 75

  • 音频8 = audio宏定义SRS_RTMP_TYPE_AUDIO
  • 视频9 = video宏定义SRS_RTMP_TYPE_VIDEO
  • 脚本数据18 = script data宏定义SRS_RTMP_TYPE_SCRIPT

其他的数据,譬如时间戳,都是通过参数接受和发送。

另外,文档其他重要信息:

  • flv文件头格式E.2 The FLV headerp74。
  • flv文件主体格式E.3 The FLV File Bodyp74。
  • tag头格式E.4.1 FLV Tagp75。

使用flv格式的原因

  • flv的格式足够简单。
  • ffmpeg也是用的这种格式
  • 收到流后加上flv tag header就可以直接保存为flv文件
  • 从flv文件解封装数据后只要将tag的内容给接口就可以flv的tag头很简单。

备注SRS2.0支持直接发送h264裸码流参考publish h.264 raw data

srs-librtmp Examples

SRS提供了实例sample也会在编译srs-librtmp时自动编译

  • research/librtmp/srs_play.c播放RTMP流实例。
  • research/librtmp/srs_publish.c推送RTMP流实例。
  • research/librtmp/srs_ingest_flv.c读取本地文件并推送RTMP流实例。
  • research/librtmp/srs_ingest_rtmp.c读取RTMP流并推送RTMP流实例。
  • research/librtmp/srs_bandwidth_check.c带宽测试工具。
  • research/librtmp/srs_flv_injecter.c点播FLV关键帧注入文件。
  • research/librtmp/srs_flv_parser.cFLV文件查看工具。
  • research/librtmp/srs_detect_rtmp.cRTMP流检测工具。

运行实例

启动SRS

make && ./objs/srs -c srs.conf 

推流实例:

make && ./objs/research/librtmp/objs/srs_publish rtmp://127.0.0.1:1935/live/livestream

备注推流实例发送的视频数据不是真正的视频数据实际使用时譬如从摄像头取出h.264裸码流,需要封装成接口要求的数据,然后调用接口发送出去。

播放实例:

make && ./objs/research/librtmp/objs/srs_play rtmp://ossrs.net/live/livestreamsuck rtmp stream like rtmpdump

Winlin 2014.11