flv

FLV header + FLV file body

FLV file body = PreTagsize0 + (Tag1 + Tagsize1) + …..

FLVTAG + VIDEODATA + AVCVIDEOPACKET

FLVTAG = TagType + DataSize + Timestamp + TE + 0

VIDEODATA = FrameType + CodecID

AVCVIDEOPACKET = AVCPacktType + CompositionTime

nginx rtmp

本文章介绍nginx rtmp module

常量

ngx_log_pid : worker 的process id

amf 流程

2018/05/28 15:58:07 [debug] 44677#0: *6 AMF func 'connect' passed to handler 0/1
2018/05/28 15:58:07 [debug] 44677#0: *6 AMF func 'createstream' passed to handler 0/1
2018/05/28 15:58:07 [debug] 44677#0: *6 AMF func 'publish' passed to handler 0/1
2018/05/28 15:58:07 [debug] 44677#0: *6 AMF func '@setdataframe' passed to handler 0/1
2018/05/28 15:58:17 [debug] 44677#0: *6 AMF func 'deletestream' passed to handler 0/1

nginx 启动

ngx_rtmp.c 定义 ngx_rtmp_module, ngx_module_t 结构体

ngx_rtmp_commands 处理nginx.conf里的配置项,调用ngx_rtmp_block。

rtmp {
}

进行

ngx_rtmp_block
  ngx_rtmp_optimize_servers
    ngx_rtmp_init_listening
      ngx_rtmp_add_listening
        ngx_create_listening
        ls->handler = ngx_rtmp_init_connection
  ngx_rtmp_init_event_handlers --> ngx_rtmp_amf_message_handler

core module server 配置调用 ngx_rtmp_core_server listen 配置调用 ngx_rtmp_core_listen application 配置调用 ngx_rtmp_core_application

live module live on —> live flag

typedef struct {
    ngx_array_t             servers;    /* ngx_rtmp_core_srv_conf_t */
    ngx_array_t             listen;     /* ngx_rtmp_listen_t */

    ngx_array_t             events[NGX_RTMP_MAX_EVENT];

    ngx_hash_t              amf_hash;
    ngx_array_t             amf_arrays;
    ngx_array_t             amf;
} ngx_rtmp_core_main_conf_t;

ngx_rtmp_notify_postconfiguration


    ch = ngx_array_push_n(&cmcf->amf, ncalls);
    if (ch == NULL) {
        return NGX_ERROR;
    }

    bh = ngx_rtmp_cmd_map;

    for(n = 0; n < ncalls; ++n, ++ch, ++bh) {
        *ch = *bh;  ///// 将map放入amf array
    }

receive

ngx_rtmp_cycle
  ngx_rtmp_recv --分析bheader, mheader(basice header, message header) 
    ngx_rtmp_receive_message
      ((*evh)(s, h, in)) --- 
ngx_rtmp_amf_message_handler
  ngx_rtmp_amf_read
    ngx_rtmp_amf_get
      switch ((*ph)(s, h, in))  ------ ngx_rtmp_cmd_map

logs

最简单的live on配置

2018/05/19 12:34:32 [debug] 46139#0: bind() 0.0.0.0:9935 #7
2018/05/19 12:34:32 [debug] 46139#0: bind() 0.0.0.0:8088 #8
2018/05/19 12:34:32 [notice] 46139#0: using the "epoll" event method
2018/05/19 12:34:32 [debug] 46139#0: counter: 00007FFB4678F080, 1
2018/05/19 12:34:32 [notice] 46139#0: nginx/1.13.9
2018/05/19 12:34:32 [notice] 46139#0: built by gcc 4.8.2 20140120 (Red Hat 4.8.2-15) (GCC)
2018/05/19 12:34:32 [notice] 46139#0: OS: Linux 2.6.32-431.el6.x86_64
2018/05/19 12:34:32 [notice] 46139#0: getrlimit(RLIMIT_NOFILE): 1000000:1000000
2018/05/19 12:34:32 [debug] 46140#0: write: 9, 00007FFFB39ED200, 6, 0
2018/05/19 12:34:32 [debug] 46140#0: setproctitle: "nginx: master process ./objs/nginx"
2018/05/19 12:34:32 [notice] 46140#0: start worker processes
2018/05/19 12:34:32 [debug] 46140#0: channel 3:9
2018/05/19 12:34:32 [notice] 46140#0: start worker process 46141
2018/05/19 12:34:32 [debug] 46140#0: sigsuspend
2018/05/19 12:34:32 [debug] 46141#0: add cleanup: 0000000001DF0FA0
2018/05/19 12:34:32 [debug] 46141#0: malloc: 0000000001DBCB90:8
2018/05/19 12:34:32 [debug] 46141#0: notify eventfd: 11
2018/05/19 12:34:32 [debug] 46141#0: testing the EPOLLRDHUP flag: success
2018/05/19 12:34:32 [debug] 46141#0: malloc: 0000000001DE20C0:6144
2018/05/19 12:34:32 [debug] 46141#0: malloc: 00007FFB46739010:237568
2018/05/19 12:34:32 [debug] 46141#0: malloc: 0000000001DF36A0:98304
2018/05/19 12:34:32 [debug] 46141#0: malloc: 0000000001E0B6B0:98304
2018/05/19 12:34:32 [debug] 46141#0: epoll add event: fd:7 op:1 ev:00002001
2018/05/19 12:34:32 [debug] 46141#0: epoll add event: fd:8 op:1 ev:00002001
2018/05/19 12:34:32 [debug] 46141#0: epoll add event: fd:9 op:1 ev:00002001
2018/05/19 12:34:32 [debug] 46141#0: setproctitle: "nginx: worker process"
2018/05/19 12:34:32 [debug] 46141#0: worker cycle
2018/05/19 12:34:32 [debug] 46141#0: epoll timer: -1

推流开始后的log

2018/05/19 12:44:52 [debug] 46141#0: epoll: fd:7 ev:0001 d:00007FFB46739010
2018/05/19 12:44:52 [debug] 46141#0: accept on 0.0.0.0:9935, ready: 0
2018/05/19 12:44:52 [debug] 46141#0: posix_memalign: 0000000001DE38D0:4096 @16
2018/05/19 12:44:52 [debug] 46141#0: *3 accept: 10.64.7.106:57765 fd:3
2018/05/19 12:44:52 [info] 46141#0: *3 client connected '10.64.7.106'
2018/05/19 12:44:52 [debug] 46141#0: *3 posix_memalign: 0000000001DC6710:4096 @16
2018/05/19 12:44:52 [debug] 46141#0: *3 setting chunk_size=128
2018/05/19 12:44:52 [debug] 46141#0: *3 posix_memalign: 0000000001DC36D0:4096 @16
2018/05/19 12:44:52 [debug] 46141#0: *3 handshake: start server handshake
2018/05/19 12:44:52 [debug] 46141#0: *3 handshake: allocating buffer
2018/05/19 12:44:52 [debug] 46141#0: *3 recv: eof:0, avail:0
2018/05/19 12:44:52 [debug] 46141#0: *3 event timer add: 3: 60000:1526705152926
2018/05/19 12:44:52 [debug] 46141#0: *3 epoll add event: fd:3 op:1 ev:80002001
2018/05/19 12:44:52 [debug] 46141#0: timer delta: 8356
2018/05/19 12:44:52 [debug] 46141#0: worker cycle
2018/05/19 12:44:52 [debug] 46141#0: epoll timer: 60000
2018/05/19 12:44:52 [debug] 46141#0: epoll: fd:3 ev:0001 d:00007FFB467392C8
2018/05/19 12:44:52 [debug] 46141#0: *3 event timer del: 3: 1526705152926
2018/05/19 12:44:52 [debug] 46141#0: *3 recv: eof:0, avail:1
2018/05/19 12:44:52 [debug] 46141#0: *3 recv: fd:3 1537 of 1537
2018/05/19 12:44:52 [debug] 46141#0: *3 epoll del event: fd:3 op:2 ev:00000000
2018/05/19 12:44:52 [debug] 46141#0: *3 handshake: stage 2
2018/05/19 12:44:52 [debug] 46141#0: *3 handshake: peer version=0.0.0.0 epoch=3953333474
2018/05/19 12:44:52 [debug] 46141#0: *3 handshake: old-style challenge
2018/05/19 12:44:52 [debug] 46141#0: *3 send: fd:3 1537 of 1537
2018/05/19 12:44:52 [debug] 46141#0: *3 handshake: stage 3
2018/05/19 12:44:52 [debug] 46141#0: *3 handshake: old-style response
2018/05/19 12:44:52 [debug] 46141#0: *3 send: fd:3 1536 of 1536
2018/05/19 12:44:52 [debug] 46141#0: *3 handshake: stage 4
2018/05/19 12:44:52 [debug] 46141#0: *3 recv: eof:0, avail:1
2018/05/19 12:44:52 [debug] 46141#0: *3 recv: fd:3 1536 of 1536
2018/05/19 12:44:52 [debug] 46141#0: *3 handshake: stage 5
2018/05/19 12:44:52 [debug] 46141#0: *3 handshake: done
2018/05/19 12:44:52 [debug] 46141#0: *3 event timer add: 3: 60000:1526705152926
2018/05/19 12:44:52 [debug] 46141#0: *3 ping: wait 60000ms
2018/05/19 12:44:52 [debug] 46141#0: *3 recv: eof:0, avail:1
2018/05/19 12:44:52 [debug] 46141#0: *3 recv: fd:3 106 of 146
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP bheader fmt=0 csid=3
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP mheader fmt=0 amf_cmd (20) time=0+0 mlen=94 len=0 msid=0
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP recv amf_cmd (20) csid=3 timestamp=0 mlen=94 msid=0 nbufs=1
2018/05/19 12:44:52 [debug] 46141#0: *3 nhandlers: 1
2018/05/19 12:44:52 [debug] 46141#0: *3 calling handler 0
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (1) 02 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (2) 00 07 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (7) 63 6F 6E 6E 65 63 74 'connect'                                                                                                [32266/32312]
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF func 'connect' passed to handler 0/1
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (1) 00 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (8) 3F F0 00 00 00 00 00 00 '????????'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (1) 03 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (2) 00 03 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (3) 61 70 70 'app'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (1) 02 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (2) 00 05 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (5) 73 6D 61 6C 6C 'small'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (2) 00 04 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (4) 74 79 70 65 'type'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (1) 02 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (2) 00 0A '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (10) XX XX XX XX XX XX XX XX XX XX '??????????'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (2) 00 05 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (5) 74 63 55 72 6C 'tcUrl'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (1) 02 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (2) 00 1D '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (29) 72 74 6D 70 3A 2F 2F 31 30 2E 36 34 2E 37 2E 31 'rtmp://10.64.7.1'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (2) 00 00 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (1) 09 '?'
2018/05/19 12:44:52 [info] 46141#0: *3 connect: app='small' args='' flashver='' swf_url='' tc_url='rtmp://10.64.7.106:9935/small' page_url='' acodecs=0 vcodecs=0 object_encoding=0, client: 10.
64.7.106, server: 0.0.0.0:9935
2018/05/19 12:44:52 [debug] 46141#0: *3 create: ack_size=5000000
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP prep ack_size (5) fmt=0 csid=2 timestamp=0 mlen=4 msid=0 nbufs=1
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP send nmsg=1, priority=0 #1
2018/05/19 12:44:52 [debug] 46141#0: *3 send: fd:3 16 of 16
2018/05/19 12:44:52 [debug] 46141#0: *3 create: bandwidth ack_size=5000000 limit=2
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP prep bandwidth (6) fmt=0 csid=2 timestamp=0 mlen=5 msid=0 nbufs=1
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP send nmsg=1, priority=0 #2
2018/05/19 12:44:52 [debug] 46141#0: *3 send: fd:3 17 of 17
2018/05/19 12:44:52 [debug] 46141#0: *3 chunk_size=4000
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP prep chunk_size (1) fmt=0 csid=2 timestamp=0 mlen=4 msid=0 nbufs=1
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP send nmsg=1, priority=0 #3
2018/05/19 12:44:52 [debug] 46141#0: *3 send: fd:3 16 of 16
2018/05/19 12:44:52 [debug] 46141#0: *3 create: amf nelts=4
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (1) 02 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (2) 00 07 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (7) 5F 72 65 73 75 6C 74 '_result'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (1) 00 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (8) 3F F0 00 00 00 00 00 00 '????????'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (1) 03 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (2) 00 06 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (6) 66 6D 73 56 65 72 'fmsVer'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (1) 02 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (2) 00 0D '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (13) 46 4D 53 2F 33 2C 30 2C 31 2C 31 32 33 'FMS/3,0,1,123'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (2) 00 0C '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (12) 63 61 70 61 62 69 6C 69 74 69 65 73 'capabilities'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (1) 00 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (8) 40 3F 00 00 00 00 00 00 '@???????'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (2) 00 00 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (1) 09 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (1) 03 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (2) 00 05 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (5) 6C 65 76 65 6C 'level'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (1) 02 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (2) 00 06 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (6) 73 74 61 74 75 73 'status'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (2) 00 04 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (4) 63 6F 64 65 'code'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (1) 02 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (2) 00 1D '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (29) 4E 65 74 43 6F 6E 6E 65 63 74 69 6F 6E 2E 43 6F 'NetConnection.Co'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (2) 00 0B '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (11) 64 65 73 63 72 69 70 74 69 6F 6E 'description'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (1) 02 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (2) 00 15 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (21) 43 6F 6E 6E 65 63 74 69 6F 6E 20 73 75 63 63 65 'Connection succe'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (2) 00 0E '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (14) 6F 62 6A 65 63 74 45 6E 63 6F 64 69 6E 67 'objectEncoding'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (1) 00 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (8) 00 00 00 00 00 00 00 00 '????????'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (2) 00 00 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (1) 09 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP prep amf_cmd (20) fmt=0 csid=3 timestamp=0 mlen=190 msid=0 nbufs=1
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP send nmsg=1, priority=0 #4
2018/05/19 12:44:52 [debug] 46141#0: *3 send: fd:3 202 of 202
2018/05/19 12:44:52 [debug] 46141#0: *3 recv: eof:0, avail:0
2018/05/19 12:44:52 [debug] 46141#0: *3 epoll add event: fd:3 op:1 ev:80002001
2018/05/19 12:44:52 [debug] 46141#0: timer delta: 0
2018/05/19 12:44:52 [debug] 46141#0: worker cycle
2018/05/19 12:44:52 [debug] 46141#0: epoll timer: 60000
2018/05/19 12:44:52 [debug] 46141#0: epoll: fd:3 ev:0001 d:00007FFB467392C8
2018/05/19 12:44:52 [debug] 46141#0: *3 recv: eof:0, avail:1
2018/05/19 12:44:52 [debug] 46141#0: *3 recv: fd:3 117 of 146
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP bheader fmt=1 csid=3
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP mheader fmt=1 amf_cmd (20) time=0+0 mlen=36 len=0 msid=0
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP recv amf_cmd (20) csid=3 timestamp=0 mlen=36 msid=0 nbufs=1
2018/05/19 12:44:52 [debug] 46141#0: *3 nhandlers: 1                                                                                                                               [32176/32312]
2018/05/19 12:44:52 [debug] 46141#0: *3 calling handler 0
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (1) 02 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (2) 00 0D '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (13) 72 65 6C 65 61 73 65 53 74 72 65 61 6D 'releaseStream'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF cmd 'releasestream' no handler
2018/05/19 12:44:52 [debug] 46141#0: *3 reusing formerly read data: 73
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP bheader fmt=1 csid=3
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP mheader fmt=1 amf_cmd (20) time=0+0 mlen=32 len=0 msid=0
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP recv amf_cmd (20) csid=3 timestamp=0 mlen=32 msid=0 nbufs=1
2018/05/19 12:44:52 [debug] 46141#0: *3 nhandlers: 1
2018/05/19 12:44:52 [debug] 46141#0: *3 calling handler 0
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (1) 02 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (2) 00 09 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (9) 46 43 50 75 62 6C 69 73 68 'FCPublish'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF cmd 'fcpublish' no handler
2018/05/19 12:44:52 [debug] 46141#0: *3 reusing formerly read data: 33
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP bheader fmt=1 csid=3
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP mheader fmt=1 amf_cmd (20) time=0+0 mlen=25 len=0 msid=0
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP recv amf_cmd (20) csid=3 timestamp=0 mlen=25 msid=0 nbufs=1
2018/05/19 12:44:52 [debug] 46141#0: *3 nhandlers: 1
2018/05/19 12:44:52 [debug] 46141#0: *3 calling handler 0
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (1) 02 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (2) 00 0C '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (12) 63 72 65 61 74 65 53 74 72 65 61 6D 'createStream'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF func 'createstream' passed to handler 0/1
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (1) 00 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (8) 40 10 00 00 00 00 00 00 '@???????'
2018/05/19 12:44:52 [info] 46141#0: *3 createStream, client: 10.64.7.106, server: 0.0.0.0:9935
2018/05/19 12:44:52 [debug] 46141#0: *3 create: amf nelts=4
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (1) 02 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (2) 00 07 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (7) 5F 72 65 73 75 6C 74 '_result'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (1) 00 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (8) 40 10 00 00 00 00 00 00 '@???????'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (1) 05 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (1) 00 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (8) 3F F0 00 00 00 00 00 00 '????????'
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP prep amf_cmd (20) fmt=0 csid=3 timestamp=0 mlen=29 msid=0 nbufs=1
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP send nmsg=1, priority=0 #5
2018/05/19 12:44:52 [debug] 46141#0: *3 send: fd:3 41 of 41
2018/05/19 12:44:52 [debug] 46141#0: *3 recv: eof:0, avail:0
2018/05/19 12:44:52 [debug] 46141#0: timer delta: 40
2018/05/19 12:44:52 [debug] 46141#0: worker cycle
2018/05/19 12:44:52 [debug] 46141#0: epoll timer: 59960
2018/05/19 12:44:52 [debug] 46141#0: epoll: fd:3 ev:0001 d:00007FFB467392C8
2018/05/19 12:44:52 [debug] 46141#0: *3 recv: eof:0, avail:1
2018/05/19 12:44:52 [debug] 46141#0: *3 recv: fd:3 49 of 146
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP bheader fmt=0 csid=4
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP mheader fmt=0 amf_cmd (20) time=0+0 mlen=37 len=0 msid=1
2018/05/19 12:44:52 [debug] 46141#0: *3 RTMP recv amf_cmd (20) csid=4 timestamp=0 mlen=37 msid=1 nbufs=1
2018/05/19 12:44:52 [debug] 46141#0: *3 nhandlers: 1
2018/05/19 12:44:52 [debug] 46141#0: *3 calling handler 0
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (1) 02 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (2) 00 07 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (7) 70 75 62 6C 69 73 68 'publish'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF func 'publish' passed to handler 0/1
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (1) 00 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (8) 40 14 00 00 00 00 00 00 '@???????'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (1) 05 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (1) 02 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (2) 00 07 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (7) 6C 6B 31 32 33 34 35 'lk12345'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (1) 02 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (2) 00 04 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF read (4) 6C 69 76 65 'live'
2018/05/19 12:44:52 [info] 46141#0: *3 publish: name='lk12345' args='' type=live silent=0, client: 10.64.7.106, server: 0.0.0.0:9935
2018/05/19 12:44:52 [debug] 46141#0: *3 live: publish: name='lk12345' type='live'
2018/05/19 12:44:52 [debug] 46141#0: *3 live: join 'lk12345'
2018/05/19 12:44:52 [debug] 46141#0: *3 live: create stream 'lk12345'
2018/05/19 12:44:52 [debug] 46141#0: *3 create: status code='NetStream.Publish.Start' level='status' desc='Start publishing'
2018/05/19 12:44:52 [debug] 46141#0: *3 create: amf nelts=4
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (1) 02 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (2) 00 08 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (8) 6F 6E 53 74 61 74 75 73 'onStatus'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (1) 00 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (8) 00 00 00 00 00 00 00 00 '????????'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (1) 05 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (1) 03 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (2) 00 05 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (5) 6C 65 76 65 6C 'level'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (1) 02 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (2) 00 06 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (6) 73 74 61 74 75 73 'status'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (2) 00 04 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (4) 63 6F 64 65 'code'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (1) 02 '?'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (2) 00 17 '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (23) 4E 65 74 53 74 72 65 61 6D 2E 50 75 62 6C 69 73 'NetStream.Publis'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (2) 00 0B '??'
2018/05/19 12:44:52 [debug] 46141#0: *3 AMF write (11) 64 65 73 63 72 69 70 74 69 6F 6E 'description'
#0  ngx_rtmp_live_publish (s=0x141b990, v=0x782020 <v.23367>) at ../nginx-rtmp-module/ngx_rtmp_live_module.c:1046
#1  0x0000000000508033 in ngx_rtmp_relay_publish (s=0x141b990, v=0x782020 <v.23367>) at ../nginx-rtmp-module/ngx_rtmp_relay_module.c:703
#2  0x000000000050bfae in ngx_rtmp_exec_publish (s=0x141b990, v=0x782020 <v.23367>) at ../nginx-rtmp-module/ngx_rtmp_exec_module.c:1190
#3  0x0000000000511144 in ngx_rtmp_notify_publish (s=0x141b990, v=0x782020 <v.23367>) at ../nginx-rtmp-module/ngx_rtmp_notify_module.c:1394
#4  0x0000000000512d30 in ngx_rtmp_log_publish (s=0x141b990, v=0x782020 <v.23367>) at ../nginx-rtmp-module/ngx_rtmp_log_module.c:849
#5  0x00000000005175ae in ngx_rtmp_hls_publish (s=0x141b990, v=0x782020 <v.23367>) at ../nginx-rtmp-module/hls/ngx_rtmp_hls_module.c:1473
#6  0x000000000051c3c0 in ngx_rtmp_dash_publish (s=0x141b990, v=0x782020 <v.23367>) at ../nginx-rtmp-module/dash/ngx_rtmp_dash_module.c:952
#7  0x00000000004f2a2f in ngx_rtmp_cmd_publish_init (s=0x141b990, h=0x13fb790, in=0x13fc730) at ../nginx-rtmp-module/ngx_rtmp_cmd_module.c:509
#8  0x00000000004f063c in ngx_rtmp_amf_message_handler (s=0x141b990, h=0x13fb790, in=0x13fc730) at ../nginx-rtmp-module/ngx_rtmp_receive.c:437
#9  0x00000000004eb665 in ngx_rtmp_receive_message (s=0x141b990, h=0x13fb790, in=0x13fc730) at ../nginx-rtmp-module/ngx_rtmp_handler.c:799
#10 0x00000000004ea677 in ngx_rtmp_recv (rev=0x142b7c0) at ../nginx-rtmp-module/ngx_rtmp_handler.c:464
#11 0x000000000045759b in ngx_epoll_process_events (cycle=0x13f7710, timer=59960, flags=1) at src/event/modules/ngx_epoll_module.c:902
#12 0x00000000004462bd in ngx_process_events_and_timers (cycle=0x13f7710) at src/event/ngx_event.c:242
#13 0x0000000000454cb1 in ngx_worker_process_cycle (cycle=0x13f7710, data=0x0) at src/os/unix/ngx_process_cycle.c:750
#14 0x00000000004514bb in ngx_spawn_process (cycle=0x13f7710, proc=0x454bca <ngx_worker_process_cycle>, data=0x0, name=0x5297f3 "worker process", respawn=-3) at src/os/unix/ngx_process.c:199
#15 0x0000000000453afb in ngx_start_worker_processes (cycle=0x13f7710, n=1, type=-3) at src/os/unix/ngx_process_cycle.c:359
#16 0x0000000000453118 in ngx_master_process_cycle (cycle=0x13f7710) at src/os/unix/ngx_process_cycle.c:131
#17 0x0000000000412169 in main (argc=1, argv=0x7fffb7827928) at src/core/nginx.c:382

handshake

c0+c1   –> client一起发送

s0+s1+s2 <— server分次多次回调发送

c2 —>

ngx_rtmp_init_connection
  ngx_rtmp_init_session
    ngx_rtmp_set_chunk_size   
  ngx_rtmp_handshake
    ngx_rtmp_handshake_recv
      ngx_rtmp_handshake_parse_challenge
      case NGX_RTMP_HANDSHAKE_SERVER_SEND_CHALLENGE
      ngx_rtmp_handshake_send
        case NGX_RTMP_HANDSHAKE_SERVER_SEND_RESPONSE:
        ngx_rtmp_handshake_send
          case NGX_RTMP_HANDSHAKE_SERVER_RECV_RESPONSE:
            ngx_rtmp_handshake_recv
           .....
           case NGX_RTMP_HANDSHAKE_SERVER_DONE:
            ngx_rtmp_handshake_done
              ngx_rtmp_cycle !!!!!!!!!!!!
                ngx_rtmp_reset_ping
                  ngx_add_timer
                  
           

connect

ngx_rtmp_handshake_done调用

ngx_rtmp_cmd_connect_init
  ngx_rtmp_connect =  ngx_rtmp_notify_connect
    ngx_rtmp_netcall_create -- ngx_rtmp_notify_connect_create, ngx_rtmp_notify_connect_create
  ngx_rtmp_relay_postconfiguration
  ngx_rtmp_relay_on_result
    ngx_rtmp_relay_connect_local
    ngx_rtmp_cmd_start_connect

publish

static ngx_rtmp_amf_handler_t ngx_rtmp_cmd_map[] = {
    { ngx_string("connect"),            ngx_rtmp_cmd_connect_init           },
    { ngx_string("createStream"),       ngx_rtmp_cmd_create_stream_init     },
    { ngx_string("closeStream"),        ngx_rtmp_cmd_close_stream_init      },
    { ngx_string("deleteStream"),       ngx_rtmp_cmd_delete_stream_init     },
    { ngx_string("publish"),            ngx_rtmp_cmd_publish_init           },
    { ngx_string("play"),               ngx_rtmp_cmd_play_init              },
    { ngx_string("play2"),              ngx_rtmp_cmd_play2_init             },
    { ngx_string("seek"),               ngx_rtmp_cmd_seek_init              },
    { ngx_string("pause"),              ngx_rtmp_cmd_pause_init             },
    { ngx_string("pauseraw"),           ngx_rtmp_cmd_pause_init             },
};

ngx_rtmp_cmd_postconfiguration

    /* register AMF callbacks */

    ncalls = sizeof(ngx_rtmp_cmd_map) / sizeof(ngx_rtmp_cmd_map[0]);

    ch = ngx_array_push_n(&cmcf->amf, ncalls);
    if (ch == NULL) {
        return NGX_ERROR;
    }

    bh = ngx_rtmp_cmd_map;

    for(n = 0; n < ncalls; ++n, ++ch, ++bh) {
        *ch = *bh;
    }
ngx_rtmp_amf_message_handler

    if (ch && ch->nelts) {
        ph = ch->elts;
        for (n = 0; n < ch->nelts; ++n, ++ph) {
            ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
                "AMF func '%s' passed to handler %d/%d",
                func, n, ch->nelts);
    --  switch ((*ph)(s, h, in))  ------ ngx_rtmp_cmd_map
ngx_rtmp_cmd_publish_init
    if (ngx_rtmp_receive_amf(s, in, in_elts,
                             sizeof(in_elts) / sizeof(in_elts[0]))) ---- 取出v.name, v.type
    ngx_rtmp_cmd_fill_args(v.name, v.args); ---此时的name包括参数,这个函数将name和arg分解
    ngx_rtmp_publish-----进入各个模块的调用

record

ngx_rtmp_record_postconfiguration
|       h = ngx_array_push(&cmcf->events[NGX_RTMP_MSG_AUDIO]);
|       *h = ngx_rtmp_record_av;
|
|       h = ngx_array_push(&cmcf->events[NGX_RTMP_MSG_VIDEO]);
|       *h = ngx_rtmp_record_av;
ngx_rtmp_record_av
ngx_rtmp_record_node_av

to solve…..

static ngx_rtmp_amf_handler_t ngx_rtmp_cmd_map[] = {
    { ngx_string("connect"),            ngx_rtmp_cmd_connect_init           },
    { ngx_string("createStream"),       ngx_rtmp_cmd_create_stream_init     },
    { ngx_string("closeStream"),        ngx_rtmp_cmd_close_stream_init      },
    { ngx_string("deleteStream"),       ngx_rtmp_cmd_delete_stream_init     },
    { ngx_string("publish"),            ngx_rtmp_cmd_publish_init           },
    { ngx_string("play"),               ngx_rtmp_cmd_play_init              },
    { ngx_string("play2"),              ngx_rtmp_cmd_play2_init             },
    { ngx_string("seek"),               ngx_rtmp_cmd_seek_init              },
    { ngx_string("pause"),              ngx_rtmp_cmd_pause_init             },
    { ngx_string("pauseraw"),           ngx_rtmp_cmd_pause_init             },
};¬

ngx_rtmp_cmd_module.c

ngx_module_t  ngx_rtmp_cmd_module = {
    NGX_MODULE_V1,
    &ngx_rtmp_cmd_module_ctx,               /* module context */
    NULL,                                   /* module directives */¬
    NGX_RTMP_MODULE,                        /* module type */¬
    NULL,                                   /* init master */¬
    NULL,                                   /* init module */¬
    NULL,                                   /* init process */¬
    NULL,                                   /* init thread */¬
    NULL,                                   /* exit thread */¬
    NULL,                                   /* exit process */¬
    NULL,                                   /* exit master */¬
    NGX_MODULE_V1_PADDING¬
};¬

ngx_rtmp.h 定义

   662 extern ngx_module_t  ngx_rtmp_module;¬
664 #define NGX_RTMP_MODULE                 0x504D5452     /* "RTMP" */¬
    70 static ngx_rtmp_module_t  ngx_rtmp_cmd_module_ctx = {¬
|     71     NULL,                                   /* preconfiguration */¬
|     72     ngx_rtmp_cmd_postconfiguration,         /* postconfiguration */¬
|     73     NULL,                                   /* create main configuration */¬
|     74     NULL,                                   /* init main configuration */¬
|     75     NULL,                                   /* create server configuration */¬
|     76     NULL,                                   /* merge server configuration */¬
|     77     NULL,                                   /* create app configuration */¬
|     78     NULL                                    /* merge app configuration */¬
|     79 };¬

ngx_rtmp_cmd_postconfiguration

会将上面的connect-> connect_init数据写入到cmcf->amf

ngx_rtmp_cmd_connect_init

设定worker socket path

ngx_rtmp_listener_init_init_conf函数修改响应内容。配置有bug,没生效

hls

ngx_rtmp_hls_postconfiguration

connect

#0  ngx_rtmp_netcall_create (s=0x156c7b0, ci=0x7fff4dd09eb0) at ./src/rtmp/ngx_rtmp_netcall_module.c:178
#1  0x0000000000523ffe in ngx_rtmp_notify_play (s=0x156c7b0, v=0x9c2b80 <v.26981>) at ./src/rtmp/ngx_rtmp_notify_module.c:2058
#2  0x000000000052d523 in ngx_rtmp_log_play (s=0x156c7b0, v=0x9c2b80 <v.26981>) at ./src/rtmp/ngx_rtmp_log_module.c:3502
#3  0x00000000004ed1f2 in ngx_rtmp_cmd_start_play (s=0x156c7b0, v=0x9c2b80 <v.26981>) at ./src/rtmp/ngx_rtmp_cmd_module.c:749
#4  0x000000000053b882 in ngx_rtmp_http_hls_play_local (r=0x1545630) at ./src/rtmp/hls/ngx_rtmp_hls_module.c:3635
#5  0x0000000000539e0a in ngx_rtmp_hls_connect_done (s=0x156c7b0, h=0x0, in=0x0) at ./src/rtmp/hls/ngx_rtmp_hls_module.c:2766
#6  0x00000000004dab06 in ngx_rtmp_fire_event (s=0x156c7b0, evt=26, h=0x0, in=0x0) at ./src/rtmp/ngx_rtmp.c:908
#7  0x00000000004ec4b3 in ngx_rtmp_cmd_connect (s=0x156c7b0, v=0x151a1b8) at ./src/rtmp/ngx_rtmp_cmd_module.c:407
#8  0x000000000050179b in ngx_rtmp_live_connect (s=0x156c7b0, v=0x151a1b8) at ./src/rtmp/ngx_rtmp_live_module.c:2962
#9  0x0000000000521bac in ngx_rtmp_notify_connect_handle (s=0x156c7b0, arg=0x151a1b8, in=0x151aad8) at ./src/rtmp/ngx_rtmp_notify_module.c:1202
#10 0x000000000050cad0 in ngx_rtmp_netcall_close (cc=0x7f989edb2750) at ./src/rtmp/ngx_rtmp_netcall_module.c:333
#11 0x000000000050cdf3 in ngx_rtmp_netcall_recv (rev=0x7f989ecc1310) at ./src/rtmp/ngx_rtmp_netcall_module.c:436
#12 0x000000000044ffb6 in ngx_epoll_process_events (cycle=0x15160b0, timer=2994, flags=1) at src/event/modules/ngx_epoll_module.c:822
#13 0x0000000000440231 in ngx_process_events_and_timers (cycle=0x15160b0) at src/event/ngx_event.c:242
#14 0x000000000044db3b in ngx_worker_process_cycle (cycle=0x15160b0, data=0x0) at src/os/unix/ngx_process_cycle.c:753
#15 0x000000000044a437 in ngx_spawn_process (cycle=0x15160b0, proc=0x44da46 <ngx_worker_process_cycle>, data=0x0, name=0x552e2b "worker process",
    respawn=-3) at src/os/unix/ngx_process.c:198
#16 0x000000000044c977 in ngx_start_worker_processes (cycle=0x15160b0, n=1, type=-3) at src/os/unix/ngx_process_cycle.c:358
#17 0x000000000044bf94 in ngx_master_process_cycle (cycle=0x15160b0) at src/os/unix/ngx_process_cycle.c:130
#18 0x0000000000412ab9 in main (argc=3, argv=0x7fff4dd0b308) at src/core/nginx.c:367
ngx_rtmp_notify_connect_handle 
  next_connect = ngx_rtmp_live_connect
  next_connect = ngx_rtmp_cmd_connect ---- 重要函数

hls video

#0  ngx_rtmp_hls_video (s=0x1571810, h=0x1545808, in=0x156c800) at ./src/rtmp/hls/ngx_rtmp_hls_module.c:2476
#1  0x00000000004e25d3 in ngx_rtmp_receive_message (s=0x1571810, h=0x1545808, in=0x156c800) at ./src/rtmp/ngx_rtmp_handler.c:926 #2  0x00000000004e11e8 in ngx_rtmp_recv (rev=0x7f989ecc1970) at ./src/rtmp/ngx_rtmp_handler.c:494
#3  0x000000000044ffb6 in ngx_epoll_process_events (cycle=0x15160b0, timer=999, flags=1) at src/event/modules/ngx_epoll_module.c:822
#4  0x0000000000440231 in ngx_process_events_and_timers (cycle=0x15160b0) at src/event/ngx_event.c:242
#5  0x000000000044db3b in ngx_worker_process_cycle (cycle=0x15160b0, data=0x0) at src/os/unix/ngx_process_cycle.c:753
#6  0x000000000044a437 in ngx_spawn_process (cycle=0x15160b0, proc=0x44da46 <ngx_worker_process_cycle>, data=0x0, name=0x552e2b "worker process",
    respawn=-3) at src/os/unix/ngx_process.c:198
#7  0x000000000044c977 in ngx_start_worker_processes (cycle=0x15160b0, n=1, type=-3) at src/os/unix/ngx_process_cycle.c:358
#8  0x000000000044bf94 in ngx_master_process_cycle (cycle=0x15160b0) at src/os/unix/ngx_process_cycle.c:130
#9  0x0000000000412ab9 in main (argc=3, argv=0x7fff4dd0b308) at src/core/nginx.c:367

codec

ngx_rtmp_codec_av
h = ngx_array_push(&cmcf->events[NGX_RTMP_MSG_AUDIO]);
*h = ngx_rtmp_codec_av;

h = ngx_array_push(&cmcf->events[NGX_RTMP_MSG_VIDEO]);
*h = ngx_rtmp_codec_av;

h = ngx_array_push(&cmcf->events[NGX_RTMP_DISCONNECT]);
*h = ngx_rtmp_codec_disconnect;

/* register metadata handler */
ch = ngx_array_push(&cmcf->amf);
if (ch == NULL) {
    return NGX_ERROR;
}
ngx_str_set(&ch->name, "@setDataFrame");
ch->handler = ngx_rtmp_codec_meta_data;

ch = ngx_array_push(&cmcf->amf);
if (ch == NULL) {
    return NGX_ERROR;
}
ngx_str_set(&ch->name, "onMetaData");
ch->handler = ngx_rtmp_codec_meta_data;

hls play

ngx_rtmp_hls_play
s->hls_stime_ms = ngx_current_msec
ngx_rtmp_hls_open_file


ngx_rtmp_hls_request_close_handler
ngx_rtmp_hls_session_close_handler
s->hls_etime_ms = ngx_current_msec




## rtmp control



static ngx_command_t ngx_rtmp_control_commands[] = {

{ ngx_string("rtmp_control"),
  NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  ngx_rtmp_control,
  NGX_HTTP_LOC_CONF_OFFSET,
  offsetof(ngx_rtmp_control_loc_conf_t, control),
  ngx_rtmp_control_masks },

ngx_null_command

};



ngx_rtmp_control clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); clcf->handler = ngx_rtmp_control_handler; —> return ngx_conf_set_bitmask_slot(cf, cmd, conf); ngx_rtmp_control_handler return ngx_rtmpcontrol##secname(r, &method); –> ngx_rtmp_control_drop ngx_rtmp_control_drop ngx_rtmp_control_walk ngx_rtmp_control_walk_server ngx_rtmp_control_walk_app ngx_rtmp_control_walk_stream ngx_rtmp_control_walk_session



## @setdataframe


ngx_rtmp_codec_postconfiguration

/* register metadata handler */
ch = ngx_array_push(&cmcf->amf);
if (ch == NULL) {
    return NGX_ERROR;
}
ngx_str_set(&ch->name, "@setDataFrame");
ch->handler = ngx_rtmp_codec_meta_data;

ch = ngx_array_push(&cmcf->amf);
if (ch == NULL) {
    return NGX_ERROR;
}
ngx_str_set(&ch->name, "onMetaData");
ch->handler = ngx_rtmp_codec_meta_data;

```