http-flv实时流的实现

1.概述

  • 目前我们选择的视频直播方案是nginx+ngx-rtmp-module;
  • http-flv直播流是把rtmp实时流的数据封装成flv格式,并基于http的chunked协议来传输。flv格式、http的chunked块协议及http-flv实时流优势在该文档不再赘述,建议读者在网上查阅;
  • http-flv流实现详见ngx_http_hlf_module、ngx_rtmp_hlf_module模块,以下简称hlf(http-live-flv)模块;
  • 本文档是在已经实现http-flv实时流功能后追加的补充文档,因此阐述的方式与一般的预研文档有所不同,请知悉;
  • 本文档的读者需要对nginx、ngx-rtmp-module有一定的基础,理解rtmp、flv、http的相关知识。

2.实现方案

2.1相关实现文件

Hlf查块实现有如下文件

ngx_http_hlf_module.c       #hlf入口模块,属http模块

ngx_rtmp_hlf_module.h            #hlf实现模块,属rtmp模块

ngx_rtmp_hlf_module.c

ngx_rtmp_hlf_shared.c       #相关内存块的管理

其它相关部分

ngx_rtmp.h                 #增加hlf相关成员

ngx_rtmp.c

ngx_http.h                                     #增加写完一帧(flv -tag)的回调函数

ngx_http.c

ngx_http_write_filter_module.c

2.2模块配置描述

2.2.1属http模块配置

hlf

Syntax: hlf on|off

Context: location

desc:(http模块)指定location是否启用hlf功能,默认off。

hlf_srv

Syntax: hlf_svr numbers

Context: location

desc:(http模块) rtmp server序号,默认0 。

备注:

代码中,见红色部分,flv_relay有识,其实有错识,纠正为hlf,但可不必理会,不影响运行结果。

//模块配置

typedef struct

{

ngx_flag_t    hlf_relay;      //联动hlf中继,默认不启用--,纠正为hlf

ngx_uint_t    hlf_srv;        //rtmp server序号,默认0

} ngx_http_hlf_loc_conf_t;

2.2.2属rtmp模块配置

hlf_enable

Syntax: hlf_enable on|off

Context: rtmp, server, application

desc:hlf启用选项,默认off。

hlf_buckets

Syntax: hlf_buckets numbers

Context: rtmp, server, application

desc:针对每个app建立hash链表,即以推流名称生成hask_key并存放入hash表,表示hash表桶大小,默认1024。

hlf_queue_max

Syntax: hlf_queue_max numbers

Context: rtmp, server, application

desc:针对每个http请求流建立发送缓冲,表示缓冲帧最大帧数,默认256,最小32。

hlf_idle_timeout

Syntax: hlf_idle_timeout time

Context: rtmp, server, application

desc:当http请求指定app的某个流不存在时,等待的时间,默认0,即直接断开。

hlf_relay

Syntax: hlf_relay on|off

Context: rtmp, server, application

desc: 联动中继,默认off。

***********************************************************************

3.实现方案详细描述

  • 还是采用从外到内的描述方式,比较宏观一些;
  • 要增加http-flv实时流,入口一定是从http模块开始,要了解ngx_http_send_header、ngx_http_output_filter两个函数作用及实现原理;
  • 从http模块接轨到rtmp模块,有hlf模块的ngx_rtmp_hlf_add_stream、ngx_rtmp_hlf_del_stream来实现;
  • hlf模块的rtmp模块实现rtmp数据转flv的tag数据,分发flv数据等;
  • 增加或完善了nginx中有关ngx_http_write_filter函数的功能;
  • 再次声明:本文档不会阐述原有模块及基本相关知识点,仅阐述增加部分的功能。

3.1 ngx_http_hlf_module

实现文件

ngx_http_hlf_module.c

相关的文件

ngx_http.h

ngx_http.c

ngx_http_write_filter_module.c

3.1.1 ngx_http_hlf_module.c

两个主要的函数

3.1.1.1ngx_http_hlf_init

初始化ngx_http_hlf_module,注册ngx_http_top_write_filter_peerfinished函数,该函数是ngx_http.h文件中新增加的,最终有ngx_http_write_filter来驱动,注册后实际会调用ngx_http_hlf_filter_peerframe_finished,用于实现每发送完一个flv-tag后,继续驱动下一个flv-tag的发送。

ngx_http_top_write_filter_peerfinished =ngx_http_hlf_filter_peerframe_finished;

ngx_rtmp_hlf_peerframe_finished      # ngx_rtmp_hlf_module

ngx_rtmp_hlf_output_filter        # ngx_rtmp_hlf_module

3.1.1.2ngx_http_hlf_do

ngx_http_hlf_do

ngx_http_hlf_handler

ngx_http_hlf_handler函数就是处理hlf配置项的;

http-flv实时流的url格式如下:

http://192.168.1.80/room_hd/6000.flv

每一个http-flv请求上来,会生成一个该模块的上下文ngx_rtmp_hlf_stream_t,该上文的结构参考了rtmp拉流上下文结构,其实整个实现都参考rtmp流实现的方案,如果你已经知道其中原理,建议跳过本文档,直接看实现代码;

ngx_http_hlf_handler实现描述

1.      检验url地址有效性,获取app及name。有ngx_http_hlf_check_uri、ngx_http_hlf_get_app_name函数实现;

2.      根据appt和name把该请求追加到ngx_rtmp_hlf _module模块中,并返回该请求上下文(ngx_rtmp_hlf_stream_t)。有ngx_rtmp_hlf_add_stream函数实现;

3.      设置模块的上下文ngx_rtmp_hlf_stream_t;

4.      注册http断开清除函数,即断开后能调用ngx_rtmp_hlf_module的ngx_rtmp_hlf_del_stream函数;

5.      生成http回复头并发送

6.      生成第一个flv-tag(flv文件头),并发送,ngx_http_hlf_gengerate_header。

备注:

以上红色标注的部分,五个函数。其中ngx_http_top_write_filter_peerfinish是nginx-http.h增加的函数,其它四个是ngx_rtmp_hlf_module模块提供的。

3.1.2相关的文件

提供每发送完一个flv-tag后,能通知出来,以便ngx_rtmp_hlf_module能继续一下flv-tag的发送。

ngx_http_top_write_filter_peerfinished

if (chain == NULL&& ngx_http_top_write_filter_peerfinished)

{

ngx_http_top_write_filter_peerfinished(r);

}

3.2ngx_rtmp_hlf_module

3.2.1配置结构体

//hlf配置

typedef struct {

ngx_flag_t                  enable;          //启用标识(其它选项,后续增加)

ngx_int_t                   nbuckets;        //hash桶个数,默认1024

ngx_int_t                   queue_max;     //缓冲最大帧数,默认256,最小32

ngx_msec_t                 idle_timeout;    //无流时保持时长 ,默认直接断开(0)

ngx_flag_t                  hlf_relay;        //联动中继,默认off

ngx_rtmp_hlf_ctx_t           **ctxs;

ngx_pool_t                  *pool;

ngx_rtmp_hlf_ctx_t            *free_ctxs;

} ngx_rtmp_hlf_app_conf_t;

3.2.2推流上下文

//推流上下文

struct ngx_rtmp_hlf_ctx_s {

ngx_rtmp_hlf_ctx_t      *next;

ngx_rtmp_hlf_app_conf_t *conf;

ngx_rtmp_session_t      *s;

ngx_rtmp_publish_t      *v;

ngx_uint_t               hlf_srv;

u_char                  name[NGX_RTMP_MAX_NAME];

ngx_rtmp_header_t       header;                //最近一个关键帧--头

ngx_chain_t            *near_iframe;           //最近一个关键帧--数据

ngx_rtmp_hlf_stream_t   *streams;

};

3.2.3http-flv拉流上下文

//http拉流上下文

struct ngx_rtmp_hlf_stream_s {

ngx_rtmp_hlf_stream_t   *next;

ngx_http_request_t      *r;

ngx_rtmp_hlf_ctx_t      *ctx;

ngx_flag_t               del;

ngx_str_t                app;

ngx_str_t                name;

ngx_msec_t              begin_time;

unsigned                start_sent:1;

unsigned                aac_header_sent:1;

unsigned                avc_header_sent:1;

unsigned                video_key_send:1;

//** 用于统计(之后改用ngx_rtmp_bandwidth_t)

size_t                  out_bytes;          //已发送字节数

size_t                  lost_frames;        //丢弃帧数

ngx_event_t  *idle_timer;        //ngx_rtmp_hlf_app_conf_t.idle_timeout>0时,启用

ngx_chain_t            *out_chain,*out_chain_c;

size_t                  out_chain_len;

ngx_chain_t            *free_chains;       //ngx_chain_t+ ngx_buf_t

ngx_chain_t       **ncs;               //用于ngx_rtmp_hlf_remove_nframes()函数

//**用于环形缓冲

size_t                  out_max,out_size,out_pos,out_last;

ngx_chain_t            *out[0];

};

3.2.4提供的外部函数

3.1节有描述,ngx_rtmp_hlf_module模块提供了三个函数给ngx_http_hlf_module模块调用。

分别http_flv请求上来时,请求断开时及发送完一个flv-tag时:

ngx_int_t

ngx_rtmp_hlf_add_stream(ngx_http_request_t*r, ngx_str_t *app, ngx_str_t *name, ngx_uint_t srv, ngx_rtmp_hlf_stream_t**st);

void

ngx_rtmp_hlf_del_stream(ngx_rtmp_hlf_stream_t*st);

ngx_int_t

ngx_rtmp_hlf_peerframe_finished(ngx_rtmp_hlf_stream_t*st);

3.2.5接入rtmp模块相关的函数链

详见:

static ngx_int_t

ngx_rtmp_hlf_postconfiguration(ngx_conf_t*cf)

{

ngx_rtmp_core_main_conf_t         *cmcf;

ngx_rtmp_handler_pt               *h;

cmcf = ngx_rtmp_conf_get_module_main_conf(cf, ngx_rtmp_core_module);

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

*h = ngx_rtmp_hlf_av;

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

*h = ngx_rtmp_hlf_av;

next_publish = ngx_rtmp_publish;

ngx_rtmp_publish = ngx_rtmp_hlf_publish;

next_close_stream = ngx_rtmp_close_stream;

ngx_rtmp_close_stream = ngx_rtmp_hlf_close_stream;

next_stream_begin = ngx_rtmp_stream_begin;

ngx_rtmp_stream_begin = ngx_rtmp_hlf_stream_begin;

next_stream_eof = ngx_rtmp_stream_eof;

ngx_rtmp_stream_eof = ngx_rtmp_hlf_stream_eof;

return NGX_OK;

}

主要有

ngx_rtmp_hlf_publish                        #rtmp推流上来时

ngx_rtmp_hlf_close_stream     #rtmp推流断开时

ngx_rtmp_hlf_av                            #av数据上来时

3.2.5.1 ngx_rtmp_hlf_publish

实现描述:

1.      生成一个本模块推流上下议,ngx_rtmp_hlf_ctx_t,并放到本模块配置上下文的ngx_rtmp_hlf_app_conf_t的ctxs链表中;

2.      若开启了无流时等待,即关闭该流下所有http_flv流请求的定时器。

3.2.5.2 ngx_rtmp_hlf_close_stream

实现描述:

1.      清除该流下所有http_flv流请求;

2.      清除缓冲的最后一个gop;

3.      清除本流上下文。

3.2.5.3 ngx_rtmp_hlf_av

本实现参考了rtmp实时流的分发机制,但也加入自己的一些认识,比如分发时的丢包机制。

实现描述:

1.      给该流下的所有http_flv请求推送flv-tag数据;

2.      同样的,ngx_rtmp_core_srv_conf_t配置上下文件中,增加了hlf相关内存块链接,例如:

ngx_chain_t            *free_hlf;       //用于http live flv

ngx_chain_t           *free_iframe;    //用于http liveflv,save near i frame

3.      第一个http_flv上下建立自己的发送缓冲,ngx_rtmp_hlf_stream_s,例如:

size_t                   out_max,out_size,out_pos,out_last;

ngx_chain_t             *out[0];

4.      flv_tag缓冲是通过引用计数的原理实现的;

5.      结合h264编码原理,引入更科学的丢包策略;

丢包策略,详见ngx_rtmp_hlf_remove_out:

移除策略:优先级从低到高分别是p帧/音频帧,i帧,强制帧

1.优先移除P帧,音频帧--(仅对i帧,强制帧有效)

2.再移除I帧--(仅对i帧,强制帧有效)

3.最终移除多余强制帧,但每个至少保留一个--(仅对强制帧有效)

**/

3.2.6相关的文件

ngx_rtmp.h

ngx_rtmp.cpp

ngx_rtmp_hlf_shared.c

主要实现分发flv-tag数据时一些内存的管理,其原理同rtmp流数据分发时内存管理策略是一样的。

主要有:

typedef struct ngx_rtmp_core_srv_conf_s {

ngx_array_t            applications; /* ngx_rtmp_core_app_conf_t */

ngx_msec_t              timeout;

ngx_msec_t              ping;

ngx_msec_t             ping_timeout;

ngx_flag_t             so_keepalive;

ngx_int_t              max_streams;

ngx_uint_t             ack_window;

ngx_int_t               chunk_size;

ngx_pool_t             *pool;

ngx_chain_t            *free;

ngx_chain_t            *free_hs;

ngx_chain_t            *free_hlf;       //用于http live flv

ngx_chain_t            *free_iframe;    //用于http live flv,save near i frame

size_t                 max_message;

ngx_flag_t             play_time_fix;

ngx_flag_t             publish_time_fix;

ngx_flag_t              busy;

size_t                  out_queue;

size_t                  out_cork;

ngx_msec_t              buflen;

ngx_rtmp_conf_ctx_t    *ctx;

} ngx_rtmp_core_srv_conf_t;

//******** begin hlf shared bufs***********************

#define NGX_RTMP_FLV_TAG_HEADER_SIZE         11 //tag header size

#define NGX_RTMP_FLV_PREVIOUS_TAG_SIZE  4  //pre tagsize

ngx_chain_t*

ngx_rtmp_hlf_alloc_shared_buf(ngx_rtmp_core_srv_conf_t*cscf);

void

ngx_rtmp_hlf_free_shared_chain(ngx_rtmp_core_srv_conf_t*cscf, ngx_chain_t *in);

ngx_chain_t*

ngx_rtmp_hlf_append_shared_bufs(ngx_rtmp_core_srv_conf_t*cscf, ngx_chain_t *head, ngx_chain_t *in);

//hlf,near i frame

ngx_chain_t*

ngx_rtmp_hlf_neariframe_alloc_chain(ngx_rtmp_core_srv_conf_t*cscf);

void

ngx_rtmp_hlf_neariframe_free_chain(ngx_rtmp_core_srv_conf_t*cscf, ngx_chain_t *in);

ngx_chain_t*

ngx_rtmp_hlf_neariframe_copy_chain(ngx_rtmp_core_srv_conf_t*cscf, ngx_chain_t *in);

//******** end hlf shared bufs*************************

ngx_rtmp_hlf_shared.c

内存管理的具体实现。

备注:

理解该部分需要对rtmp分发数据的原理有一定的了解,同时知道ngx_chain_t,ngx_buf_t相关结构。

4.总结

源码详见:

https://download.csdn.net/download/laichanghe/10455405

QQ:19993939

备注:文档内QQ号是错的,在此纠正。

基于ngx-rtmp-module模块http-flv直播流的实现相关推荐

  1. LiveQing流媒体RTMP推流服务-如何获直播流地址 HLS/HTTP-FLV/WS-FLV/WebRTC/RTMP视频流地址

    LiveQing流媒体RTMP推流服务-如何获直播流地址 HLS/HTTP-FLV/WS-FLV/WebRTC/RTMP视频流地址 1.服务说明 2.如何一步一步搭建视频直播 3.配置鉴权直播间 3. ...

  2. LiveNVR配置拉转RTSP传统海康大华安防摄像机直播流输出RTSP/RTMP/HLS/HTTP-FLV如何获取直播流地址

    LiveNVR配置拉转RTSP传统海康大华安防摄像机直播流输出RTSP/RTMP/HLS/HTTP-FLV如何获取直播流地址 1. Onvif/RTSP流媒体服务 2.配置拉转直播流 2.1 RTSP ...

  3. 视频流媒体播放器EasyPlayer.js如何实现在FLV直播流断流恢复后自动重连?

    背景分析 EasyPlayer-Android播放器是一款可针对RTSP.RTMP.RTSP&RTMP协议进行过优化的流媒体播放器,其中我们引以为傲的两个技术优势就是起播速度快和播放延迟低.最 ...

  4. flv直播流播放视频,websocket响应造成内存泄漏 浏览器崩溃

    项目现状: 问题:公司做了个监控设备的直播流大屏,技术使用了flv 和websocket,项目写好了,拿到他们那边使用运行了40分钟 浏览器崩溃了,报内存不足 ## 解决思路一:第一个我想到的是flv ...

  5. nginx的rtmp搭建流媒体服务器实现直播流

    最近自己搞了一个用nginx的rtmp来搭建流媒体服务器,从而实现直播的过程,参考了网上很多资料,有些资料对于初学者来说比较难以理解,在此将我搭建的过程记录下来,分享给大家. 1.下载nginx-rt ...

  6. flv(直播流视频播放)踩坑

    最近项目开发中用flv加载的直播视频流遇到了如下几个问题,现进行记录学习 1.出现组件销毁后,视频流依然在进行拉流 2.出现断流和卡顿 项目场景: flv格式的直播流通过flv.js依赖进行实时直播播 ...

  7. 基于OpenCV 的美颜相机推送直播流

    程序流程: 1.图像采集 先从opencv(2.4.10版本)采集回来摄像头的图像,是一帧一帧的 每一帧图像是一个矩阵,opencv中的mat 数据结构. 2.人脸的美化 人脸美化,我们用的皮肤检测, ...

  8. java做flv直播服务器_一种RTMP直播流到HTTPFLV直播流实时转换系统及其工作方法与流程...

    本发明属于互联网的音视频技术领域,具体涉及一种RTMP直播流到HTTP FLV直播流实时转换系统及其工作方法. 背景技术: 在传统互联网直播领域,PC端采用RTMP协议进行视频直播,国内一部分CDN服 ...

  9. java做flv直播服务器,EasyDSS流媒体服务器软件(支持RTMP/HLS/HTTP-FLV/视频点播/视频直播)-正式环境安装部署攻略...

    EasyDSS流媒体服务器软件,提供一站式的转码.点播.直播.时移回放服务,极大地简化了开发和集成的工作. 其中,点播功能主要包含:上传.转码.分发.直播功能,主要包含:直播.录像, 直播支持RTMP ...

  10. Car-eye-http-flv-module 实现nginx-rtmp-mudule HTTP方式的FLV直播功能

    nginx-rtmp-mudule RTMP 是一款优秀的Car-eye-http-flv-module 是在nginx-rtmp-mudule RTMP基础上修改的流媒体服务器,除了支持flash播 ...

最新文章

  1. 剑指Offer——网易笔试之解救小易
  2. java核心api_Java核心API之字符流使用介绍
  3. Liunx操作系统的引导过程(系统操作引导过程,模拟MBR,GRUB故障,root密码遗忘解决,优化启动过程 ,运行级别的分类)
  4. java引用hive高可用连接hive_Hiveserver2高可用实现
  5. 数据安全架构设计与实战~如何加密结构化数据
  6. 学生管理系统--golang--简单版本---开发框架
  7. 汽车在哪扇门后面(博弈论的诡计)
  8. 拓端tecdat|R语言NLP案例:LDA主题文本挖掘优惠券推荐网站数据
  9. 微信小程序数据懒加载
  10. 搬运视频抖音封号md5视频修改工具
  11. Linux(centos7下载安装)
  12. 聊天机器人 java_java实现自动回复聊天机器人
  13. 11月15~30非技术积累
  14. 新一代容器技术———Podman
  15. 【Unity 22】 Unity 力,扭矩,刚体,触发器的简单使用
  16. java hex_使用java实现hex和ascii码的转换
  17. Qt延时处理的四种方法
  18. 未来教育1级计算机基础及ms,未来教育·全国计算机等级考试教程:一级计算机基础及MS Office应用...
  19. matlab SOR统计滤波
  20. 科学计算库——Pandas随笔【附网络隐私闲谈】

热门文章

  1. 对修饰器的实验支持功能在将来的版本中可能更改。在“tsconfig“ 或 “jsconfig“ 中设置 “experimentalDecorators“ 选项以删除此警告
  2. 西南大学计算机考研808真题分享
  3. 国外电商网站snapdeal爬取流程
  4. 8.9 五色定理(Heawood 1890)
  5. 早安心语优美的心情语录
  6. 【营销】史上最全4P、4C、4S、4R、4V、4I营销理论
  7. LeetCode160.相交链表
  8. 【论文阅读】R3Det
  9. ROS——一文读懂:param参数
  10. 关于keil中,while循环条件不成立却无法跳出的问题