push,pull config:Nginx-rtmp模块实现流媒体play、push、pull功能_莫失莫忘的博客-CSDN博客
config:启用push功能,将本机(172.16.6.36)/mypush,app中的数据流推送至172.16.6.39服务器下的/myapp app中
application mypush { live on; push rtmp://172.16.6.39:1935/myapp; }
配置实现pull功能,172.16.6.39服务器能够从172.16.6.36服务器上拉取数据流,并保存在本机/mypull app中.
application mypush { live on; push rtmp://172.16.6.39:1935/myapp; }
整体结构图
两种情况转推:
ngx_rtmp_relay_send_publish-->ngx_rtmp_relay_play_local: 本地作为subscribe
ngx_rtmp_relay_send_play-->ngx_rtmp_relay_publish_local :pull同时转推
rtmp交互逻辑
relay模块和对端服务器交互主要rtmp协议三次握手,connect,createStream,play/publish命令消息服务器
- 转推:类似终端推流
分成两种情况:在publish之后转推和在pull之后转推
在publish之后转推: 1) 向转推server发送publish信令 2)将转推的server a作为subscribe,接收本机的推流转发.
实际r就是将push server,变成一个play subsribe. 在转发给其他subscribers的时候也转发给它一份.
send metadata,send av是推流器的事情,即liventpublish的send metadata,send av。
nginx握手属于复杂握手,不向librtmp都封装好了
ngx_rtmp_relay_on_result 真正的relay enter
publish 在完成以上步骤后客户端和服务器建立了一个网络流,接下来就可以传输媒体数据了。
大致流程如上图红色标注下面部分。
一般来讲媒体数据分为两部分,一部分是meta元信息,另一部分是音视频数据。
首先传送的是meta元信息。客户端推送媒体,服务器处理如下
在pull之后转推:
scenario2: 拉流:
pull scenario:pull的本质也是创建一个subsribe.请publisher server转发过来
relay分成两种情况,可以push也可以pull;pull分成静态 or非静态
pull rtmp的信令交互图: 客户端rtmp连接观看时函数调用 和ffmpeg推送视频一样,客户端连接服务器观看时流程也分为:建立rtmp连接–>建立网络连接–>建立网络流–>传输媒体数据。
前面建立rtmp连接和建立网络连接过程是相同的,区别在于建立网络流和传输媒体数据过程。
此部分为客户端连接nginx-rtmp时的交互,没有推送视频流。其中建立rtmp连接和建立网络连接过程和2.2.1、2.2.2节相同,参考对应章节内容。
而建立网络流过程与2.2.3区别于两点:
1、第一步中,从客户端接收一个protocol_message,推送时该message转到ngx_rtmp_set_chunk_size处理,而观看时该message未被处理;
2、第二步中,接收客户端一个amf控制消息,推送时是连续3个;
而媒体数据传输步骤中,在服务器没有接收推送时,过程如下:
1、从客户端(观看端)接收两个amf命令消息;
2、然后服务器会利用ngx_rtmp_cmd_publish_init来初始化发布环境。该函数会读取刚接收端amf信息,然后设置参数;
3、和2.2.4类似,初始化其他子模块:
A、ngx_rtmp_notify_module.c -> ngx_rtmp_notify_play
B、ngx_rtmp_exec_module.c -> ngx_rtmp_exec_play
C、ngx_rtmp_relay_module.c -> ngx_rtmp_relay_play
D、ngx_rtmp_live_module.c -> ngx_rtmp_live_play,会向客户端发送两个amf状态消息
E、ngx_rtmp_access_module.c -> ngx_rtmp_access_play
F、ngx_rtmp_cmd_module.c -> ngx_rtmp_cmd_play
4.客户端向服务器发送set_buflen的用户消息ngx_rtmp_user_message_handler将对其处理
5、因为没有推送数据,所以现在不会有媒体数据交互。
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
Scenario3 relay:ngx_rtmp_relay_module: pull模型分析1: 播放器端发起play
2: ngx_rtmp_relay_play()
3: ngx_rtmp_relay_pull() --主要建立pull请求, 将远程拉流的上下文和本地上下文放到链表中
ngx_rtmp_relay_create_local_ctx()创建本地上下文
ngx_rtmp_relay_create_remote_ctx()创建远端上下文
4: ngx_rtmp_relay_create_remote_ctx详解: 创建远端session, 开始rtmp信令交互
1: ngx_rtmp_relay_create_connection
2: ngx_rtmp_init_session
注意:此时session中的flashver为“ngx-local-relay“
5: rtmp信令交互流程
核心函数: ngx_rtmp_relay_on_result主要用来接收对端服务端发送的amf消息包,而后按正常rtmp协议请求进行下一步交互,这个主要是当前服务端做为客户端发起远程rtmp请求流程
例如: ngx_rtmp_client_handshake(发起握手)
握手完成后调用回调函数: ngx_rtmp_relay_handshake_done
ngx_rtmp_relay_send_connect:发起连接请求, 接着参考rtmp信令交互图
other: rtmp推流地址:rtmp://ip/live0/stream-name
对应的http-flv播放地址:http://ip/live0/stream-name 和 http://ip/flv0/stream-name
http-ts的配置方式和http-flv的配置原理完全相同。
对应的http-ts播放地址:http://ip/live0/stream-name
rtmp { server { listen 1935; application live0 { live on; } }} http { server { listen 80; location flv0 { flv_live 1935 app=live0; } ....}}relay 模块
整体结构: 采用hash表+链表的结构;横向:同一个流名的链表: 用play串起来;纵向:不同流名用next串起来
QA:pull和play什么关系?play是pull吗,应该有区别,中间的ngx_rtmp_relay_pull才是pull
pull 开始client handshake---connect---createstream---play
(动态pull,应该是类似aqy回源找到server)
play终端也得走上述过程。 源码分析:
if (ctx->publish != ctx && !s->static_relay) { ngx_rtmp_relay_send_publish(s) return ngx_rtmp_relay_play_local(s); } else { ngx_rtmp_relay_send_play(s) return ngx_rtmp_relay_publish_local(s); 注意有一个参数publisher,ngx_rtmp_live_join()函数会通过这个判断是推流还是拉流
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
statplay2(播放)
和上面的play命令不同的是,play2命令可以在不改变播放内容时间轴的情况下切换到不同的比特率,服务器端会维护多种比特率的文件来供客户端使用play2命令来切换。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)