nginx_rtmp_module 之 ngx_rtmp_live_module模块

模块作用

直播模块代码 ngx_rtmp_live_module.c,主要作用是:当客户端推流或者拉流的时候,创建的rtmp session会加入到 live 模块的存储链表中。

模块配置命令

static ngx_command_t  ngx_rtmp_live_commands[] = {{ ngx_string("live"),NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,ngx_conf_set_flag_slot,NGX_RTMP_APP_CONF_OFFSET,offsetof(ngx_rtmp_live_app_conf_t, live),NULL },// 表示开启直播{ ngx_string("stream_buckets"),NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,ngx_conf_set_str_slot,NGX_RTMP_APP_CONF_OFFSET,offsetof(ngx_rtmp_live_app_conf_t, nbuckets),NULL },// 录制流名hash桶的大小{ ngx_string("buffer"),NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,ngx_conf_set_msec_slot,NGX_RTMP_APP_CONF_OFFSET,offsetof(ngx_rtmp_live_app_conf_t, buflen),NULL },// 设置默认缓冲区长度。通常客户端set_buflen在播放之前发送RTMP 命令,并重置此设置。默认是1000 ms。{ ngx_string("sync"),NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,ngx_rtmp_live_set_msec_slot,NGX_RTMP_APP_CONF_OFFSET,offsetof(ngx_rtmp_live_app_conf_t, sync),NULL },// 同步音频和视频流。如果订阅者带宽不足以以发布者速率接收数据,则服务器会丢弃一些帧。这就导致了同步问题。当时间戳差异超过sync参数指定的值时,将发送一个绝对帧来修复它。默认值是300ms。{ ngx_string("interleave"),NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,ngx_conf_set_flag_slot,NGX_RTMP_APP_CONF_OFFSET,offsetof(ngx_rtmp_live_app_conf_t, interleave),NULL },// 切换交错模式。在这种模式下,音频和视频数据在相同的RTMP块流上传输。默认为关闭。{ ngx_string("wait_key"),NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,ngx_conf_set_flag_slot,NGX_RTMP_APP_CONF_OFFSET,offsetof(ngx_rtmp_live_app_conf_t, wait_key),NULL },// 使视频流开始于关键帧。在某些情况下才会触发{ ngx_string("wait_video"),NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,ngx_conf_set_flag_slot,NGX_RTMP_APP_CONF_OFFSET,offsetof(ngx_rtmp_live_app_conf_t, wait_video),NULL },{ ngx_string("publish_notify"),NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,ngx_conf_set_flag_slot,NGX_RTMP_APP_CONF_OFFSET,offsetof(ngx_rtmp_live_app_conf_t, publish_notify),NULL },{ ngx_string("play_restart"),NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,ngx_conf_set_flag_slot,NGX_RTMP_APP_CONF_OFFSET,offsetof(ngx_rtmp_live_app_conf_t, play_restart),NULL },{ ngx_string("idle_streams"),NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,ngx_conf_set_flag_slot,NGX_RTMP_APP_CONF_OFFSET,offsetof(ngx_rtmp_live_app_conf_t, idle_streams),NULL },// 如果关闭,nginx-rtmp会阻止订阅用户连接到空闲/不存在的直播流,并在流发布者断开连接时断开所有订阅用户。默认为开启。{ ngx_string("drop_idle_publisher"),NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,ngx_rtmp_live_set_msec_slot,NGX_RTMP_APP_CONF_OFFSET,offsetof(ngx_rtmp_live_app_conf_t, idle_timeout),NULL },// 在指定时间内删除已空闲(无音频/视频数据)的发布者连接。默认为关闭。注意,这仅在连接处于发布模式(在发送发布命令之后)时有效。ngx_null_command
};

代码流程模块

1. 定义live_module 模块,加载模块的时候,会调用相应的函数进行初始化操作
 

static ngx_rtmp_module_t  ngx_rtmp_live_module_ctx = {NULL,                                   /* preconfiguration */ngx_rtmp_live_postconfiguration,        /* postconfiguration */NULL,                                   /* create main configuration */NULL,                                   /* init main configuration */NULL,                                   /* create server configuration */NULL,                                   /* merge server configuration */ngx_rtmp_live_create_app_conf,          /* create app configuration */ngx_rtmp_live_merge_app_conf            /* merge app configuration */
};

2. 配置文件初始化

static void * ngx_rtmp_live_create_app_conf(ngx_conf_t *cf)
{ngx_rtmp_live_app_conf_t      *lacf;// 从pool内存池中分配 ngx_rtmp_live_app_conf_t 对象lacf = ngx_pcalloc(cf->pool, sizeof(ngx_rtmp_live_app_conf_t));if (lacf == NULL) {return NULL;}lacf->live = NGX_CONF_UNSET;lacf->nbuckets = NGX_CONF_UNSET;lacf->buflen = NGX_CONF_UNSET_MSEC;lacf->sync = NGX_CONF_UNSET_MSEC;lacf->idle_timeout = NGX_CONF_UNSET_MSEC;lacf->interleave = NGX_CONF_UNSET;lacf->wait_key = NGX_CONF_UNSET;lacf->wait_video = NGX_CONF_UNSET;lacf->publish_notify = NGX_CONF_UNSET;lacf->play_restart = NGX_CONF_UNSET;lacf->idle_streams = NGX_CONF_UNSET;return lacf;
}

3. 解析配置文件,如果配置文件没有配置指定命令,则取默认值,配置值则直接赋值

static char *
ngx_rtmp_live_merge_app_conf(ngx_conf_t *cf, void *parent, void *child)
{ngx_rtmp_live_app_conf_t *prev = parent;ngx_rtmp_live_app_conf_t *conf = child;ngx_conf_merge_value(conf->live, prev->live, 0);ngx_conf_merge_value(conf->nbuckets, prev->nbuckets, 1024);ngx_conf_merge_msec_value(conf->buflen, prev->buflen, 0);ngx_conf_merge_msec_value(conf->sync, prev->sync, 300);ngx_conf_merge_msec_value(conf->idle_timeout, prev->idle_timeout, 0);ngx_conf_merge_value(conf->interleave, prev->interleave, 0);ngx_conf_merge_value(conf->wait_key, prev->wait_key, 1);ngx_conf_merge_value(conf->wait_video, prev->wait_video, 0);ngx_conf_merge_value(conf->publish_notify, prev->publish_notify, 0);ngx_conf_merge_value(conf->play_restart, prev->play_restart, 0);ngx_conf_merge_value(conf->idle_streams, prev->idle_streams, 1);conf->pool = ngx_create_pool(4096, &cf->cycle->new_log);if (conf->pool == NULL) {return NGX_CONF_ERROR;}conf->streams = ngx_pcalloc(cf->pool,sizeof(ngx_rtmp_live_stream_t *) * conf->nbuckets);return NGX_CONF_OK;
}

4. ngx_rtmp_live_av:音视频数据到来的时候会回调ngx_rtmp_live_av,进行处理数据
   ngx_rtmp_live_publish onpublish 时间回调此函数
   ngx_rtmp_live_play  onplay 事件回调此函数
   ngx_rtmp_live_close_stream 流关闭回到次函数

5. 当客户端推流或者拉流,会通过ngx_rtmp_live_join,把推流或者拉流的rtmp session 加入到流的hash 桶中,hash桶的大小可以通过配置,如果发生hash 冲突,则通过桶对应的链表进行解决,访问的时候通过name进行比较确定是哪一路stream。下面一图表示流的存储数据结构


6. 超时会断开流

static void
ngx_rtmp_live_idle(ngx_event_t *pev)
{ngx_connection_t           *c;ngx_rtmp_session_t         *s;c = pev->data;s = c->data;ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,"live: drop idle publisher");ngx_rtmp_finalize_session(s);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/227975.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue3 插槽slot

插槽是子组件中的提供给父组件使用的一个占位符&#xff0c;用 <slot> 表示&#xff0c;父组件可以在这个占位符中填充任何模板代码&#xff0c;如 HTML、组件等&#xff0c;填充的内容会替换子组件的<slot> 元素。<slot> 元素是一个插槽出口 (slot outlet)&…

蓝桥杯专题-真题版含答案-【骑士走棋盘】【阿姆斯壮数】【Shell 排序法 - 改良的插入排序】【合并排序法】

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分…

李宏毅机器学习2023课程记录(1)--课程介绍

李宏毅机器学习2023课程记录(1)–课程介绍 在这里&#xff0c;记录我最近听的李宏毅老师的机器学习课程的一些笔记和感想&#xff0c;进行归纳总结同时方便后续复习回顾。 注&#xff1a;这门课虽然叫做机器学习&#xff0c;但是李宏毅老师讲课主要以深度学习的技术&#xff0…

在Node.js中MongoDB的连接查询操作

本文主要介绍在Node.js中MongoDB的连接查询操作。 目录 Node.js中MongoDB的连接查询操作使用原生的mongodb驱动程序进行连接查询操作使用Mongoose库进行连接查询操作注意项 Node.js中MongoDB的连接查询操作 在Node.js中使用MongoDB进行连接操作&#xff0c;可以使用原生的mong…

AOP切入点表达式和使用连接点获取匹配到的方法信息

目录 第一种 execution(访问修饰符? 返回值 包名.类名.?方法名(方法参数) throws 异常?) 第二种 annotation(com.itheima.anno.Log 首先&#xff0c;自定义一个注解&#xff0c;可以自己随意命名&#xff1a; 第一种 execution(访问修饰符? 返回值 包名.类名.?方法名…

Explain工具-SQL性能优化

文章目录 SQL性能优化的目标Explain中type效率级别&#xff08;重要&#xff09;注意 Explain覆盖索引ExplainindexExplainfilesortExplainfilesort创建 idx_bd(b,d) SQL性能优化的目标 达到 range 级别 Explain中type效率级别&#xff08;重要&#xff09; 显示的是单位查询…

pytorch强化学习(1)——DQNSARSA

实验环境 python3.10 torch2.1.1 gym0.26.2 gym[classic_control] matplotlib3.8.0 numpy1.26.2DQN代码 首先是module.py代码&#xff0c;在这里定义了网络模型和DQN模型 import torch import torch.nn as nn import numpy as npclass Net(nn.Module):# 构造只有一个隐含层的…

LLM大语言模型(二):Streamlit 无需前端经验也能画web页面

目录 问题 Streamlit是什么&#xff1f; 怎样用Streamlit画一个LLM的web页面呢&#xff1f; 文本输出 页面布局 滑动条 按钮 对话框 输入框 总结 问题 假如你是一位后端开发&#xff0c;没有任何的web开发经验&#xff0c;那如何去实现一个LLM的对话交互页面呢&…

Python MySQL数据库连接与基本使用

一、应用场景 python项目连接MySQL数据库时&#xff0c;需要第三方库的支持。这篇文章使用的是PyMySQL库&#xff0c;适用于python3.x。 二、安装 pip install PyMySQL三、使用方法 导入模块 import pymysql连接数据库 db pymysql.connect(hostlocalhost,usercode_space…

Spring MVC开发流程

1.Spring MVC环境基本配置 Maven工程依赖spring-webmvc <dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.1.9.RELEASE</version> </dependency>web.xml配置Dispatche…

NSSCTF第16页(2)

[NSSRound#4 SWPU]1zweb(revenge) 查看index.php <?php class LoveNss{public $ljt;public $dky;public $cmd;public function __construct(){$this->ljt"ljt";$this->dky"dky";phpinfo();}public function __destruct(){if($this->ljt"…

day01unittest复习,断言

1.unittest 方法执行前 # def setUp(self) -> None: # print(方法执行前执行) # # def tearDown(self) -> None: # print(方法执行后执行一次) 2.unittest 类方法执行前后执行一次 classmethod def setUpClass(cls) -> None:print(类执行前执行一次)classm…

微分和导数(一)

1.微分&#xff1a; 假设我们有⼀个函数f : R → R&#xff0c;其输⼊和输出都是标量。如果f的导数存在&#xff0c;这个极限被定义为 如果f′(a)存在&#xff0c;则称f在a处是可微的。如果f在⼀个区间内的每个数上都是可微的&#xff0c;则此函数在此区间中是可微的。导数f′…

网络协议 - UDP 协议详解

网络协议 - UDP 协议详解 UDP概述UDP特点UDP的首部格式UDP校验 參考文章 基于TCP和UDP的协议非常广泛&#xff0c;所以也有必要对UDP协议进行详解。 UDP概述 UDP(User Datagram Protocol)即用户数据报协议&#xff0c;在网络中它与TCP协议一样用于处理数据包&#xff0c;是一种…

必要时进行保护性拷贝

保护性拷贝&#xff08;Defensive Copy&#xff09;是一种常见的编程实践&#xff0c;用于在传递参数或返回值时&#xff0c;创建副本以防止原始对象被意外修改。以下是一个例子&#xff0c;展示了何时进行保护性拷贝&#xff1a; mport java.util.ArrayList; import java.uti…

数据手册Datasheet解读-肖特基二极管笔记

数据手册Datasheet解读笔记1-肖特基二极管 数据手册大体结构共包含10个部分肖特基二极管-SS14第一重点关注点&#xff1a;极限值第二重点关注点&#xff1a;电气特性 数据手册大体结构共包含10个部分 1.Features一特性 2.Application一应用 3.Description一说明4.Pin Configur…

关于在Java中打印“数字”三角形图形的汇总

之前写过一篇利用*打印三角形汇总&#xff0c;网友需要查看可以去本专栏查找之前的文章&#xff0c;这里利用二维数组嵌套循环打印“数字”三角形&#xff0c;汇总如下&#xff0c;话不多说&#xff0c;直接上代码&#xff1a; /*** 打印如下数字三角形图形*/ public class Wo…

逻辑分析仪_使用手册

LA1010 1> 能干啥&#xff1f;2> 硬件连接3> 软件安装4> 参数设置4.1> 采样深度和采样率4.2> 添加协议解析器4.3> 毛刺过滤设置 1> 能干啥&#xff1f; 测量通信波形&#xff0c;并自动解析&#xff1b; 比如测量&#xff0c;UART&#xff0c;SPI&…

【DataSophon】大数据管理平台DataSophon-1.2.1安装部署详细流程

&#x1f984; 个人主页——&#x1f390;开着拖拉机回家_Linux,大数据运维-CSDN博客 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341; &#x1fa81;&#x1f341;&#x1fa81;&am…

java_web_电商项目

java_web_电商项目 1.登录界面2.注册界面3. 主界面4.分页界面5.商品详情界面6. 购物车界面7.确认订单界面8.个人中心界面9.收货地址界面10.用户信息界面11.用户余额充值界面12.后台首页13.后台商品增加14.后台用户增加15.用户管理16.源码分享1.登录页面的源码2.我们的主界面 1.…