当前位置: 首页 > news >正文

nginx-rtmp-module 支持 Enhancing RTMP HEVC(H.265)

  Enhancing RTMP, FLV 2023年7月31号正式发布,主要支持了HEVC(H.265)、VP9、AV1视频编码,发布差不多半年了,很多开源项目已支持,最近打算播放和推送端也支持下,想找个支持的rtmp server方便测试用,但没找到合适的。干脆自己改改nginx-rtmp-module代码,做个基本的支持,能正常推送和播放Enhancing RTMP H265就好。

  Enhancing RTMP细节直接看标准文档,网上能下载到,关键信息就几页,  看起来也快,这里就不再重复说细节了,直接贴下我改的nginx-rtmp-module代码:

/**
** ngx_rtmp_codec_module.h
** 这个文件要改,修改的地方我加了注释,方便参考,问题沟通qq:1130758427, 微信:ldxevt
**//** Copyright (C) Roman Arutyunyan*/#ifndef _NGX_RTMP_CODEC_H_INCLUDED_
#define _NGX_RTMP_CODEC_H_INCLUDED_#include <ngx_config.h>
#include <ngx_core.h>
#include "ngx_rtmp.h"/* Audio codecs */
enum {/* Uncompressed codec id is actually 0,* but we use another value for consistency */NGX_RTMP_AUDIO_UNCOMPRESSED     = 16,NGX_RTMP_AUDIO_ADPCM            = 1,NGX_RTMP_AUDIO_MP3              = 2,NGX_RTMP_AUDIO_LINEAR_LE        = 3,NGX_RTMP_AUDIO_NELLY16          = 4,NGX_RTMP_AUDIO_NELLY8           = 5,NGX_RTMP_AUDIO_NELLY            = 6,NGX_RTMP_AUDIO_G711A            = 7,NGX_RTMP_AUDIO_G711U            = 8,NGX_RTMP_AUDIO_AAC              = 10,NGX_RTMP_AUDIO_SPEEX            = 11,NGX_RTMP_AUDIO_MP3_8            = 14,NGX_RTMP_AUDIO_DEVSPEC          = 15,
};/* Video codecs */
enum {NGX_RTMP_VIDEO_JPEG             = 1,NGX_RTMP_VIDEO_SORENSON_H263    = 2,NGX_RTMP_VIDEO_SCREEN           = 3,NGX_RTMP_VIDEO_ON2_VP6          = 4,NGX_RTMP_VIDEO_ON2_VP6_ALPHA    = 5,NGX_RTMP_VIDEO_SCREEN2          = 6,NGX_RTMP_VIDEO_H264             = 7,
};/**********************************************/
/***下面是Enhancing RTMP加的, 2024-01-25****/#define FLV_EX_VIDEO_HEADER_MASK (0x80)
#define FLV_EX_VIDEO_FRAME_TYPE_MASK (0x70)
#define FLV_EX_VIDEO_PACKET_TYPE_MASK (0xf)enum {FLV_EX_VIDEO_PACKET_TYPE_SEQUENCE_START = 0,FLV_EX_VIDEO_PACKET_TYPE_CODED_FRAMES = 1,FLV_EX_VIDEO_PACKET_TYPE_SEQUENCE_END = 2,FLV_EX_VIDEO_PACKET_TYPE_CODED_FRAMESX = 3,FLV_EX_VIDEO_PACKET_TYPE_META_DATA = 4,FLV_EX_VIDEO_PACKET_TYPE_MPEG2TS_SEQUENCE_START = 5,
};#define FLV_EX_VIDEO_FOURCC_AV1 NT_MAKE_FOURCC('a', 'v', '0', '1')
#define FLV_EX_VIDEO_FOURCC_VP9 NT_MAKE_FOURCC('v', 'p', '0', '9')
#define FLV_EX_VIDEO_FOURCC_HEVC NT_MAKE_FOURCC('h', 'v', 'c', '1')static ngx_inline ngx_int_t 
ngx_rtmp_get_ex_video_packet_type(ngx_chain_t *in) {return in->buf->pos[0] & FLV_EX_VIDEO_PACKET_TYPE_MASK;
}static ngx_inline ngx_int_t 
ngx_rtmp_is_ex_video_codec_header(ngx_chain_t *in) {return FLV_EX_VIDEO_PACKET_TYPE_SEQUENCE_START == ngx_rtmp_get_ex_video_packet_type(in);
}static ngx_inline ngx_int_t
ngx_rtmp_get_ex_video_frame_type(ngx_chain_t *in) {const uint8_t v = in->buf->pos[0];const uint8_t packet_type = v&FLV_EX_VIDEO_PACKET_TYPE_MASK;if (FLV_EX_VIDEO_PACKET_TYPE_META_DATA == packet_type)return 0;return (v&FLV_EX_VIDEO_FRAME_TYPE_MASK) >> 4;
}/***上面是Enhancing RTMP加的, 2024-01-25****/
/**********************************************/u_char * ngx_rtmp_get_audio_codec_name(ngx_uint_t id);
u_char * ngx_rtmp_get_video_codec_name(ngx_uint_t id);typedef struct {ngx_uint_t                  width;ngx_uint_t                  height;ngx_uint_t                  duration;ngx_uint_t                  frame_rate;ngx_uint_t                  video_data_rate;ngx_uint_t                  video_codec_id;ngx_uint_t                  audio_data_rate;ngx_uint_t                  audio_codec_id;ngx_uint_t                  aac_profile;ngx_uint_t                  aac_chan_conf;ngx_uint_t                  aac_sbr;ngx_uint_t                  aac_ps;ngx_uint_t                  avc_profile;ngx_uint_t                  avc_compat;ngx_uint_t                  avc_level;ngx_uint_t                  avc_nal_bytes;ngx_uint_t                  avc_ref_frames;ngx_uint_t                  sample_rate;    /* 5512, 11025, 22050, 44100 */ngx_uint_t                  sample_size;    /* 1=8bit, 2=16bit */ngx_uint_t                  audio_channels; /* 1, 2 */u_char                      profile[32];u_char                      level[32];ngx_chain_t				   *hevc_header; /*这里HEVC Enhancing RTMP 2024-01-25*/ngx_chain_t                *avc_header;ngx_chain_t                *aac_header;ngx_chain_t                *meta;ngx_uint_t                  meta_version;
} ngx_rtmp_codec_ctx_t;extern ngx_module_t  ngx_rtmp_codec_module;#endif /* _NGX_RTMP_LIVE_H_INCLUDED_ *//***** ngx_rtmp_codec_module.h 文件结束****//**
** ngx_rtmp_codec_module.c
** 这个文件代码较多,就贴下改过的地方,问题沟通qq:1130758427, 微信:ldxevt
**//** Copyright (C) Roman Arutyunyan*/static ngx_int_t
ngx_rtmp_codec_disconnect(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,ngx_chain_t *in)
{ngx_rtmp_codec_ctx_t               *ctx;ngx_rtmp_core_srv_conf_t           *cscf;ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module);if (ctx == NULL) {return NGX_OK;}cscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_core_module);/*** Enhancing RTMP 修改 2024-01-25***/if (ctx->hevc_header) {ngx_rtmp_free_shared_chain(cscf, ctx->hevc_header);ctx->hevc_header = NULL;}if (ctx->avc_header) {ngx_rtmp_free_shared_chain(cscf, ctx->avc_header);ctx->avc_header = NULL;}if (ctx->aac_header) {ngx_rtmp_free_shared_chain(cscf, ctx->aac_header);ctx->aac_header = NULL;}if (ctx->meta) {ngx_rtmp_free_shared_chain(cscf, ctx->meta);ctx->meta = NULL;}return NGX_OK;
}static ngx_int_t
ngx_rtmp_codec_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,ngx_chain_t *in)
{ngx_rtmp_core_srv_conf_t           *cscf;ngx_rtmp_codec_ctx_t               *ctx;ngx_chain_t                       **header;uint8_t                             fmt;ngx_int_t							is_ex_video_header; /*Enhancing RTMP 2024-01-25*/static ngx_uint_t                   sample_rates[] ={ 5512, 11025, 22050, 44100 };if (h->type != NGX_RTMP_MSG_AUDIO && h->type != NGX_RTMP_MSG_VIDEO) {return NGX_OK;}ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module);if (ctx == NULL) {ctx = ngx_pcalloc(s->connection->pool, sizeof(ngx_rtmp_codec_ctx_t));ngx_rtmp_set_ctx(s, ctx, ngx_rtmp_codec_module);}/* save codec */if (in->buf->last - in->buf->pos < 1) {return NGX_OK;}fmt = in->buf->pos[0];if (h->type == NGX_RTMP_MSG_AUDIO) {is_ex_video_header = 0; /*Enhancing RTMP 2024-01-25*/ctx->audio_codec_id = (fmt & 0xf0) >> 4;ctx->audio_channels = (fmt & 0x01) + 1;ctx->sample_size = (fmt & 0x02) ? 2 : 1;if (ctx->sample_rate == 0) {ctx->sample_rate = sample_rates[(fmt & 0x0c) >> 2];}} else {/*Enhancing RTMP 2024-01-25*/if (fmt & FLV_EX_VIDEO_HEADER_MASK)is_ex_video_header = 1;else {is_ex_video_header = 0;ctx->video_codec_id = (fmt & 0x0f);}}/*Enhancing RTMP 2024-01-25*/if (!is_ex_video_header) {/* save AVC/AAC header */if (in->buf->last - in->buf->pos < 3) {return NGX_OK;}} else {if (in->buf->last - in->buf->pos < 5)return NGX_OK;const uint8_t* pos = in->buf->pos + 1;ctx->video_codec_id = NT_MAKE_FOURCC(pos[0], pos[1], pos[2], pos[3]);}/*Enhancing RTMP 2024-01-25*//* no conf */if (!is_ex_video_header) {if (!ngx_rtmp_is_codec_header(in))return NGX_OK;} else {if (!ngx_rtmp_is_ex_video_codec_header(in))return NGX_OK;}cscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_core_module);header = NULL;if (h->type == NGX_RTMP_MSG_AUDIO) {if (ctx->audio_codec_id == NGX_RTMP_AUDIO_AAC) {header = &ctx->aac_header;ngx_rtmp_codec_parse_aac_header(s, in);}} else {/*Enhancing RTMP 2024-01-25*/const ngx_uint_t codec_id = ctx->video_codec_id;if (NGX_RTMP_VIDEO_H264 == codec_id) {header = &ctx->avc_header;ngx_rtmp_codec_parse_avc_header(s, in);}else if (FLV_EX_VIDEO_FOURCC_HEVC == codec_id) {header = &ctx->hevc_header;ngx_rtmp_codec_parse_hevc_header(s, in);}else if (FLV_EX_VIDEO_FOURCC_AV1 == codec_id) {}else if (FLV_EX_VIDEO_FOURCC_VP9 == codec_id) {}}if (header == NULL) {return NGX_OK;}if (*header) {ngx_rtmp_free_shared_chain(cscf, *header);}*header = ngx_rtmp_append_shared_bufs(cscf, NULL, in);return NGX_OK;
}u_char *
ngx_rtmp_get_video_codec_name(ngx_uint_t id)
{/*Enhancing RTMP 2024-01-25*/if (FLV_EX_VIDEO_FOURCC_HEVC == id)return (u_char*)"HEVC";else if (FLV_EX_VIDEO_FOURCC_AV1 == id)return (u_char*)"AV1";else if (FLV_EX_VIDEO_FOURCC_VP9 == id)return (u_char*)"VP9";return (u_char *)(id < sizeof(video_codecs) / sizeof(video_codecs[0])? video_codecs[id]: "");
}/***** ngx_rtmp_codec_module.c 文件结束****/

  另外rtmp直播还要修改ngx_rtmp_live_module.c, flv录像支持需修改ngx_rtmp_record_module.c, 支持转hls要修改ngx_rtmp_hls_module.c和ngx_rtmp_mpegts.c,根据实际需求改下代码就好。

  改好重新编译运行,推送播放效果:

  简单改改已经满足我的测试需求, 有问题请联系qq: 1130758427, 微信:ldxevt。

相关文章:

nginx-rtmp-module 支持 Enhancing RTMP HEVC(H.265)

Enhancing RTMP, FLV 2023年7月31号正式发布&#xff0c;主要支持了HEVC(H.265)、VP9、AV1视频编码&#xff0c;发布差不多半年了&#xff0c;很多开源项目已支持&#xff0c;最近打算播放和推送端也支持下&#xff0c;想找个支持的rtmp server方便测试用&#xff0c;但没找到合…...

2024最新JDK1.8+JDK17+JDK21安装包下载+文档

2024年更新&#xff0c;JDK8的64位和32位安装包都有&#xff0c;Java8最新文档也有&#xff0c;JDK17和JDK21的最新安装包也有 因为网上的安装包都不是最新的&#xff0c;所以自己去Oracle官网登录下载保存了一份&#xff0c;需要的朋友下面网盘链接下载 JDK8—64位安装程序&…...

如何利用chatgpt提升工作效率

chatgpt全领域小助手 项目管理&#xff1a;制定项目计划、跟踪进度、分配任务和记录里程碑。客户服务&#xff1a;回答常见问题、提供产品支持和处理客户投诉&#xff0c;提升客户满意度。销售支持&#xff1a;提供销售培训、销售脚本和客户资料&#xff0c;辅助销售团队进行销…...

WinSCP下载安装并实现远程SSH本地服务器上传文件

文章目录 1. 简介2. 软件下载安装&#xff1a;3. SSH链接服务器4. WinSCP使用公网TCP地址链接本地服务器5. WinSCP使用固定公网TCP地址访问服务器 1. 简介 ​ Winscp是一个支持SSH(Secure SHell)的可视化SCP(Secure Copy)文件传输软件&#xff0c;它的主要功能是在本地与远程计…...

QEMU搭建arm虚拟机开发环境

获取QEMU代码 git clone https://gitlab.com/qemu-project/qemu.git 切换对应的工程分支 使用git指令切换到对应的分支上&#xff0c;我这里使用的是stable-4.0的分支 git checkout -b stable-4.0 remotes/origin/stable-4.0 配置&编译 在工程的根目录下执行 ./conf…...

web 应用常见的安全问题

一xss攻击 人们经常将跨站脚本攻击&#xff08;Cross Site Scripting&#xff09;缩写为CSS&#xff0c;但这会与层叠样式表&#xff08;Cascading Style Sheets&#xff0c;CSS&#xff09;的缩写混淆。因此&#xff0c;有人将跨站脚本攻击缩写为XSS。 跨站脚本攻击&#xff…...

502. IPO

502. IPO 题目链接&#xff1a;502. IPO 代码如下&#xff1a; //堆的使用 class Solution { public:int findMaximizedCapital(int k, int w, vector<int>& profits, vector<int>& capital) {vector<pair<int,int>> mp;//优先队列默认的是大…...

如何安装MeterSphere并实现无公网ip远程访问服务管理界面

文章目录 前言1. 安装MeterSphere2. 本地访问MeterSphere3. 安装 cpolar内网穿透软件4. 配置MeterSphere公网访问地址5. 公网远程访问MeterSphere6. 固定MeterSphere公网地址 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学习网站&#xff0c; 通…...

做FP独立站怎么引流?这个引流法宝收好了!

近年来&#xff0c;由于卖家数量飙升导致平台竞争持续升级&#xff0c;卖家之间的恶性循环竞争以及平台政策的不断调整等&#xff0c;造成了众多亚马逊等跨境卖家纷纷从平台转向独立站。可是&#xff0c;转型做独立站前要先考虑清楚独立站与平台二者之间的区别。 如果在第三方平…...

幻兽帕鲁PalWorld服务器搭建教程,1分钟开服,纯小白教程,无需基础

雨云面板服快速开幻兽帕鲁PalWorld服务器的教程&#xff0c;配置文件修改方法和配置项中文注释。 最近这游戏挺火&#xff0c;很多人想跟朋友联机&#xff0c;如果有专用服务器&#xff0c;就不需要房主一直开着电脑&#xff0c;稳定性也好得多。 幻兽帕鲁简介 《幻兽帕鲁》…...

算法小抄01

1. 计数排序是一种基于 统计 的排序算法 2. 基于比较的排序算法有&#xff1a;&#xff08;1&#xff09;直接插入排序&#xff1b;&#xff08;2&#xff09;冒泡排序&#xff1b;&#xff08;3&#xff09;简单选择排序&#xff1b;&#xff08;4&#xff09;希尔排序&#…...

Spring Boot 集成 API 文档 - Swagger、Knife4J、Smart-Doc

文章目录 1.OpenAPI 规范2.Swagger: 接口管理的利器3.Swagger 与 SpringFox&#xff1a;理念与实现4.Swagger 与 Knife4J&#xff1a;增强与创新5.案例&#xff1a;Spring Boot 整合 Swagger35.1 引入 Swagger3 依赖包5.2 优化路径匹配策略兼容 SpringFox5.3 配置 Swagger5.4 S…...

2024年软考报名时间及条件,小白必看

不少考生开始准备报名2024年软件水平考试&#xff0c;那么报名软考有没有学历、专业以及工作经验等方面的限制呢?今天就给大家梳理下2024年软考考试&#xff0c;若有变更&#xff0c;也会及时更新内容。 免费送备考资料。联系我 2024年软考考试时间 2024年软考有两次考试&a…...

vue 跨域XMLHttpRequest

vue 跨域 使用XMLHttpRequest 亲测好使 let url=http://127.0.0.1:9000/pssnotifyyb?b=1//url=https://api.j4u.ink/v1/store/other/proxy/remote/moyu.jsonvar xhr=new XMLHttpRequest()xhr.open(GET,url,true)//第三个参数是是否异步请求,默认true xhr.onreadyst…...

【正点原子STM32】STM32基础知识(F1F4F7H7 STM32系统框架、寻址范围、存储器映射的存储器功能划分、寄存器映射)

一、STM32系统框架 1.1、Cortex M内核 & 芯片1.2、F1系统架构1.3、F4系统架构1.4、F7系统架构1.5、H7系统架构 二、STM32的寻址范围&#xff1f; 三、存储器映射 存储器功能划分&#xff08;F1为例&#xff09;STM32F1存储器映射图 四、寄存器映射 寄存器基础知识STM3…...

Oracle、MySQL数据库常规命令语法-简易记录(非常规持续更新)

前言:呈现的是非常基础必备命令以及常规关联语法,因涉及到不同数据库其表达都会有所区别,此篇纯属做个仓库记录更非常规持续更新,专业人士可忽略,且看且珍惜… MySQL: 关系型数据库、重点开源、支持大型规模、标准SQL数据语言、多平台多架构、高可用集群、可定制开发等等、…...

用react搞定一个大模型对话效果

怎么用react实现一个类似文心一言那样的对话效果呢&#xff1f; 最近AI盛行&#xff0c;关注几个大模型网站都能发现&#xff0c;跟AI对话的时候&#xff0c;返回的文本是逐字展示的&#xff0c;就给人一种AI边解析边返回的感觉&#xff08;不知道是为了装X还是真的需要这样&a…...

DP读书:在常工院的2023年度总结

DarrenPig的年度总结 这是最好的时代&#xff0c;这是最坏的时代。——狄更斯 这是最好的时代&#xff0c;这是最坏的时代。——狄更斯 这是最好的时代&#xff0c;这是最坏的时代。——狄更斯 一、2023我的感受 不就是2023吗&#xff0c;不就是一年的经历吗&#xff0c;大家…...

2023-2024年重庆职业院校技能大赛“信息安全管理与评估”比赛样题

2023 年重庆职业院校技能大赛&#xff08;高等职业教育&#xff09; “信息安全管理与评估”样题任务书 第一阶段&#xff1a;任务 1 网络平台搭建&#xff08;50 分&#xff09;任务 2 网络安全设备配置与防护&#xff08;250 分&#xff09; 第二阶段&#xff1a;第一部分 网…...

【Ubuntu】systemctl 命令

systemctl 是一个用于检视和控制 systemd 系统和服务管理器的命令行工具。systemd 是用于启动、停止和管理 Linux 系统中的服务的守护进程。以下是一些常用的 systemctl 命令及其说明&#xff1a; systemctl start <unit>: 启动指定的服务单元 systemctl start sshd sy…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案

在大数据时代&#xff0c;海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构&#xff0c;在处理大规模数据抓取任务时展现出强大的能力。然而&#xff0c;随着业务规模的不断扩大和数据抓取需求的日益复杂&#xff0c;传统…...

MyBatis中关于缓存的理解

MyBatis缓存 MyBatis系统当中默认定义两级缓存&#xff1a;一级缓存、二级缓存 默认情况下&#xff0c;只有一级缓存开启&#xff08;sqlSession级别的缓存&#xff09;二级缓存需要手动开启配置&#xff0c;需要局域namespace级别的缓存 一级缓存&#xff08;本地缓存&#…...

JDK 17 序列化是怎么回事

如何序列化&#xff1f;其实很简单&#xff0c;就是根据每个类型&#xff0c;用工厂类调用。逐个完成。 没什么漂亮的代码&#xff0c;只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...

Netty自定义协议解析

目录 自定义协议设计 实现消息解码器 实现消息编码器 自定义消息对象 配置ChannelPipeline Netty提供了强大的编解码器抽象基类,这些基类能够帮助开发者快速实现自定义协议的解析。 自定义协议设计 在实现自定义协议解析之前,需要明确协议的具体格式。例如,一个简单的…...