Live555核心解析:RTSP/RTP协议栈与流媒体推流实践
做流媒体的同行对 Live555 应该都不陌生这个老牌开源库几乎成了 RTSP/RTP/RTCP 协议栈的代名词。我最早接触它是在做嵌入式监控设备的时候当时要在一个资源很紧的平台上做 RTSP 推流自己从头写协议栈完全不可能最终就是靠 Live555 把链路跑通的。这些年陆陆续续在服务器端和播放器端都和它打过交道踩过不少坑也理清了框架的核心脉络。这篇东西不打算把类文档抄一遍而是按我自己的理解把 Live555 从设计思路到实际使用的关键细节掰开讲清楚。如果你要做的方向和流媒体传输相关比如摄像头 RTSP 推流、播放器拉流、流媒体网关、安防平台接入或者你是刚被分配去维护一套基于 Live555 的项目代码那么这篇内容应该能帮你省下不少弯路。先说结论Live555 本身不负责音视频编码解码它管的是 RTSP 会话控制、RTP 打包发送、RTCP 反馈以及最底层的网络传输调度。很多人一开始没搞明白这一点容易把“推流不出去”或“画面不对”归咎于 Live555实际上问题往往出在编码和 RTP 负载格式的匹配上。1. 先弄清楚 Live555 到底管到哪一层1.1 它在流媒体协议栈中的位置流媒体从采集到显示可以拆成几个层次采集编码H.264/H.265/AAC 等- 封装MP4/FLV 等- 传输控制RTSP/RTMP 等- 网络传输RTP/RTCP over UDP/TCP- 解码渲染。Live555 的覆盖面是从控制层到传输层具体来说它实现了 RTSPRFC 2326后来的 RFC 7826 也兼容、RTP/RTCPRFC 3550 等、SDP 解析和生成以及基于 UDP/TCP 的 RTP 收发。它不包含 H.264 编码器也没有 H.265 解码器更不负责画面渲染。有些刚接触的人会误以为 Live555 是一个“开箱即用的播放器”实际上你还需要把解出来的 H.264 裸流喂给 FFmpeg 或硬件解码器才能看到画面。反过来做推流服务器时你的编码器输出 H.264 的 Annex-B 流Live555 负责把它拆成 NAL 单元、加 RTP 头、按时间戳发出去。这个定位决定了 Live555 的优势和短板。优势是它把 RTSP 状态机和 RTP 打包这些“脏活”做得很完整跨平台性也极好几乎任何有 TCP/UDP 套接字的系统都能编译运行。短板是它本质上是 C 单线程事件驱动模型扩展性要靠自己写 MediaSource 和 Sink 子类代码风格也比较老派现代 C 特性用得少读起来需要一点耐心。1.2 一个请求从客户端到服务器端的旅程理解 Live555 最好的方式是跟着一个 RTSP 请求走一遍。假设客户端想拉取rtsp://ip:8554/live这个地址对应的流完整过程大概是客户端先发 OPTIONS问服务器支持哪些命令服务器返回 PUBLIC 或 ALLOW列出 DESCRIBE、SETUP、PLAY、TEARDOWN 等。客户端发 DESCRIBE带 Accept: application/sdp服务器返回一个 SDP 文本里面描述了媒体类型、编码格式、RTP 负载类型PT、端口信息等。客户端从 SDP 里解析出媒体流信息针对每一个媒体流发 SETUP带上客户端接收 RTP/RTCP 的端口比如Transport: RTP/AVP/UDP;unicast;client_port8000-8001。服务器收到 SETUP 后绑定服务端端口通过 8001 端口周期性发 RTCP SR 报文客户端通过 8000 端口收 RTP。客户端发 PLAY服务器开始发送 RTP 数据包。播放过程中客户端可以发 PAUSE 暂停TEARDOWN 结束会话。这套流程里DESCRIBE 得到的 SDP 是后续 SETUP 的基础而 SETUP 协商的传输参数单播/组播、UDP/TCP、端口号直接影响 RTP 能不能到达客户端。Live555 在这个环节做得比较严如果客户端请求的端口范围不可用服务器会拒绝或改用其他端口这也是排查问题时要留意的地方。2. Live555 的核心对象与代码骨架2.1 事件循环、环境与任务调度Live555 的所有逻辑都跑在一个单线程事件循环里这是理解这个框架最重要的一点。核心类有两个TaskScheduler和UsageEnvironment。TaskScheduler负责定时任务和 socket 事件的调度UsageEnvironment封装错误日志、随机数、系统时间等基础能力。在典型的服务端程序里你会在 main 函数里创建BasicTaskScheduler和BasicUsageEnvironment然后进入env-taskScheduler().doEventLoop()。这个模型有几个直接推论。第一你的回调函数里绝对不能做阻塞操作比如等待锁、sleep、大文件读取一旦阻塞整个服务器的所有会话都会卡住。第二跨线程更新状态要特别小心比如工作线程产生了一帧数据直接调用 Live555 的Sink::sendPacketIfNecessary是不安全的通常需要注册一个Triggerable事件让事件循环线程去取数据。第三内存管理上Live555 大量使用引用计数类如Medium虽然有Medium::close这类全局关闭方法但使用不当容易悬垂。UsageEnvironment的operator重载很有趣你可以直接写env some log \n输出日志这在不同平台的移植上省了很多事。实际项目中如果想接统一的日志系统可以继承UsageEnvironment重写相关虚函数或者简单粗暴地重定向fputs。2.2 服务端的三层结构Live555 服务端最核心的三个类分别是RTSPServer、ServerMediaSession和ServerMediaSubsession。理解它们的从属关系基本就理解了服务端业务怎么组织。RTSPServer管理监听 socket负责接收 TCP 连接、解析 RTSP 请求、维护会话列表。一个服务器可以有多个监听端口最常见的是 8554也可以用 554需要 root。RTSPServer::lookupServerMediaSession用来查找是否有对应的流名如果没有可以注册一个“动态创建”的回调也就是ServerMediaSession的构造函数里传入streamName和创建会话的 lambda旧版本是DynamicRTSPServer子类。ServerMediaSession对应一个流媒体会话比如live它内部包含一个或多个ServerMediaSubsession分别代表视频轨和音频轨。视频轨通常是一个H264VideoFileServerMediaSubsession或你自己实现的动态子会话。ServerMediaSubsession负责为每个客户端创建StreamSource和RTPSink。每个客户端请求同一个ServerMediaSession都会得到独立的RTPSink实例因为 RTP 发送要考虑各自的端口、时间戳基准、SSRC同步源标识符。这个三层结构意味着如果你要扩展自己的协议或媒体格式主要工作是继承ServerMediaSubsession并实现createNewStreamSource和createNewRTPSink虚函数。以摄像头为例createNewStreamSource返回一个把摄像头数据包装成FramedSource的类createNewRTPSink返回对应的H264VideoRTPSink或H265VideoRTPSink。2.3 客户端一侧的请求连接器客户端通常用RTSPClient发送控制命令用MediaSession存储解析后的 SDP 和媒体通道信息用MediaSink子类接收并处理 RTP 流。使用 RTSPClient 的典型模式是发一条命令后在回调里继续发下一条形成状态机。打个比方RTSPClient 像一个电话接线员你告诉它“打电话给某人”它在接通后把话筒交给你你继续说下一句。Live555 把这种连续对话做成回调链条continueAfterDESCRIBE回调里发 SETUPcontinueAfterSETUP回调里发 PLAY。这么多回调写起来确实丑但逻辑清晰每个异步步骤都显式地流程化。如果你要实现一个简单的播放器至少要做三件事发 OPTIONS 探测服务器能力可选发 DESCRIBE 拿 SDP发 SETUP 建立传输发 PLAY 开始拉流。RTP 数据到达后交给下游解码器。这里要注意RTSP 的 SETUP 是逐媒体流进行的多轨流要循环 SETUP 完所有轨道才能 PLAY。3. 从零搭一个 RTSP 推流服务器代码实操3.1 最小服务端代码下面是一个最小可用的 Live555 服务端示例它把本地的test.h264文件当作一个循环播放的 H.264 流通过 RTSP 发布出去。这段代码常被作为项目的起点模板。#include live555/liveMedia.hh #include live555/BasicUsageEnvironment.hh int main(int argc, char** argv) { // 1. 创建环境 TaskScheduler* scheduler BasicTaskScheduler::createNew(); UsageEnvironment* env BasicUsageEnvironment::createNew(*scheduler); // 2. 创建 RTSP 服务监听 8554 端口 RTSPServer* rtspServer RTSPServer::createNew(*env, 8554, NULL); if (rtspServer NULL) { *env Failed to create RTSP server: env-getResultMsg() \n; return -1; } // 3. 创建媒体会话 ServerMediaSession* sms ServerMediaSession::createNew(*env, live, NULL, Session streamed by Live555, True); // True 表示支持循环播放 // 4. 添加 H.264 文件子会话 由文件生成流 sms-addSubsession(H264VideoFileServerMediaSubsession::createNew(*env, test.h264, True)); // 5. 将会话注册到服务器 rtspServer-addServerMediaSession(sms); *env RTSP server started at rtsp://127.0.0.1:8554/live\n; env-taskScheduler().doEventLoop(); return 0; }这段代码看起来简单但每一行背后都有值得注意的点。第一步创建BasicTaskScheduler和BasicUsageEnvironment可以理解成“准备一个发动机和一套仪表盘”。TaskScheduler里有一个DelayQueue所有延迟任务都放在里面事件循环每轮遍历一次。UsageEnvironment则负责输出错误信息。第二步的RTSPServer::createNew第三个参数是reuseAddr一般传 NULL 即可内部会处理SO_REUSEADDR。如果这个参数为 False在某些平台上可能出现“端口被占用但仍能启动”的诡异情况重启时反而不行排查起来很头疼。第三步创建ServerMediaSession最后一个参数True表示允许重复流名存在。通常在你需要支持多个客户端同时拉流时这个参数传 True 是必要的但如果你希望“同一时间只能一个客户端访问”可以传 False后面访问相同流名的会话会失败。第四步比较关键H264VideoFileServerMediaSubsession会按文件里的 H.264 裸流逐帧读取。它知道如何解析 Annex-B 格式中的起始码00 00 00 01 或 00 00 01并把每个 NAL 单元作为一个Frame发送。第二个参数True同样表示支持循环播放即文件播完了重头再播。3.2 动态会话与设备接入的扩展思路上面是基于文件的静态会话实际项目中更多的是动态会话比如摄像头实时流数据源由接收线程或采集线程产生。这时候需要自己写一个FramedSource子类往RTPSink里喂数据。一个常见的做法是继承FramedSource实现doGetNextFrame()。在doGetNextFrame里从自己的环形缓冲区取一帧完整数据拷贝到fTo指向的内存并设置fFrameSize、fPresentationTime、fDurationInMicroseconds。调afterGetting(this)通知 Live555 这一帧处理完了。在ServerMediaSubsession::createNewStreamSource里实例化这个FramedSource子类。创建动态会话时ServerMediaSubsession通常在构造时传入一个Boolean reuseFirstSource参数表示多个客户端是否复用同一个数据源。对摄像头这种单采集源来说多个客户端共享同一个源会更合理否则每个客户端都去打开摄像头驱动会受不了。但复用一个源时要注意不同的RTPSink需要各自维护自己的 RTP 序列号和时间戳Live555 内部会为每个RTPSink独立生成这些所以你只需要保证数据源是线程安全的即可。3.3 H.264 RTP 打包的隐藏细节H.264 的 RTP 打包主要分三种模式单一 NAL 单元、STAP-A聚合包、FU-A分片包。Live555 的H264VideoRTPSink会自动处理当 NAL 单元小于 MTU 时一个包一个 NALRTP 头后面直接跟 NAL 头。当 NAL 单元大于 MTU 时拆成 FU-A 分片每个 RTP 包只承载一个分片最后一个分片的 E 标志置 1。如果开启了STAP-A聚合可以把多个小 NAL如 SPS 和 PPS拼到一个 RTP 包里发出去。这里有一个很常见的坑SPS/PPS 怎么传。在文件流场景下Live555 会把 SPS/PPS 放到 RTP 包的extra data或直接放在视频流前面但在某些场景下解码器必须先拿到 SPS/PPS 才能开始解码如果传输过程中丢了就会出现花屏或黑屏。解决方法有几种在 SDP 中用sprop-parameter-sets携带 SPS/PPS 的 base64 编码或者在关键帧前面周期性带 IDR 的 SPS/PPS。实际项目里我见过不少人忽略了sprop-parameter-sets导致播放器在弱网下收到关键帧但无法解码。再说时间戳。RTP 时间戳的频率对视频一般是 90kHz也就是时间戳每秒增加 90000。Live555 根据帧的呈现时间fPresentationTime来计算 RTP 时间戳。如果你从设备拿到的帧率是 25fps那相邻两帧的时间戳应增加 360090000/25。如果源没提供准确的时间而你自己用gettimeofday累计会导致音视频不同步或播放速率不正确。还有一个容易被忽略但很重要的参数OutPacketBuffer::maxSize。它的默认值在 liveMedia 里通常是 60000 字节也就是一个 RTP 包最大 60KB 左右。对 1080p 或更高分辨率的 H.264 流如果 IDR 帧特别大某些情况下可能超出这个缓冲限制导致发送时被截断。你可以在 main 函数开头调用OutPacketBuffer::increaseMaxSizeTo(200000)来扩大缓冲。4. 客户端拉流要点与 RTSP 状态机4.1 RTSP 请求时序与状态码客户端侧的交互看似简单但错误处理要谨慎。下表整理了 RTSP 常用方法、作用以及处理时的注意事项。方法作用注意事项OPTIONS探测服务器支持哪些方法不是必须的但有助于快速定位协议不兼容DESCRIBE获取 SDP 描述当服务器返回 405 时需要回退处理有些服务器拒绝空未认证的 DESCRIBESETUP协商传输参数每个媒体流都要 SETUP指定端口前要检查可用性PLAY开始发送 RTP响应头里会有 RTP-Info包含起始序号和时间戳对同步很重要PAUSE暂停发送暂停后再 PLAY时间戳会继续增加避免再次送老帧TEARDOWN结束会话正常退出和异常退出都应尽量发送释放服务器资源GET_PARAMETER / SET_PARAMETER一般用于保活很多设备用 GET_PARAMETER 作为心跳发送每条命令时都需要带 CSeq序列号服务器响应的 CSeq 要和请求一致。如果客户端发送命令后长时间没收到响应可能是网络问题也可能是服务器处理线程卡死了这种情况要通过心跳和超时处理来保活。4.2 用 RTSPClient 拉流的关键代码流程实际用RTSPClient拉流时代码结构大致是这样class RTSPClientSession : public RTSPClient { public: static RTSPClientSession* createNew(UsageEnvironment env, char const* rtspURL, int verbosityLevel) { return new RTSPClientSession(env, rtspURL, verbosityLevel); } protected: RTSPClientSession(UsageEnvironment env, char const* rtspURL, int verbosityLevel) : RTSPClient(env, rtspURL, verbosityLevel) {} virtual ~RTSPClientSession() {} };然后你在某个地方调用sendDescribeCommand(continueAfterDESCRIBE)。在continueAfterDESCRIBE里需要从MediaSession拿到描述信息再为每个子会话发 SETUPvoid continueAfterDESCRIBE(RTSPClient* client, int resultCode, char* resultString) { if (resultCode ! 0) { /* 处理错误 */ return; } MediaSession* mediaSession MediaSession::createNew(*env, resultString); MediaSubsessionIterator iter(*mediaSession); MediaSubsession* sub; while ((sub iter.next()) ! NULL) { sub-sink MediaSink::createNew(*env, sub-fmtp_configuration()); // 具体 sink 类型根据 codec 决定比如 H264VideoRTPSink sub-rtpSource MediaSource::createNew(*env, sub-rtpPayloadFormat()); // 发送 SETUP client-sendSetupCommand(*sub, continueAfterSETUP, False, False); } }这里有几个容易出错的地方不要在所有 SETUP 完成前发 PLAY。因为服务器只有在所有媒体轨都 SETUP 后才会真正开始发送数据部分服务器对 PLAY 之前未 SETUP 的轨道直接返回 455 错误。RTSPClient 的回调函数签名是固定的如果希望回调里能访问自定义数据可以把自定义数据塞进继承类或者在send*类函数之前保存上下文。如果只拉视频不拉音频你仍然需要 SETUP 视频轨并且在 PLAY 后接收 RTP 包。但 SDP 里可能包含多个轨道不 SETUP 的轨道会保持不可用状态这样后续 RTCP 或 RTP 会不完整。客户端接收 RTP 数据时MediaSink的afterGettingFrame回调拿到的是去掉 RTP 头之后的应用数据。但要注意RTP 头里的 payload 类型、SSRC、序列号都在RTPSource里如果需要做抖动缓冲或丢包检测需要自行查看RTPPacket信息。5. 常见问题与排查实录5.1 视频花屏、无法解码这个问题在基于 Live555 的项目里排名第一。原因通常是 SPS/PPS 没有正确传给解码器或者 RTP 包乱序严重或者时间戳跳变导致解码参考帧丢失。排查思路用 Wireshark 抓包过滤rtp查看第一帧数据是否包含 SPS/PPS。很多抓包工具能直接解析 H.264 RTP 里的 NAL 类型。检查 SDP 里是否有sprop-parameter-sets。如果没有可以在播放端预先配置 SPS/PPS或者让服务器循环发送带 SPS/PPS 的关键帧。确认解码器是否已经处理了 RTP 的 FU-A 分片重组。如果你在接收端直接把每个 RTP 包当一个 H.264 帧交给解码器遇到大的 IDR 帧分片时会直接失败。实际调试中我发现很多解码器初始化时要求先收到一个 IDR 帧而不是 P 帧。如果拉流端是从流中间接入的可能等了很久才等到下一个 IDR而 RTP 序列号很乱。可以把服务器设置为定期推关键帧如每 2 秒一个 IDR减少接入等待时间。5.2 客户端能连上但流出不来现象是 RTSP 握手都成功客户端也收到 200 OK但收不到 RTP 包。可能原因有几类服务端 UDP 端口未监听或防火墙阻挡。默认动态分配端口时服务端 RTP/RTCP 端口是随机可用的但如果端口范围受限比如云平台安全组只开放了 8554没开 RTP 端口数据就过不来。排查方法在服务端抓包看是否有包发到客户端端口或改用 TCP 传输模式Transport: RTP/AVP/TCP。客户端 UDP 端口未打开。有些播放器默认只监听 TCP或者客户端在 NAT 后面但没有配置端口映射。解法是让客户端先发 SETUP指定本地端口然后保持这些端口可收包。RTCP 报文没处理。少数实现比较脆要求必须收到 RTCP SR 才能同步音视频。如果 RTCP 被防火墙丢弃视频会一直缓冲。检查网络层是否放行 RTCP 端口通常 RTP 端口 1。命令实现中SETUP 请求的Transport参数要和服务器协商一致。如果客户端请求 UDP但服务器只支持 TCP会返回 461 Unsupported Transport。可以预先用 OPTIONS 探测能力或者根据响应回退。5.3 CPU 占用高、延迟大Live555 是单线程模型CPU 高多数时候不是 Live555 本身的问题而是你往事件循环里塞了太多事。比如在doGetNextFrame里做视频格式转换、加解密、磁盘 I/O 等都会阻塞事件循环导致 RTP 发送延迟。解决方案是让重活在其他线程做只在 Live555 线程里做“取帧并发送”的轻量操作。数据源可以采用双缓冲或者环形缓冲生产者线程写消费者线程Live555按需读。需要注意的是多个 RTPSink 复用一个FramedSource时Live555 通过引用来保证源只被读取一次但如果你在多个线程里同时触发读取需要自己加锁。延迟方面网络抖动是一个因素但更常见的是缓冲策略。Live555 发送端的RTPTransmissionStatsDB会记录丢包率但不是实时的播放端的接收缓冲如果太大延迟会明显上升。我通常在客户端设置一个较小的抖动缓冲比如 100ms 到 200ms然后根据网络情况动态调整。5.4 一个踩过的坑静态会话的循环播放参数在用文件流做测试时明明设置了True循环播放文件播完却断了。查了很久发现是文件里 H.264 裸流格式问题有些文件末尾没有补齐结尾码或者最后一个 NAL 不完整导致 Live555 读文件时遇到 EOF 后没有正确处理循环逻辑。解决办法把文件先用工具转成标准的 Annex-B 格式比如用 FFmpeg 转成h264_mp4toannexb的裸流再作为 Live555 的输入。还有一种情况是文件名包含空格或中文旧版本 Live555 对路径的解析可能出错建议用英文路径。另外H264VideoFileServerMediaSubsession的循环播放是针对文件级别的暂停播放时文件读取位置也会停在当前帧位置。如果你需要按某个特定时间点循环播最好自己实现数据源而不是依赖文件子会话。5.5 多客户端并发的问题Live555 默认支持多客户端同时访问同一个流因为每个客户端会创建自己的RTPSink。但当你使用自定义FramedSource时如果多个RTPSink都试图从同一个源读取数据可能出现帧被重复读取或竞争。一个常见方案是在FramedSource的doGetNextFrame里引入引用计数把源变成“共享源”只让第一个使用者触发读取后续使用者从已经读到的同一帧克隆数据。还有一种更隐蔽的情况如果客户端 A 请求live流B 也请求live流但你的ServerMediaSession::createNew返回的是同一个对象那么两个客户端共享同一个会话。此时如果会话被 A 的 TEARDOWN 销毁B 的流也断了。正确做法是在RTSPClient连接断开时检查引用计数或者为每个客户端创建新的会话实例。6. 从实际项目看 Live555 的设计取舍6.1 什么场景适合 Live555Live555 最适合做单播 RTSP 拉流和推流特别是摄像头、编码器、播放器这类设备端场景。它的跨平台能力和协议完备程度是很大的优势。如果你要做一个中心服务器支撑几千路并发除非你很清楚自己在做什么否则还是建议考虑其他更现代的架构。毕竟单线程模型决定了它的并发上限而且调试复杂协议栈的难度不低。我见过有人在 Live555 上叠加了多线程doEventLoop来提升并发能力但这要求你深刻理解TaskScheduler内部的数据结构否则会出现内存问题。实际上很多项目用“一个服务器进程绑定多个端口每个端口对应一个事件循环线程”的方式来分流比在单线程里硬撑更有效。6.2 和 FFmpeg 对比别混淆职责很多初学者问有 FFmpeg 了为什么还用 Live555两者解决的问题重叠部分其实很少。FFmpeg 偏重编解码、转封装的媒体处理它的 RTSP 客户端支持虽然能用但更多是作为工具链一部分Live555 专注于 RTSP/RTP/RTCP 会话控制服务端能力强很多。常见组合是用 Live555 做 RTSP 服务器内部把 H.264 裸流传给 FFmpeg 解码或者用 FFmpeg 编码得到裸流传给 Live555 发送。6.3 一套稳定链路的建议路径如果你现在要基于 Live555 做一个项目我的建议是先跑通最小链路再加功能。最小链路就是文件推流 - VLC 或 FFmpeg 拉流播放然后再换成你的真实数据源最后处理多路、鉴权、断线重连等复杂逻辑。不要一开始就把采集、编码、网络全接在一起出了问题很难定位到底在哪一环。再具体一点代码里优先把这两件事做好一是自定义FramedSource的数据帧格式和时间戳这是所有上层功能的地基二是对RTSPServer的注册会话和错误日志做一个可视化的输出比如打印每个 SETUP/PLAY/TEARDOWN 事件。调试过程中几乎 80% 的问题都能通过这两个点的日志直接定位。我个人在实际开发中还养成了一个习惯给 Live555 的入口加一个专门的VERBOSE日志宏把每一条 RTSP 请求和关键 RTCP 报文打出来。这个习惯帮我避开了很多理不清头绪的协议交互问题。建议你也在自己的项目里保留这个调试口别为了日志好看而把细节藏起来。

相关新闻

Salesforce Einstein AI落地指南:自动化活动捕获、线索评分与搜索优化

Salesforce Einstein AI落地指南:自动化活动捕获、线索评分与搜索优化

简介:一份PDF资料系统介绍了Salesforce Einstein AI的体系与核心应用场景,目标读者是CRM产品经理、销售运营以及关注企业AI落地的从业者。内容围绕自动化销售活动、精准定位最佳潜在客户、提升成交率、深度连接客户以及Einstein搜索五大功能模块展开&…

2026/10/11 18:13:43 阅读更多 →
WiFi已连接但上不了网?Carrier IMS for Pixel一键修复captive portal联网验证详解

WiFi已连接但上不了网?Carrier IMS for Pixel一键修复captive portal联网验证详解

【免费下载链接】carrier-ims-for-pixel Carrier IMS for Pixel (TurboIMS): multilingual (中文/English) pixel ims / ims / carrierconfig / volte / vowifi / 5G toolkit for Google Pixel. 项目地址: https://gitcode.com/gh_mirrors/ca/carrier-ims-for-pixel…

2026/10/11 18:13:43 阅读更多 →
x64dbg DbgDelEncodeTypeSegment 函数详解:按内存段删除编码类型映射的调试 API

x64dbg DbgDelEncodeTypeSegment 函数详解:按内存段删除编码类型映射的调试 API

逆向工程调试器开发工具应用安全 【免费下载链接】x64dbg An open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis. 项目地址: https://gitcode.com/gh_mirrors/x6/x64dbg 点击查看 免费下载 导读 本文围绕 x64…

2026/10/11 18:12:43 阅读更多 →

最新新闻

IEC 81346-2-2019类对象与代码:统一设备身份的工程指南

IEC 81346-2-2019类对象与代码:统一设备身份的工程指南

简介:IEC 81346-2-2019《第2部分:类对象和代码的分类》是国际电工委员会发布的工业自动化系统和集成系列标准的重要构成,面向自动化工程师、系统架构师、设备维护人员及标准合规人员,用于统一类对象的分类和代码标识,解…

2026/10/11 19:46:42 阅读更多 →
用Visio画网上书店系统数据流图:从顶层图到0层图实务指南

用Visio画网上书店系统数据流图:从顶层图到0层图实务指南

简介:这是一份完整的PDF教程,面向软件工程课程学习者及系统分析设计人员,详细讲解如何利用Visio 2007绘制网上书店系统的数据流图。教程以Gane-Sarson数据流图为核心,严格遵循结构化分析方法中“自顶向下、逐层细化”的原则&#…

2026/10/11 19:46:41 阅读更多 →
华为IPD流程管理实战:六大阶段、DCP评审与落地避坑指南

华为IPD流程管理实战:六大阶段、DCP评审与落地避坑指南

简介:华为IPD流程管理(完整版)是一份系统讲解华为集成产品开发体系的PPTX课件,目标读者为企业管理者、产品研发人员、流程变革项目成员及咨询顾问。课件从“满足客户需求是生存唯一理由”的核心理念切入,深入剖析OR流程…

2026/10/11 19:46:41 阅读更多 →
UML建模与图书管理系统需求分析:从数据字典到需求基线的完整路径

UML建模与图书管理系统需求分析:从数据字典到需求基线的完整路径

简介:一份面向 UML 初学者的图书管理系统需求分析文档,系统梳理用例图、类图、顺序图等核心模型从需求分析到设计落地的完整过程,适合作为软件工程课程设计或毕业设计的参考资料。压缩包内为单独的 1 个 doc 文档,约 265KB&#x…

2026/10/11 19:46:41 阅读更多 →
软件概要设计说明书实战指南:模块划分、接口定义与数据流设计

软件概要设计说明书实战指南:模块划分、接口定义与数据流设计

简介:这份软件概要设计说明书面向计算机专业学生、软件工程初学者及需要撰写设计文档的开发人员,帮助读者理解概要设计阶段的核心任务与文档规范。资源包内含1个doc文件,约350KB,完整呈现了从引言、范围界定到系统结构设计、数据设…

2026/10/11 19:46:41 阅读更多 →
工业网关 OTA 固件防物理篡改:硬件 eFuse 熔丝与安全启动链 TrustZone

工业网关 OTA 固件防物理篡改:硬件 eFuse 熔丝与安全启动链 TrustZone

在部署于高山风电塔筒、偏远光伏汇流箱或无人值守变电站的工业物联网边缘网关中,设备长期暴露在缺乏物理安防的旷野环境下。攻击者不仅可以通过无线网络发起远程渗透,更有充裕的时间实施“物理接触式攻击(Physical Tampering)”&a…

2026/10/11 19:45:40 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →