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,一经查实,立即删除!

相关文章

SQL规约

文章目录 前言SQL规约-索引注意字段类型利用覆盖索引利用有序性禁模糊 超过三个表禁止 joinSQL规约-count拒绝替代计算不重复行数当值全是NULL时 SQL规约-分页若 count 为 0优化超多分页场景 SQL规约-null值使用 ISNULL()来判断是否为 NULL 值NULL< >NULLNULLNULLNULL<…

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…

接口-幂等性问题

1.什么是接口的幂等性&#xff1f; 接口的幂等性就是一个接口无论是调用一次还是多次&#xff0c;最后的结果应该是一样的。2.为何需要保证接口的幂等性&#xff1f; 因为服务之间调用&#xff0c;可能存在超时。如果是成功或者失败&#xff0c;那么程序都是正常的。当出现超…

10 在Vue3中使用SCSS编写样式

概述 When using Vue components, the Vite compiler allows you to use almost any frontend templating language style. The easiest way to enable these expressive library plugins in your Vue templates is to install them when you initialize your project, or by …

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

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

条款27:尽量少做转型动作

1.前言 C规则的设计目标之一是保证“类型错误”绝对不可能发生。理论上如果你的程序很顺利的通过编译&#xff0c;就表示它并不企图在任何对象身上执行任何不安全&#xff0c;无意义的操作。这是个极具价值的保证&#xff0c;可别草率的放弃它。 不幸的是&#xff0c;转型&am…

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; 显示的是单位查询…

工作流JBPM笔记:了解JBPM

一、什么是工作流 工作流管理联盟&#xff08;WFMC&#xff09;把工作流定义为&#xff1a;全部或部分由计算机支持或自动处理的业务过程。 工作流管理系统&#xff08;Workflow Management System&#xff0c;WFMS&#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):# 构造只有一个隐含层的…

Qt容器QToolBox工具箱

# QToolBox QToolBox是Qt框架中的一个窗口容器类,常用的几个函数有: ​setCurrentIndex(int index):设置当前显示的页面索引。可以通过调用该函数,将指定索引的页面设置为当前显示的页面。 addItem(QWidget * widget, const QString & text):向QToolBox中添加一个页面…

Flink系列之:分组聚合

Flink系列之&#xff1a;分组聚合 一、DISTINCT 聚合二、GROUPING SETS三、ROLLUP四、CUBE五、HAVING 适用于流、批 像大多数数据系统一样&#xff0c;Apache Flink支持聚合函数&#xff1b;包括内置的和用户定义的。用户自定义函数在使用前必须在目录中注册。 聚合函数把多行…

flutter学习-day10-布局类组件

&#x1f4da; 目录 介绍布局原理和约束盒模型布局 约束容器ConstrainedBox非约束容器UnconstrainedBox 线性布局 行row列column 弹性布局流式布局 WrapFlow 层叠布局对齐和相对定位布局构建回调 LayoutBuilder布局过程中AfterLayout布局完成后执行 本文学习和引用自《Flutte…

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"…

【力扣100】73.矩阵置零

添加链接描述 class Solution:def setZeroes(self, matrix: List[List[int]]) -> None:"""Do not return anything, modify matrix in-place instead."""# 思路是1.记录每一个0元素的行和列下标 2.遍历全数组row_index[]column_index[]mlen(…