Nginx rtmp 转推push和relay(pull)

Nginx rtmp 转推push和relay(pull),第1张

Nginx rtmp 转推push和relay(pull)

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命令来切换。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5637041.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存