FFmpeg rtmp推流直播
文章目录
- rtmp协议
- RTMP协议组成
- RTMP的握手过程
- RTMP流的创建
- RTMP消息格式
- Chunking(Message 分块)
- rtmp服务器搭建
- Nginx服务器
- 配置Nginx服务器
- librtmp库编译
- 推流
rtmp协议
RTMP(Real Time Messaging Protocol)是由Adobe公司基于Flash Player播放器对应的音视频flv封装格式提出的一种,基于TCP的数据传输协议。本身具有稳定、兼容性强、高穿透的特点。常被应用于流媒体直播、点播等场景。常用于推流方(主播)的稳定传输需求。
RTMP协议组成
RTMP协议主要由以下三个部分组成:
- 握手阶段: 在RTMP连接建立之初,客户端与服务器通过握手过程来确认双方的协议版本以及交换随机数等信息,握手成功后,双方将建立起稳定的连接。
- 消息传输: 在握手成功之后,RTMP协议将音视频数据、命令消息等封装成消息进行传输。RTMP协议支持多种消息类型,包括音频、视频、数据消息、命令消息等。为保证消息的有序传输,RTMP还引入了流ID、消息ID等概念来对消息进行管理。
- 块传输: RTMP协议采用分块传输机制来提高传输效率。将消息划分为一系列较小的块(chunks),每个块的大小可配置。这种分块传输机制可以降低延迟,提高实时性。
RTMP协议的工作原理可概括为以下几个步骤:
- 客户端与服务器建立TCP连接
- 双方通过握手过程确认协议版本及交换随机数等信息
- 客户端发送连接命令(connect)到服务器
- 服务器响应连接命令,返回连接结果
- 客户端与服务器建立流(stream)进行音视频数据传输
- 在传输过程中,双方可以发送控制命令,如播放、暂停等
- 当连接关闭时,双方结束消息传输并断开连接
RTMP的握手过程
RTMP流的创建
RTMP消息格式
RTMP数据单元(Message)是RTMP协议中用于封装音频、视频、命令和数据等信息的基本单位。其结构如图所示:RTMP的消息格式都是由消息头和消息体构成。
在RTMP Header中包含三个部分,基本头(Basic Header),消息头(Message Header)和扩展时间戳(Extended TimeStamp)其中消息头和扩展时间戳是可选的。
Basic Header包含了chunk stream ID(流通道id)和chunk type,chunk stream id一般被简写为CSID,用来唯一标识一个特定的流通道,chunk type决定了后面Message Header的格式。Basic Header的长度可能是1,2或4个字节,其中chunk type的长度是固定的(占2位,单位是bit),Basic Header是变长的,其长度取决于CSID的大小,在足够存储这两个字段的前提下,最好用尽量少的字节从而减少由于引入Header增加的数据量。
RTMP协议最多支持65597个用户定义chunk stream ID,范围为[3,65599],ID 0,1,2被协议规范直接使用,其中ID值0,1分别表示了Basic Header占用2个字节和4个字节:
ID值0:代表Basic Header占用2个字节,CSID在 [64,319]之间
ID值1:代表Basic Header占用4个字节,CSID在[64,65599]之间
ID值2:代表chunk是控制信息和一些命令信息
消息头(Message Header) 包含时间戳(TimeStamp),消息长度(MsgLength),消息类型(TypeID)和流ID(SteamID)
它们都是可选的。常用的消息类型如下表所示:
扩展时间戳 是可选的。当时间戳过大,TimeStamp无法表示时才会使用。即TimeStamp 的值为0xFFFFFF
Chunking(Message 分块)
RTMP在收发数据的时候并不是以Message为单位的,而是把Message拆分成Chunk发送,而且必须在一个Chunk发送完成之后才能开始发送下一个Chunk。每个Chunk中带有MessageID(Chunk Stream ID)代表属于哪个Message,接受端也会按照这个id来将chunk组装成Message。
为什么RTMP要将Message拆分成不同的Chunk呢?通过拆分,数据量较大的Message可以被拆分成较小的“Message”,这样就可以避免优先级低的消息持续发送阻塞优先级高的数据,比如在视频的传输过程中,会包括视频帧,音频帧和RTMP控制信息,如果持续发送音频数据或者控制数据的话可能就会造成视频帧的阻塞,然后就会造成看视频时最烦人的卡顿现象。同时对于数据量较大的Message,可以通过对Chunk Header的字段来压缩信息,从而减少信息的传输量。
Chunk的默认大小是128字节,在传输过程中,通过一个叫做Set Chunk Size的控制信息可以设置Chunk数据量的最大值,在发送端和接受端会各自维护一个Chunk Size(srs流媒体服务器默认是60000),可以分别设置这个值来改变这一方发送的Chunk的最大值。大一点的Chunk减少了计算每个chunk的时间从而减少了CPU的占用率,但是它会占用更多的时间在发送上,尤其是在低带宽的网络情况下,很可能会阻塞后面更重要信息的传输。小一点的Chunk可以减少这种阻塞问题,但小的Chunk会引起过多额外的信息(Chunk中的Header),少量多次的传输也可能会造成发送的间断导致不能充分利用高带宽的优势,因此并不适合在高比特率的流中传输。在实际发送时应对要发送的数据用不同的Chunk Size去尝试,通过抓包分析等手段得出合适的Chunk大小,并且在传输过程中可以根据当前的带宽信息和实际信息的大小动态调Chunk的大小,从而尽量提高CPU的利用率并减少信息的阻塞机率。
rtmp服务器搭建
Nginx服务器
Nginx(engine x)是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·塞索耶夫为俄罗斯访问量第二的Rambler.ru站点开发的,第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、简单的配置文件和低系统资源的消耗而闻名。2011年6月1日,nignx 1.0.4发布。
其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
Nginx是高性能的HTTP和反向代理的web服务器,处理高并发能力是十分强大的,能经受高负载的考验,有报告表明能支持高达50,000个并发连接数。
Nginx支持热部署,启动简单,可以做到7*24小时不间断运行,几个月都不需要重新启动。
Windows平台下要使用特殊的Nginx版本:
Nginx服务器下载地址:http://nginx-win.ecsds.eu/download/ 选择nginx 1.7.11.3 Gryphon.zip下载
想要推拉流还需要下载一个rtmp模块
Nginx的rtmp模块下载地址:https://github.com/arut/nginx-rtmp-module/
配置Nginx服务器
- 解压Nginx的压缩包并打开
- 将下载好的rtmp模块解压,放到该目录下
- 进入conf目录,打开Nginx配置文件nginx-win.conf
4.在该文件中添加如下内容
rtmp {server {listen 1935;#监听端口,若被占用,可以更改chunk_size 4000;#上传flv文件块儿的大小application live { #创建一个叫live的应用live on;#开启live的应用allow publish 127.0.0.1;#allow play all;}}
}
5. 启动Nginx服务器
进入Nginx.exe所在目录
6. 使用命令行打开
常用命令如下
nginx.exe -c conf\nginx-win.conf
nginx.exe -s stop //快速终止服务器,可能不保存相关信息
nginx.exe -s quit //完整有序停止服务器,保存相关信息
nginx.exe -s reload //重新载入Nginx,当配置信息修改,需要重新载入这些配置时使用此命令
执行后有个光标在那闪,nginx就启动成功了
7. 测试服务器是否是正常的
拉流
打开电脑上的vlc,没有的话去下载一个
点媒体>网络串流
输入网络填 rtmp://127.0.0.1/live/room
推流
8. 打开电脑上的obs,没有的话去下载一个
9. 点左下角+添加场景,然后点中间的+点显示器采集,点确定,选择主显示器。点确定
10. 点设置>直播>服务>自定义
11. 直播成功
librtmp库编译
librtmp库编译
推流
flv构成在框架简介那篇有介绍
推流代码用vs2022跑的,代替了obs的工作
#define _CRT_SECURE_NO_WARNINGS#include <iostream>
#include <WinSock2.h>
extern "C" {
#include <rtmp.h>
}
#pragma comment(lib, "ws2_32.lib")bool openFLV(CONST char* filename, FILE** file)//打开FLV文件
{*file = fopen(filename, "rb");//打开文件if (!*file){std::cout << "打开文件失败" << std::endl;return false;}fseek(*file, 9, SEEK_SET);//跳过FLV头fseek(*file, 4, SEEK_CUR);//跳过PreviousTagSize,定位到当前Tagreturn true;
}
int readFLV(FILE* file, RTMPPacket** packet)
{char tag[11] = "";if (fread(tag, 1, 11, file) != 11)//读取11个字节return 0;uint32_t dataSize = (tag[1] << 16 & 0xFF0000) | (tag[2] << 8 & 0xFF00) | (tag[3] & 0xFF);;//获取数据大小if (tag[0] != 0x08 && tag[0] != 0x09)//判断是否是音频或视频Tag{fseek(file, dataSize + 4, SEEK_CUR);//跳过当前Tag,和下一个PreviousTagSize,定位到下一个Tagreturn 2;}int ret = fread((*packet)->m_body, 1, dataSize, file);//读取数据if (ret != dataSize)//判断是否读取成功return 0;(*packet)->m_headerType = RTMP_PACKET_SIZE_LARGE;//设置包大小(*packet)->m_nBodySize = dataSize;//设置包大小uint32_t timestamp = (tag[4] << 16 & 0xFF0000) | (tag[5] << 8 & 0xFF00) | (tag[6] & 0xFF);//获取时间戳(*packet)->m_nTimeStamp = timestamp;//设置时间戳(*packet)->m_packetType = tag[0];//设置包类型std::cout << "read " << dataSize << " bytes, timestamp: " << timestamp << std::endl;fseek(file, 4, SEEK_CUR);//跳过PreviousTagSizereturn 1;
}int main()
{WSADATA wsaData;if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)return -1;RTMP* r = RTMP_Alloc();//分配内存RTMP_Init(r);//初始化RTMP_SetupURL(r, (char*)"rtmp://localhost/live/stream");//设置URL RTMP_EnableWrite(r);//启用写权限if (!RTMP_Connect(r, NULL) || !RTMP_ConnectStream(r, 0))//连接return -1;RTMPPacket* packet = new RTMPPacket;//分配内存RTMPPacket_Alloc(packet, 1024 * 1024);//分配内存RTMPPacket_Reset(packet);//重置packet->m_hasAbsTimestamp = 0;//设置时间戳packet->m_nChannel = 0x04;//设置通道packet->m_nInfoField2 = r->m_stream_id;//设置流IDFILE* file;if (!openFLV("source/video-60fps.flv", &file))//打开FLV文件return -1;int ret = 0;uint32_t ts = 0;while (true){ret = readFLV(file, &packet);//读取FLV文件if (ret == 0)//读取失败break;if (ret == 2)//读取成功,但不是音频或视频Tagcontinue;if (!RTMP_IsConnected(r))//判断是否连接成功break;if (ts < packet->m_nTimeStamp)//判断是否需要等待Sleep(packet->m_nTimeStamp - ts);if (!RTMP_SendPacket(r, packet, true))//发送包break;ts = packet->m_nTimeStamp;//更新时间戳}std::cout << "推流结束" << std::endl;fclose(file);//关闭文件RTMPPacket_Free(packet);//释放内存RTMP_Close(r);//关闭连接RTMP_Free(r);//释放内存WSACleanup();//清理return 0;
}
}
测试
1.启动nignx
2.打开vlc,配置上面代码中设置的url地址
3. 运行上面写的代码
相关文章:
FFmpeg rtmp推流直播
文章目录 rtmp协议RTMP协议组成RTMP的握手过程RTMP流的创建RTMP消息格式Chunking(Message 分块) rtmp服务器搭建Nginx服务器配置Nginx服务器 librtmp库编译推流 rtmp协议 RTMP(Real Time Messaging Protocol)是由Adobe公司基于Flash Player播放器对应的…...
北京门头沟区房屋轮廓shp的arcgis数据建筑物轮廓无偏移坐标测评
在IT行业中,地理信息系统(GIS)是用于处理、分析和展示地理空间数据的重要工具,而ArcGIS则是GIS领域中的一款知名软件。本文将详细解析标题和描述中提及的知识点,并结合“门头沟区建筑物数据”这一标签,深入…...
Verilog基础(一):基础元素
verilog基础 我先说,看了肯定会忘,但是重要的是这个过程,我们知道了概念,知道了以后在哪里查询。语法都是术,通用的概念是术。所以如果你有相关的软件编程经验,那么其实开启这个学习之旅,你会感…...
Games104——游戏引擎Gameplay玩法系统:基础AI
这里写目录标题 寻路/导航系统NavigationWalkable AreaWaypoint NetworkGridNavigation Mesh(寻路网格)Sparse Voxel Octree Path FindingDijkstra Algorithm迪杰斯特拉算法A Star(A*算法) Path Smoothing Steering系统Crowd Simu…...
vue生命周期及其作用
vue生命周期及其作用 1. 生命周期总览 2. beforeCreate 我们在new Vue()时,初始化一个Vue空的实例对象,此时对象身上只有默认的声明周期函数和事件,此时data,methods都未被初始化 3. created 此时,已经完成数据观测࿰…...
数据分析师使用Kutools for Excel 插件
数据分析师使用Kutools for Excel 插件 Kutools for Excel 是一款功能强大的 Excel 插件,旨在提高 Excel 用户的工作效率,简化复杂的操作。它提供了超过 300 个增强功能,帮助用户快速完成数据管理、格式化、排序、分析等任务,特别…...
毫秒级响应的VoIP中的系统组合推荐
在高并发、低延迟、毫秒级响应的 VoIP 场景中,选择合适的操作系统组合至关重要。以下是针对 Ubuntu linux-lowlatency、CentOS Stream kernel-rt 和 Debian 自定义 PREEMPT_RT 的详细对比及推荐: 1. 系统组合对比 特性Ubuntu linux-lowlatencyCentO…...
unordered_map/set的哈希封装
【C笔记】unordered_map/set的哈希封装 🔥个人主页:大白的编程日记 🔥专栏:C笔记 文章目录 【C笔记】unordered_map/set的哈希封装前言一. 源码及框架分析二.迭代器三.operator[]四.使用哈希表封装unordered_map/set后言 前言 哈…...
表格标签的使用
一.表格标签 1.1表格标签的作用 用来显示和展示数据,不是用来布局页面的。 1.2表格的基本语法 <table> //用于定义表格标签 <tr> // table row 用于定义表格中的行,必须嵌套在<table> </table>标签中 <td>单元格内的文…...
python算法和数据结构刷题[5]:动态规划
动态规划(Dynamic Programming, DP)是一种算法思想,用于解决具有最优子结构的问题。它通过将大问题分解为小问题,并找到这些小问题的最优解,从而得到整个问题的最优解。动态规划与分治法相似,但区别在于动态…...
【cocos creator】【模拟经营】餐厅经营demo
下载:【cocos creator】模拟经营餐厅经营...
编程AI深度实战:给vim装上AI
系列文章: 编程AI深度实战:私有模型deep seek r1,必会ollama-CSDN博客 编程AI深度实战:自己的AI,必会LangChain-CSDN博客 编程AI深度实战:给vim装上AI-CSDN博客 编程AI深度实战:火的编程AI&…...
信息学奥赛一本通 2088:【22CSPJ普及组】逻辑表达式(expr) | 洛谷 P8815 [CSP-J 2022] 逻辑表达式
【题目链接】 ybt 2088:【22CSPJ普及组】逻辑表达式(expr) 洛谷 P8815 [CSP-J 2022] 逻辑表达式 【题目考点】 1. 表达式树:中缀表达式建树 可以看该问题信息学奥赛一本通 1356:计算(calc) 了解中缀表达式建树过程。 【解题思路】 解法…...
Linux系统管理
文章目录 一、进程与服务二、systemctl基本语法操作 三、系统运行级别Linux进程运行级别查看当前运行级别修改当前运行级别 四、关机重启命令 一、进程与服务 守护进程与服务是一个东西。 二、systemctl 基本语法 systemctl start|stop|restart|status 服务名查看服务的方法…...
CTFSHOW-WEB入门-命令执行71-77
题目:web 71 题目:解题思路:分析可知highlight_file() 函数被禁了,先想办法看看根目录:cvar_export(scandir(dirname(‘/’))); 尝试一下发现很惊奇:(全是?)这种情况我也…...
[MRCTF2020]Ez_bypass1(md5绕过)
[MRCTF2020]Ez_bypass1(md5绕过) 这道题就是要绕过md5强类型比较,但是本身又不相等: md5无法处理数组,如果传入的是数组进行md5加密,会直接放回NULL,两个NuLL相比较会等于true; 所以?id[]1&gg…...
PPT演示设置:插入音频同步切换播放时长计算
PPT中插入音频&同步切换&放时长计算 一、 插入音频及音频设置二、设置页面切换和音频同步三、播放时长计算四、使用宏设置设置页面切换和音频同步一、 插入音频及音频设置 1.插入音频:点击菜单栏插入-音频-选择PC上的音频(已存在的音频)或者录制音频(现场录制) …...
Modbus Slave RTU 在 AVP28335(兼容德州仪器TMS 320 28335) 上实现含源码及注释。
今天先把题目先给出来, 在近两天会把源码 (含详细注释 )及部署、测试结果给出来, 希望能给大家帮助。(原来这个程序在CSDN中,有小伙伴已经写了一些,但是发现里面埋了很多坑,例如&…...
git-secret 使用教程
以下是一份详细的 git-secret 使用教程,包含常见场景的 Bash 代码示例: 1. 安装 git-secret # Ubuntu/Debian sudo apt-get install git-secret# macOS (Homebrew) brew install git-secret# 其他 Linux (Snap) sudo snap install git-secret# 验证安装…...
防火墙安全策略
目录 一.拓扑及需求 二.需求分析 三.配置详细信息 防火墙: OA server: Web Server: PC1: 编辑PC2: PC3: 配置安全区域: 交换机: 四.需求实现以及测试: 1.…...
蓝桥杯python基础算法(2-2)——基础算法(D)——进制转换*
目录 五、进制转换 十进制转任意进制,任意进制转十进制 例题 P1230 进制转换 作业 P2095 进制转化 作业 P2489 进制 五、进制转换 十进制转任意进制,任意进制转十进制 int_to_char "0123456789ABCDEF" def Ten_to_K(k, x):answer "…...
VSCode源码分析参考资料
VSCode Architecture Analysis - Electron Project Cross-Platform Best Practices 中文版 VSCode 架构分析 - Electron 项目跨平台最佳实践 Sihan Li博客上的vscode源码分析系列:分析了微服务架构、事件体系、资源管理、配置系统等 文召博客上的vscode 源码解析…...
深入理解 Rust 模块中的路径与公开性:绝对路径、相对路径和 `pub` 的应用
1. 路径的两种形式:绝对路径与相对路径 在 Rust 中,路径类似于文件系统中的目录路径,用来告诉编译器去哪里查找某个项。路径主要有两种形式: 绝对路径 绝对路径从 crate 的根开始。对于当前 crate 的代码,绝对路径以关…...
DeepSeek R1 大模型本地部署指南
以下是部署DeepSeek R1大模型的详细Markdown指南,可直接保存为.md文件并分享: # DeepSeek R1 大模型本地部署指南**适用系统**:Windows 10/11 & Linux (Ubuntu 20.04)---## 目录 1. [硬件要求](#硬件要求) 2. [准备工作](#准备工作) 3. […...
从Proxmox VE开始:安装与配置指南
前言 Proxmox Virtual Environment (Proxmox VE) 是一个开源的虚拟化平台,基于Debian Linux,支持KVM虚拟机和LXC容器。它提供了一个强大的Web管理界面,方便用户管理虚拟机、存储、网络等资源。Proxmox VE广泛应用于企业级虚拟化、云计算和开…...
Docker 安装详细教程(适用于CentOS 7 系统)
目录 步骤如下: 1. 卸载旧版 Docker 2. 配置 Docker 的 YUM 仓库 3. 安装 Docker 4. 启动 Docker 并验证安装 5. 配置 Docker 镜像加速 总结 前言 Docker 分为 CE 和 EE 两大版本。CE即社区版(免费,支持周期7个月)…...
前端 | 浅拷贝深拷贝
在前端开发中,我们经常需要复制对象或数组,但不同的复制方式可能会影响数据的完整性和应用的稳定性。本文将深入探讨浅拷贝(Shallow Copy)和深拷贝(Deep Copy)的区别、实现方式及适用场景。 1. 浅拷贝 1.…...
巧用 Cursor+Coze,轻松简化小程序开发
一、为啥要用 Cursor+Coze 简化小程序开发 家人们,如今小程序简直火出圈啦!不管你是电商从业者,还是服务行业的工作者,又或是自媒体运营者,拥有一个小程序,就相当于给业务插上了腾飞的翅膀,能带来更多的流量和机会。但是,小程序开发的过程,那可真是充满了挑战。从最开…...
Spring Boot常用注解深度解析:从入门到精通
今天,这篇文章带你将深入理解Spring Boot中30常用注解,通过代码示例和关系图,帮助你彻底掌握Spring核心注解的使用场景和内在联系。 一、启动类与核心注解 1.1 SpringBootApplication 组合注解: SpringBootApplication Confi…...
解决Mac安装软件的“已损坏,无法打开。 您应该将它移到废纸篓”问题
mac安装软件时,如果出现这个问题,其实很简单 首先打开终端,输入下面的命令 sudo xattr -r -d com.apple.quarantine 输入完成后,先不要回车,点击访达--应用程序--找到你无法打开的app图标,拖到终端窗口中…...
爱普生L3153打印机无线连接配置流程
家里使用的是移动宽带中兴路由器,有WPS功能,进入192.168.1.1管理员页面,用户名user,密码在路由器背面(可以登录后修改密码)。在网络-WLAN网络配置-WPS中,点击push button,激活路由器…...
第二十章 存储函数
目录 一、概述 二、语法 三、示例 一、概述 前面章节中,我们详细讲解了MySQL中的存储过程,掌握了存储过程之后,学习存储函数则肥仓简单,存储函数其实是一种特殊的存储过程,也就是有返回值的存储过程。存储函数的参数…...
pytorch实现门控循环单元 (GRU)
人工智能例子汇总:AI常见的算法和例子-CSDN博客 特性GRULSTM计算效率更快,参数更少相对较慢,参数更多结构复杂度只有两个门(更新门和重置门)三个门(输入门、遗忘门、输出门)处理长时依赖一般适…...
unity报错不存在类型或者命名空间
导入资源或者打开项目时,突然发现多了一堆报错,如 Assets\2DGamekit\Utilities\DefaultPlayables\ScreenFader\ScreenFaderBehaviour.cs(5,19): error CS0234: The type or namespace name UI does not exist in the namespace UnityEngine (are you mi…...
Qt展厅播放器/多媒体播放器/中控播放器/帧同步播放器/硬解播放器/监控播放器
一、前言说明 音视频开发除了应用在安防监控、视频网站、各种流媒体app开发之外,还有一个小众的市场,那就是多媒体展厅场景,这个场景目前处于垄断地位的软件是HirenderS3,做的非常早而且非常全面,都是通用的需求&…...
Spring Bean 的生命周期介绍
Spring Bean 的生命周期涉及多个阶段,从实例化到销毁,在开发中我们可以通过各种接口和注解介入这些阶段来定制化自己的功能。以下是详细的生命周期流程: 1. Bean 的实例化(Instantiation) 方式:通过构造函…...
奥卡姆剃刀原理:用简单的力量,解锁复杂的世界
奥卡姆剃刀原理 大名鼎鼎的奥卡姆剃刀原理(Occam’s Razor),其含义很简单,就一句话:“如无必要,勿增实体”。 这句看似简单却蕴含着深刻智慧的话,是由14世纪的英格兰逻辑学家、圣方济各会修士…...
STM32 串口发送与接收
接线图 代码配置 根据上一章发送的代码配置,在GPIO配置的基础上需要再配置PA10引脚做RX接收,引脚模式可以选择浮空输入或者上拉输入,在USART配置串口模式里加上RX模式。 配置中断 //配置中断 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE…...
如何生成强密码:提高网络安全性的全面指南
引言 在数字化时代,密码的安全性至关重要。随着我们在社交媒体、电子邮件、在线银行等平台上储存越来越多的个人信息,强密码的使用变得更加关键。强密码能有效防止暴力破解、字典攻击等安全威胁。因此,在本文中,我们将深入探讨如…...
如何不更新application.yml而更新spring的配置
更改应用程序外部属性的位置 默认情况下,来自不同来源的属性会按定义的顺序添加到 Spring 中(有关确切顺序,请参阅“Spring Boot 功能”部分中的“外部化配置”)。Environment 您还可以提供以下系统属性(或环境变量&…...
【Unity踩坑】Unity项目管理员权限问题(Unity is running as administrator )
问题描述: 使用Unity Hub打开或新建项目时会有下面的提示。 解决方法: 打开“本地安全策略”: 在Windows搜索栏中输入secpol.msc并回车,或者从“运行”对话框(Win R,然后输入secpol.msc)启…...
【JavaScript】《JavaScript高级程序设计 (第4版) 》笔记-Chapter1-什么是 JavaScript
一、什么是 JavaScript 虽然 JavaScript 和 ECMAScript(发音为“ek-ma-script”) 基本上是同义词,但 JavaScript 远远不限于 ECMA-262 所定义的那样。没错,完整的 JavaScript 实现包含以下几个部分。 核心(ECMAScript&…...
队列 + 宽搜(4题)
目录 1.n叉树的层序遍历 2.二叉树的锯齿形层序遍历 3.二叉树的最大宽度 4.在每个树行中找最大值 1.n叉树的层序遍历 429. N 叉树的层序遍历 - 力扣(LeetCode) 我们只需要把某个节点出队的时候把它的孩子节点添加进来即可。 出队的次数就是最开始队列…...
二、面向对象
一、结构体类型 结构体类型是一种自定义类型,用于创建我们游戏或者实际业务中的自定义类型. 代码中变量有通用的,可以使用结构体,包裹起来。 1、成员变量 /// <summary> /// 英雄结构体 /// </summary> struct Hero {//成员p…...
【DeepSeek背后的技术】系列二:大模型知识蒸馏(Knowledge Distillation)
目录 1 引言2 操作步骤和公式说明2.1 准备教师模型(Teacher Model)和学生模型(Student Model)2.2 生成软标签(Soft Labels)2.3 定义蒸馏损失函数2.4 训练学生模型2.5 调整超参数2.6 评估与部署 3 其他知识蒸…...
PyQt4学习笔记2】QMainWindow
目录 一、创建 QMainWindow 组件 1. 创建工具栏 2. 创建停靠窗口 3. 设置状态栏 4. 设置中央窗口部件 二、QMainWindow 的主要方法 1. addToolBar() 2. addDockWidget() 3. setStatusBar() 4. setCentralWidget() 5. menuBar() 6. saveState() 和 restoreState() 三、QMainWind…...
《海丰县蔡氏简介》前言
《海丰县蔡氏简介》前言 蔡惠进主编 汕尾市海陆丰蔡姓祖先基本是福建人, 在宋朝时迁至海丰, 因受潮汕文化、 客家文化、 广府文化、 政治归属等系列因素影响, 形成了闽南人一 种新的文化, 既有传统的闽南文化, 又有潮汕…...
深入探索Vue 3组合式API
深入探索Vue 3组合式API 深入探索Vue 3组合式API一、组合式API诞生背景1.1 Options API的局限性1.2 设计目标二、核心概念解析2.1 setup() 函数:组合式API的基石2.2 响应式系统:重新定义数据驱动2.3 生命周期:全新的接入方式2.4 响应式原理探…...
获取 ARM Cortex - M 系列处理器中 PRIMASK 寄存器的值
第一种实现(纯汇编形式) __ASM uint32_t __get_PRIMASK(void) {mrs r0, primaskbx lr }代码分析 __ASM 关键字:这通常是特定编译器(如 ARM GCC 等)用于嵌入汇编代码的指示符。它告诉编译器下面的代码是汇编代码。mrs …...
使用deepseek写一个单击,双击和长按的检测函数
DeepSeek好火,注册试用一下,感觉和chatgpt o1差别不大,唯一的问题就是追多几次就崩溃了,再问不下去了。以下是测试结果。 提问: 请使用c语言写一个函数,输入参数是是为: A为当前的输入量&am…...