nginx-rtmp hls流程分析

一 hls(http live streaming)
hls协议包括两部分,1 m3u8文件(切片列表文件)更新。2 ts切片更新


二 nginx-hls模块
nginx hls模块集成在nginx-rtmp-module中。
相关配置如下:
rtmp {
    server {
        listen 1995;
        ack_window 800000;
        application live {//app名
            live on;
            hls on;//开启hls
            hls_path /data/hls;//hls临时目录
            hls_fragment 3s;//切片大小,以这个标准来,切片以GOP开始,当GOP大于这个配置的时候,切片为一个GOP大小
            hls_max_fragment 10s;//绝对小于这个值,当这个值小于GOP的时候,会出现切片不是以I帧开始
        }


        application hls {
                live on;
                hls on;  
                hls_path temp/hls;  
                hls_fragment 3s;
                hls_max_fragment 4s;  
        }
    }
}


三 nginx-rtmp-module中的hls模块分析
相关回调接口
ngx_rtmp_hls_publish 发布流调用
ngx_rtmp_hls_stream_begin 流开始
ngx_rtmp_hls_stream_eof 流结束
ngx_rtmp_hls_video 视频帧
ngx_rtmp_hls_audio 音频帧
ngx_rtmp_hls_cleanup

ngx_rtmp_hls_publish:
主要创建临时目录,初始化直播m3u8文件名。
ngx_rtmp_hls_stream_eof 流结束,通过注册的回收函数
ngx_rtmp_hls_cleanup 删除hls临时目录。


ngx_rtmp_hls_video-->
ngx_rtmp_hls_update_fragment()//每次处理视频帧,尝试更新切片
{
    if (ctx->opened) {//如果切片是打开状态
        f = ngx_rtmp_hls_get_frag(s, ctx->nfrags);//获取切片信息
        d = (int64_t) (ts - ctx->frag_ts);//当前duration


        if (d > (int64_t) hacf->max_fraglen * 90 || d < -90000) {
            ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
                          "hls: force fragment split: %.3f sec, ", d / 90000.);
            force = 1;//强制关闭切片,切片过大


        } else {//正常切片大小
            f->duration = (ts - ctx->frag_ts) / 90000.;
            discont = 0;
        }
    }


    if (boundary || force) {//如果是切片的边界了,key frame
        ngx_rtmp_hls_close_fragment(s);
        ngx_rtmp_hls_open_fragment(s, ts, 0);
    }
}
PS:我前面准备做一个统计所有ts切片总的duration的功能,于是在ngx_rtmp_hls_close_fragment之前每次把当前切片的
duration加起来,也就是f->duration。但是发现core了,后面意识到当流刚开始,第一次要生成切片的时候,open状态是关闭的,
所以在加duration的时候要判断f是否为空。这样也不会遗漏一个切片,因为每个切片都是在这里结束的。


ngx_rtmp_hls_copy:解析rtmp trunk
ngx_rtmp_mpegts_write_frame()
将数据写到ts切片中。

你可能感兴趣的:(音视频)