nginx-rtmp流程分析

一 nginx-rtmp模块初始化
模块配置初始化
ngx_rtmp_cmd_postconfiguration()
{//注意以下回调都是链表,注册了这个回调的模块将会被回调
ngx_rtmp_connect = ngx_rtmp_cmd_connect;
    ngx_rtmp_disconnect = ngx_rtmp_cmd_disconnect;
    ngx_rtmp_create_stream = ngx_rtmp_cmd_create_stream;
    ngx_rtmp_close_stream = ngx_rtmp_cmd_close_stream;
    ngx_rtmp_delete_stream = ngx_rtmp_cmd_delete_stream;
    ngx_rtmp_publish = ngx_rtmp_cmd_publish;
    ngx_rtmp_play = ngx_rtmp_cmd_play;
    ngx_rtmp_seek = ngx_rtmp_cmd_seek;
    ngx_rtmp_pause = ngx_rtmp_cmd_pause;


    ngx_rtmp_stream_begin = ngx_rtmp_cmd_stream_begin;
    ngx_rtmp_stream_eof = ngx_rtmp_cmd_stream_eof;
    ngx_rtmp_stream_dry = ngx_rtmp_cmd_stream_dry;
    ngx_rtmp_recorded = ngx_rtmp_cmd_recorded;
    ngx_rtmp_set_buflen = ngx_rtmp_cmd_set_buflen;
}最终回调是存放到cmcf配置中


ngx_rtmp_block()入口函数
{
    for (i = 0; i < cmcf->listen.nelts; i++) {
        if (ngx_rtmp_add_ports(cf, &ports, &listen[i]) != NGX_OK) {
            return NGX_CONF_ERROR;
        }
return ngx_rtmp_optimize_servers(cf, &ports);
    }
//启动监听端口和设置新连接回调
ngx_rtmp_init_connection() rtmp新连接回调接口

-->ngx_rtmp_init_session()初始化新的rtmp连接
-->ngx_rtmp_handshake(s); rtmp握手
ngx_rtmp_cmd_module.c文件
ngx_rtmp_handshake_recv()->
ngx_rtmp_handshake_done(s);//处理握手之后的命令,connect,publish/play等
ngx_rtmp_fire_event()调用上面注册的回调

二 rtmp推送处理流程
由于握手和前期的chunksize协商等,这些流程对于所有的rtmp协议都是一样,所以已经统一放到握手那块去处理了。
这里主要是看publish开始的调用流程
ngx_rtmp_live_module.c文件
ngx_rtmp_live_publish()-->ngx_rtmp_live_join() 添加到rtmp流列表(直播流配置信息中),注意末尾还有一个调用
return next_publish(s, v);上面说过,nginx-rtmp里面这种回调都是一个链表,模块之间通过
next_xxx回调链接起来。会依次调用注册了publish这个回调的模块,比如hls,flv等模块

三 rtmp播放处理流程
上面推流添加到了直播流列表中,
播放调用ngx_rtmp_live_play()->依然是调用ngx_rtmp_live_join(unsigned publisher)
注意有一个参数publisher,ngx_rtmp_live_join()函数会通过这个判断是推流还是拉流。
ngx_rtmp_live_get_stream()根据流名获取流信息,
如果是观看,并且没有流,将返回错误流未找到。
ctx->next = (*stream)->ctx;//每个观看上下文将呗添加到发布流的观看链表中
四 rtmp转发
上面推流和播放的流程已经清楚了。转发就是遍历观看链表,然后挨个把数据发一遍。
注意:rtmp观看的时候,服务端需要先发metadata消息,以及audio codec head信息和
video codec head信息。
具体看ngx_rtmp_live_av()函数。
rtmp协议的chunk head有四种模式,format占用2bit,标识chunk head携带的信息,比如时间戳,分为两种,
一种是绝对时间戳,和相对时间戳。很显然,第一次转发数据的时候,肯定要先发个绝对时间戳,后面再发相对时间戳。

if (h->type == NGX_RTMP_MSG_AUDIO)
{
ngx_rtmp_is_codec_header(in);//如果遇到音频就先发音频的codec head
}
else
{
ngx_rtmp_is_codec_header(in);//如果遇到视频就先转发视频的codec head
}

for (pctx = ctx->stream->ctx; pctx; pctx = pctx->next)
{
//遍历观看列表,转发rtmp消息数据
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值