SRS 代码阅读工作流详解:基于 learn-code.md 的零修改溯源方法论
发布时间:2026/9/10 2:20:04来源:尧图网络
SRS 代码阅读工作流详解基于 learn-code.md 的零修改溯源方法论【免费下载链接】srsSRS is a simple, high-performance, AI-driven real-time media server supporting RTMP, WebRTC, HLS, HTTP-FLV, HTTP-TS, SRT, MPEG-DASH, and GB28181, with codec support for H.264, H.265, AV1, VP9, AAC, Opus, and G.711.项目地址: https://gitcode.com/GitHub_Trending/sr/srsSRS 仓库的skills/srs-develop技能集定义了六类开发任务其中Learn Code学习代码是专门用于“只读理解现有 SRS 或 Oryx 实现”的工作流在不修改任何项目文件的前提下回答关于实现原理、架构设计、控制流、数据流和模块边界的问题。本文基于 Learn Code 工作流文档结合 srs-develop 主技能 的任务路由、代码地图路由 与 文档路由 的实际结构完整拆解这套四步工作流的路由规则、可信范围约束与答案规范并以 Go 代理服务的真实源码cmd/proxy/main.go、internal/bootstrap/proxy.go、internal/lb/lb.go作为贯穿示例展示如何落地执行“先文档、再代码、后对账”的阅读路径。一、工作流定位前置条件与适用范围Learn Code 文档 开篇即给出两条强约束前置条件Prerequisite只有当 srs-develop 主技能 中的Task Router任务路由器选中 Learn Code 之后才能执行该工作流不允许直接触发。适用范围Scope解释现有 SRS 或 Oryx 代码如何工作不修改任何一侧项目。回答必须覆盖实现、架构、控制流、数据流、模块边界和行为且一切结论都要立足当前代码与项目文档。1.1 Task Router为什么不能直接执行skills/srs-develop/SKILL.md 的 Task Router 章节明确要求⚠️ 必须首先执行路由步骤绝不能跳过也不能直接跳入某个任务每个请求必须被路由到且仅一个任务类型。六类任务分别为任务类型适用场景工作流文档Develop Code任何计划中的 SRS、Oryx、Dev Docker、文档或技能变更develop-code.mdScan Issues只读扫描近期活跃且可能需要关注的开放 issuescan-issues.mdScan PRs只读评估指定 PR或最近更新的 PRscan-prs.mdFix a Bugissue 报告了损坏、异常或不安全行为可能需要调查或修复fix-a-bug.mdLearn Code用户希望在不改动项目的前提下理解现有实现、架构、控制流或行为learn-code.mdReview a PR变更已存在于本地的维护者集成流程review-a-pr.mdTask Router 对 Learn Code 的路由描述是“当用户希望在不进行项目变更的情况下获得对现有 SRS 或 Oryx 实现、架构、控制流或行为的解释时使用。路由到最小相关的文档与代码地图对账后以聚焦的源码引用作答。” 此外还有两条配套规则若路由到的任务尚不支持必须停止并告知用户任务类型、暂不支持、未来会加入支持——而不是勉强执行每个任务在执行前必须先识别产品是SRS 还是 Oryx若产品不明且该选择会改变仓库、issue 跟踪器、代码地图或验证方式应先向用户澄清不得把 SRS 与 Oryx 的工作混为一谈。这一设计解释了 Learn Code 的第一句话“Do not execute it directly”——工作流的输入不是裸问题而是已经过产品判别和任务分类的请求。1.2 核心原则代码与文档是唯一真相skills/srs-develop/SKILL.md 的 Core Principle 章节是整个工作流的哲学基础Code and documents are the only truth.Issue 描述可能不准确Pull Request 可能有误导性功能描述可能不充分。始终基于实际源码和项目文档来建立理解。文档承载了设计意图、架构动机和代码本身无法表达的复杂背景——它们是代码的另一种形式。当代码与文档冲突时去调查而不是假设其中一方是错的。这条原则直接决定了 Learn Code 第三步“对账reconcile”的存在意义文档与代码不一致不是选边站而是要作为“冲突”去调查。二、Step 1先路由并阅读文档Learn Code 第一步要求先加载 internal-docs-for-srs/SKILL.md 并使用它的 Reference Router引用路由器在阅读任何项目文档之前完成路由。具体有三条子规则先按产品分类再按服务器代际、服务、协议或功能细分选择并阅读最小相关文档集覆盖设计意图、架构和已记录的行为若文档路由器没有匹配的路由或路由解析出的文件不可用记录文档缺口documentation gap并继续进入代码路由而不是大范围搜索文档目录、更不是编造设计意图。2.1 文档路由器Reference Router的实际结构skills/internal-docs-for-srs/SKILL.md 的 Reference Router 是一份“主题 → 可信文档”的映射表按五个分区组织每个条目都带有一句话描述供选择“最小相关文档集”C 媒体服务器发布记录trunk/doc/CHANGELOG.md—— 所有 SRS 版本的完整变更日志每个已合并 PR 对应一条记录和一个版本提升C 媒体服务器用户文档共 28 篇如references/cpp-docs/doc/introduction.md概述、支持协议、State Threads 架构、学习路径、getting-started.mdDocker 快速开始、各协议 URL 模式、rtmp.md、hls.md、webrtc.mdWHIP/WHEP、SFU 架构、RTMP 转 RTC、srt.md、low-latency.md延迟调优、performance.mdperf、Valgrind、ASAN 与基准测试方法论、origin-cluster.md代理式负载均衡与 Go 代理架构等C 媒体服务器官网页面FAQ、License、产品里程碑、安全公告等 4 篇Oryx 文档Oryx 概览与部署、FAQ、oryx/README.md、oryx/DEVELOPER.md以及一批按日期命名的场景博客部署、HTTPS、认证、录制、转码、AI 字幕、翻译、OCR 等。文档还给出优先级规则Oryx 问题优先使用 getting-started 指南、FAQ 和仓库文档带日期的博客视为场景化指导当命令、UI 标签或行为不一致时优先选择与用户 Oryx 版本匹配的文档RTMP Go API 示例internal/rtmp/example_test.go—— AMF0、握手与协议流程的 RTMP API 示例WHEP 性能分析references/perf/proxy-whep.md—— 用 pprof 和 srs-bench 剖析 WHEP 的 CPU、分配、堆、goroutine 与 trace 数据下一代 Go 代理文档6 篇包括references/proxy/features.md功能状态与限制、proxy-design.md无状态代理设计、内置负载均衡、Redis 模式、水平扩展、proxy-protocol.md后端注册、调试后端、心跳协议与环境变量、proxy-usage.md构建、启动、注册、推流验证、proxy-load-balancer.md内存/Redis 负载均衡器行为、proxy-origin-cluster.md生产多源站集群。路由器同时附带核心规则只加载与任务相关的文档不要全部加载只有被该技能或所选引用列出的项目文件才视为可信文档没有路由覆盖的任务要如实报告“文档路由器未覆盖”而不是扫描或大范围 grep 文档目录。以“Go 代理的启动流程”为例按 Step 1 的规则应选中references/proxy/proxy-design.md与proxy-protocol.md两篇文档架构 协议注册而非 6 篇全读——这就是“最小相关文档集”的含义。三、Step 2路由到负责的代码Learn Code 第二步同样要求先路由、后读码共有四条子规则加载 internal-codemap-for-srs/SKILL.md用其 Reference Router 选择相关的 SRS 或 Oryx 代码地图若选错产品或服务器代际会实质性改变答案必须向用户澄清用所选地图的描述定位负责模块与最小相关文件集当地图列出的是目录而非文件时先只列出该目录内的文件名再挑选文件只读取或搜索所选文件仅当证据显示实现跨越了第一个模块边界时才追加路由下一个模块对 Oryx保持当前工作目录不变通过项目根相对的oryx/路径查看它可能是目录也可能是指向用户首选 checkout 的符号链接若不可用请用户在该位置提供 checkout不要搜索其他 checkout。3.1 代码地图路由器Reference Router的实际结构skills/internal-codemap-for-srs/SKILL.md 的 Reference Router 将代码域映射到六份引用地图代码域使用时机加载的地图C 媒体服务器第一代 origin/edge 服务器、trunk/src/、trunk/conf/、协议、媒体处理、State Threadscpp-server.md下一代 Go 服务器Go 代理、未来的 Go origin/edge 服务、cmd/、internal/go-server.md浏览器推流端与播放器WHIP、WHEP、HTTP-FLV、HLS 的浏览器推流/播放含trunk/research/players/browser-clients.mdSRS Docker 构建镜像ossrs/dev-docker、依赖与缓存镜像、打包的 FFmpeg 等构建工具dev-docker.md测试与验证需要选择或运行 C 单元测试、黑盒测试、E2E、复现或基准验证testing.mdOryx 一体化视频方案ossrs/oryx、oryx/、Go 平台、React 仪表盘、SRS/Redis 运行时集成、安装与发布oryx.md跨代际比较或迁移任务需同时加载两份服务器地图只有需要 SRS 验证时才追加测试引用跨越独立 SRS 与 Oryx 的任务则加载 Oryx 地图加最小负责的 SRS 地图。3.2 可信导航范围与禁止行为代码地图技能的核心规则中对“如何读码”给出了强约束这些约束是 Learn Code 第二步的执行细则以当前工作目录为项目根不搜索父目录、不发现其他仓库根外部仓库仅有两个例外dev-docker/与oryx/路径均通过git -C访问、保持当前工作目录不变、不解析符号链接、不搜索备用 checkout只有被所选引用列出的文件和模块目录才是可信导航范围禁止 grep 仓库根或trunk/src/、cmd/、internal/、oryx/platform/、oryx/ui/这类宽泛目录树——这保证了“从地图进文件”而非“从海量搜索碰文件”模块目录只列文件名再挑选读码只发生在被选文件上没有路由覆盖时如实报告不做临时发明路由报告“路由文件缺失”之前先直接检查其完全解析后的路径。3.3 用两份地图看实际模块划分Go 服务器地图go-server.md描述了cmd/internal/的完整模块结构。可以据此快速回答“某个行为归谁负责”cmd/proxy—— 无状态反向代理位于一个或多个 SRS C origin 之前接受 RTMP、HTTP-FLV/HLS、WebRTC WHIP/WHEP、SRT 客户端连接通过负载均衡器解析后端 origin 后透明转发流量不缓存流、不处理媒体——只转发字节全部通过环境变量或.env文件配置无配置文件入口为 cmd/proxy/main.gointernal/bootstrap—— 启动与生命周期编排日志上下文、信号处理、环境加载、强制退出定时器、可选 pprof、负载均衡器初始化按PROXY_LOAD_BALANCER_TYPE选内存或 Redis随后顺序启动六个服务器RTMP、WebRTC、HTTP API、SRT、System API、HTTP Stream阻塞直到 context 取消每个服务器通过defer Close()优雅关闭internal/proxy—— 五个代理服务器实现RTMPrtmp.go解析 connect/publish/play 提取流 URL双向复制 RTMP 消息、HTTP 流http.go静态文件 HTTP-FLV/TS 反代 HLS m3u8 的spbhid重写、WebRTCrtc.go两阶段WHIP/WHEP 信令 SDP 改写 基于 STUN ufrag 的 UDP 媒体转发有状态、SRTsrt.go本地拦截 SRT 四步握手、解析 stream ID、与后端重放握手有状态、HTTP API System APIapi.goSystem API 提供/api/v1/srs/register供后端 SRS C 服务器注册internal/rtmp—— RTMP 协议实现解析而非代理完整 chunk 流与消息协议、四种格式类型、扩展时间戳、消息重组以及完整 AMF0 编解码器internal/lb—— 负载均衡抽象与两种实现内存 LBmem.gosync.Map、按流 URL 粘性随机挑选、单代理部署与 Redis LBredis.goTTL 过期、多代理水平扩展其余基础设施模块internal/env环境变量配置默认端口 RTMP11935、HTTP API11985、HTTP Stream18080、WebRTC18000、SRT20080、System API12025、internal/loggerslog JSON 日志每条连接带 7 位十六进制上下文 ID、internal/errors带堆栈的错误包装、internal/sync泛型 sync.Map、internal/signalSIGINT/SIGTERM 与 30 秒强制退出兜底、internal/debugpprof、internal/utilsURL/协议/网络辅助函数等。C 服务器地图cpp-server.md则把trunk/src/分为四层并给出文件命名约定srs_{模块}_{主题}.cpp/.hppmain/main_server即main()入口core/基础定义——核心宏与配置、按主版本划分的版本定义core_version至core_version8、SrsUniquePtr智能指针、性能调优常量、平台抽象、时间类型kernel/无网络、无协议逻辑的底层构件——编解码/容器FLV、MP4、TS、PS、H.264/H.265/AAC 解析、缓冲与 I/OSrsBuffer、SrsSimpleStream、文件读写、RTC 原语RTP/RTCP 编解码、重排队列、工具错误码、日志、常量、kernel_hourglass定时器协程、kernel_balance轮询负载均衡protocol/线上格式——RTMP chunk 流与 AMF 命令、HTTP 栈含来自 Node.js 的 llhttp、WebRTC 原语STUN、SDP、RTP 打包、SRT socket 封装、RTSP、裸 H.264/H.265 流Annex-B ↔ AVCC 转换、JSON 与 Protobuf 辅助app/应用逻辑——app_server主服务器、app_config配置解析、RTMP 连接与源app_rtmp_conn、app_rtmp_source管理消费者、GOP 缓存与 hub、HTTP API/回调/静态/流、WebRTC 全套服务器、连接、源、WHIP/WHEP API、DTLS、音频转码、SRT、RTSP、GB28181、HLS/DASH 复用器、DVR 录制、Edge/Forward/Bridge、Ingest/Transcode/FFmpeg 进程管理、安全规则、统计、心跳、熔断器等。该地图还特别说明了两条容易误判的依赖路径C 服务器通过两条独立路径使用 FFmpeg——app_rtc_codec进程内调用libavcodec/libswresample/libavutil做 AAC/MP3/Opus 音频转换编译期依赖裁剪版trunk/3rdparty/ffmpeg-4-fit/需SRS_FFMPEG_FIT以及app_ingest/app_encoder通过app_ffmpeg拼装 CLI 参数并经app_processfork/exec 外部 FFmpeg 可执行文件两条路径不可混为一谈。这类“边界澄清”正是代码地图存在的价值Learn Code 第二步“定位负责模块”能否准确直接取决于地图对边界的刻画。四、Step 3追踪并对账实现第三步是 Learn Code 的“引擎”包含四条子规则每条都对应一个具体的阅读动作追踪最窄有用路径从功能入口点配置、API、监听器、协议处理器或公开接口出发穿过负责模块与必需的底层依赖分离通用路径与协议/服务特有行为识别相关的默认值、平台相关行为、回退与限制文档对账代码对实质性冲突要去调查而不是静默地偏向任一方明确区分“已确认行为、合理推断、未知”按需验证仅在用户要求运行时验证、或静态证据对重要结论不足时才使用测试与验证地图testing.mdLearn Code 过程中不得修改代码或测试。下面以“Go 代理的启动流程”为例演示 Step 1 → Step 3 的完整落地。4.1 追踪从入口到六个服务器按 go-server 地图入口点是 cmd/proxy/main.go。其main()只有三行实质逻辑bs : bootstrap.NewProxyBootstrap() if err : bs.Start(context.Background()); err ! nil { // Error already logged in bootstrap.Start(). os.Exit(-1) }入口只做了“构造 bootstrap 并 Start”所有编排都在 internal/bootstrap/proxy.go 中。Start()L144-L161先给 context 注入日志上下文打印SRSX-Proxy/版本 started日志然后安装信号处理器最后调用run()并忽略用户取消导致的 errorctx.Err() context.Canceled时不记错误日志。run()L165-L196按顺序完成五件事b.newEnvironment(ctx)创建环境读取进程环境变量与.env文件InstallForceQuit安装强制退出定时器——注释解释了动机“正常情况下主线程在 context 取消后退出但有时主线程可能被阻塞因此需要强制退出兜底以确保程序终止”debug.HandleGoPprof可选启动 pprof由GO_PPROF环境变量控制见 internal/debug/pprof.goinitializeLoadBalancerL199-L213按environment.LoadBalancerType()分支值为redis时构造 Redis LB其余任何值都回退到内存 LB——这是地图中“single-proxy内存/multi-proxyRedis”两种部署模式的代码对应点startServers解析GraceQuitTimeout()后顺序启动服务器。startServers()L216-L263按固定顺序启动六个服务器每个都先Run(ctx)再defer Close()RTMP → WebRTC → HTTP API传入 webRTCProxyServer 引用→ SRT → System API → HTTP Stream最后-ctx.Done()阻塞等待取消。这与 go-server 地图对internal/bootstrap的描述逐句吻合——地图文档与源码对账一致可作为“已确认行为”写入答案。值得注意的是proxyBootstrap结构体L72-L123每个组件都是函数型构造字段newEnvironment、newRedisLoadBalancer、newRTMPProxyServer……默认值指向真实实现测试可通过函数式选项注入 fake如proxyfakes.FakeRTMPProxyServer而不绑定真实端口。从源码结构看这一设计让 internal/bootstrap/proxy_test.go 能在不启动任何网络监听的情况下验证编排逻辑本身——这正是“静态证据 测试证据”双重支撑的典型形态。4.2 分离负载均衡的通用接口与两种实现Step 3 第二条“分离通用路径与特有行为”在 internal/lb/lb.go 中体现得很清楚。该文件定义了四个接口与一个核心结构体OriginServerL38-L61后端 origin 的注册信息——IP、用户配置的DeviceID、持久化的ServerID存于文件、重启不变、每次重启都变化的ServiceID与PID以及 RTMP/HTTP/API/SRT/RTC 五类监听端点和最后更新时间。ID()由ServerID-ServiceID-PID拼出天然区分同一台机器的不同进程OriginServiceL128-L133Update记录注册或心跳与Pick按流 URL 挑选后端HLSServiceL136-L141按流 URL 与SPBHIDSRS Proxy Backend HLS ID索引 HLS 会话状态对应 HTTP 代理中 m3u8 的spbhid重写机制RTCServiceL144-L149按流 URL 存储、按 ICE ufrag 查找 WebRTC 连接OriginLoadBalancerL152-L158组合上述三组能力加Initialize。文件头部的两个常量同样值得注意HLSAliveDuration与RTCAliveDuration均为 120 秒“在该时长内有更新即视为存活”而parseOriginServerTTL将PROXY_ORIGIN_SERVER_TTL解析为源站存活 TTL、未设置时默认 300 秒且必须为正数。这类“默认值与限制”正是 Step 3 第二条要求显式识别的要素。内存实现与 Redis 实现分别位于 internal/lb/mem.go 与 internal/lb/redis.go均有对应单测 mem_test.go、redis_test.go前者用sync.Map做按流 URL 的粘性随机挑选单代理后者用带 TTL 的 Redis 键实现多代理共享状态水平扩展——地图文档中“single-proxy / multi-proxy”两种部署模式的静态证据链到此闭合。4.3 对账区分确认、推断与未知Step 3 第三条要求答案中明确区分三类陈述。对照上例已确认行为启动顺序、defer Close()优雅关闭、redis分支与内存回退——均有 internal/bootstrap/proxy.go 源码直接支撑合理推断例如“六个服务器顺序启动而非并发启动”——源码确实如此但若结论需要外推到“并发启动会怎样”则超出证据边界应标注为推断未知/冲突若地图文档与源码不一致比如文档说“默认 TTL 300 秒”而代码写的是别的Learn Code 要求“调查而非偏向任一方”并把该冲突作为答案的一部分报告出来。4.4 按需验证测试与验证地图第四步的验证只“按需”触发而验证手段由 skills/internal-codemap-for-srs/references/testing.md 定义。该地图把验证分为五类并给出“是否需要运行服务器 / 是否走网络 / 是否有 pass/fail”的判别矩阵类型服务器是否运行测试网络Pass/fail单元测试否隔离的内部逻辑否有黑盒测试是自管理全服务器行为有有E2E是外部管理协议工作流有有跨组件集成脚本自管理代理、源站、边缘、路由与协议互操作有有基准测试是外部管理性能与容量有否仅指标对应的真实测试资产包括trunk/src/utest/ 下的 C 单元测试构建运行方式为cd trunk ./configure --utest make utest ./objs/srs_utest含 AI 编写的srs_utest_ai01–ai24、手工编写的srs_utest_manual_*与工作流测试srs_utest_workflow_*trunk/3rdparty/srs-bench/blackbox/ 下的黑盒测试每个测试用NewSRSServer()自管理 SRS 进程用 FFmpeg/FFprobe 推流播放并校验输出覆盖 RTMP、HLS、SRT、RTSP、HEVC、DVR、HTTP API、MP3trunk/3rdparty/srs-bench/srs/ 下针对外部启动 SRS 的 E2E 协议测试真实 Pion WebRTC、RTMP 与 HTTP API 客户端以及 trunk/3rdparty/srs-bench/ 本身的性能基准模拟并发 WHIP、WHEP、RTMP、重连、DVR、明文 RTC、Janus 负载只报指标、无 pass/fail 断言。Go 侧则以各模块的*_test.go如 internal/bootstrap/proxy_test.go、internal/lb/lb_test.go、internal/rtmp/rtmp_test.go和 counterfeiter 生成的 fakeinternal/bootstrap/proxy_test.go注入的proxyfakes、lbfakes作为静态与单元测试证据。测试地图还特别强调skills/srs-develop/scripts/ 下的proxy-*脚本是跨组件集成验证其命名标识的是入口拓扑而非“仅限代理变更”——这一点与 skills/srs-develop/SKILL.md 的 Cross-Component Verification 章节呼应对 Go 代理或 C 媒体服务器的任何独立运行时变更都要在模块级验证之外运行 integration-tests.md 定义的完整套件。不过按 Learn Code 规则这些验证只在“用户要求运行时验证或静态证据不足”时才被触发且阅读过程中绝不修改代码或测试。五、Step 4给出答案的五条规范Learn Code 第四步规定了答案的输出形态逐条对应如下先直接回答用户问题再描述调查过程——结论前置声明被检查的产品与组件当行为可能随版本变化时声明所属仓库的当前分支与 commit——把“答案适用边界”写进答案引用负责文件并给出聚焦的行号范围解释各文件职责如何衔接不得返回无结构的文件堆砌file dump——前文 internal/bootstrap/proxy.go 的run()分析就是这一规范的示例形态文件路径 行号范围 职责衔接说明报告相关的文档缺口、代码/文档冲突、限制与未解决问题——Step 1 记录的 documentation gap、Step 3 发现的冲突都在这一步浮出水面不做任何项目变更。若调查发现疑似 bug 或期望的变更报告它由用户另行发起 Fix a Bug 或 Develop Code 任务——这保证了六类任务互不越界Learn Code 的只读属性在流程终点再次被锁定。六、路径解析约定路由文件“从哪里找”四步工作流中反复出现“加载skills/...的某个 SKILL.md 或 references 文件”这些路径如何解析由 skills/srs-develop/SKILL.md 的 Path Resolution 章节统一规定以当前工作目录为项目根不搜索父目录、不发现其他仓库根Oryx 一律通过项目根相对的oryx/路径git -C访问dev-docker同理两者均可能是目录或指向用户首选 checkout 的符号链接不可用时请求用户提供不自动创建、不解析符号链接、不搜索备用 checkout以references/、scripts/、assets/、agents/开头的捆绑路径相对于所在 SKILL.md 的目录解析而非当前工作目录而trunk/、internal/、cmd/、skills/这类仓库路径则相对于当前工作目录解析使用当前被调用的技能目录不在.agents/、.kiro/、.claude/等工具专属目录下搜索备用副本报告路由文件缺失之前先直接检查其完全解析后的路径。这套规则让 Learn Code 的两步路由文档路由、代码路由在多工具、多 checkout 环境下保持确定性和可重复性。七、工作流全景与执行清单将 learn-code.md 的四步与支撑技能汇总一次 Learn Code 任务的标准执行路径是用户问题 │ ▼ Task Routerskills/srs-develop/SKILL.md ├─ 判定产品SRS 还是 Oryx代际是否影响答案必要时澄清 └─ 判定任务类型Learn Code │ ▼ Step 1 文档路由skills/internal-docs-for-srs/SKILL.md ├─ 按产品 → 代际 → 服务/协议/功能 分类 ├─ 选择最小相关文档集28 篇 C 文档 / Oryx 文档 / 6 篇 Go 代理文档 / 示例与性能文档 └─ 无路由 → 记录文档缺口继续 │ ▼ Step 2 代码路由skills/internal-codemap-for-srs/SKILL.md ├─ 选择地图cpp-server / go-server / browser-clients / dev-docker / testing / oryx ├─ 目录级模块先列文件名再挑最小文件集 ├─ 只读所选文件证据显示跨模块边界时才追加 └─ Oryx 走 oryx/ 路径不解析符号链接、不搜索备用 checkout │ ▼ Step 3 追踪与对账 ├─ 从入口配置/API/监听器/协议处理器追踪最窄路径 ├─ 分离通用路径与协议特有行为识别默认值、平台差异、回退、限制 ├─ 文档 vs 代码 冲突 → 调查并区分 确认 / 推断 / 未知 └─ 仅在需要时调用测试地图五类验证不改代码 │ ▼ Step 4 回答 ├─ 先结论后过程声明产品/组件/分支/commit ├─ 文件 聚焦行号 职责衔接不做文件堆砌 ├─ 报告文档缺口、冲突、限制、未解问题 └─ 零变更疑似 bug 移交 Fix a Bug / Develop Code八、小结这套方法论解决了什么Learn Code 工作流的本质是把“读一个大型媒体服务器代码库”这一模糊任务转化为一条有路由、有边界、有对账、有输出规范的确定性流水线路由优先文档先于代码、地图先于文件。两份路由器文档 28 篇可信文档、代码 6 张模块地图把“可信范围”显式化禁止 grep 仓库根保证阅读成本与问题规模成比例最小文件集从目录到文件逐级收敛只有证据显示实现跨越模块边界时才扩圈——这与internal/lb只含OriginLoadBalancer接口与两个实现、跨模块协作全部通过接口HLSService、RTCService暴露的架构风格天然契合对账而非选边文档承载设计意图、代码承载实际行为冲突是调查对象而不是噪音答案中强制区分“确认 / 推断 / 未知”三级证据只读契约从前置条件到 Step 3 的“不改代码或测试”再到 Step 4 的“疑似问题移交其他任务”Learn Code 的零修改属性在流程首、中、尾三次被锁定使其可以安全地用于任何“想懂 SRS/Oryx 某个行为”而不愿承担改动风险的场景。对于想理解 SRS 某段代码“为什么这样写”的读者最直接的实践方式就是按本文路径走一遍先读 skills/srs-develop/SKILL.md 完成产品与任务判定再用 skills/internal-docs-for-srs/SKILL.md 和 skills/internal-codemap-for-srs/SKILL.md 的两张路由器锁定最小文档集与最小文件集最后按 Step 3/4 的规范完成追踪、对账与作答。【免费下载链接】srsSRS is a simple, high-performance, AI-driven real-time media server supporting RTMP, WebRTC, HLS, HTTP-FLV, HTTP-TS, SRT, MPEG-DASH, and GB28181, with codec support for H.264, H.265, AV1, VP9, AAC, Opus, and G.711.项目地址: https://gitcode.com/GitHub_Trending/sr/srs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网