news 2026/9/7 16:10:53

RK3588边缘AI盒子帧率优化:从模型量化到RGA加速的完整排查指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RK3588边缘AI盒子帧率优化:从模型量化到RGA加速的完整排查指南

前阵子帮客户调一块 RK3588 边缘 AI 盒子,软件栈装好、模型转换完、摄像头也出图了,但帧率始终徘徊在 20fps 上下。官方 demo 里那种丝滑感完全出不来,更头疼的是这个帧率还不稳定,系统跑几分钟就掉到 15fps 以下,过一会儿又自己恢复。客户盯着这个数字不松口,我只能老老实实把整条链路拆开查。

最后问题分成三块才解决:模型转换时的量化策略、图像预处理链路的硬件加速、以及散热策略导致的 NPU 动态降频。这篇文章就把 RK3588 边缘 AI 视觉算法推理帧率相关的完整排查过程、经验教训和优化配置整理出来。无论是刚拿到开发板想跑通 YOLO 的新手,还是正在做视觉引导定位、实时视频监控、多路流分析的工程师,这篇文章里的链路拆解、量化要点和排查方法都能直接拿来用。

1. 先算清算力账:RK3588 的 NPU 真正能扛多少活

1.1 CPU、NPU、RGA、VPU 各管一摊,别把所有活都压给 CPU

RK3588 的架构是 4 个 Cortex-A76 大核加 4 个 Cortex-A55 小核,CPU 理论性能放在 ARM 阵营里确实能打。但对边缘 AI 推理来说,它最值钱的是内置的三核 NPU,标称 6 TOPS 算力。

很多人对 6 TOPS 没有概念,容易被开发板宣传冲昏头脑。我直接给个直观参考:在纯 NPU 推理层面,YOLOv8s 640×640 INT8 大概需要 35-45ms 一帧,约合每秒 22-28 帧;换成 YOLOv5s 同分辨率,大概能压到 25-35ms,也就是 30fps 上下。注意这里说的是“纯 NPU 推理”,要是把整条系统的帧率直接等同这个数字,后面一定会被现实教育。

RK3588 上还有几个对视觉链路至关重要的硬件模块,新手往往没注意。RGA 是 2D 图像硬件加速器,缩放、旋转、颜色空间转换都是它的强项;VPU/MPP 负责视频硬件编解码,H.264/H.265 都能硬解硬编;还有 ISP 处理摄像头原始数据。这些模块和 NPU 配合好,才是完整高效的边缘 AI 方案。

我见过不少项目把模型加载到 NPU 上,但图像缩放和格式转换全用 OpenCV 在 CPU 上跑,导致 NPU 空转等数据。这种“单点快、链路慢”的情况,在 RK3588 这类带多硬件加速单元的 SoC 上尤其容易犯。关键认知是:RK3588 不是一块“能跑 AI 的 CPU 开发板”,而是一台需要调度多个硬件单元协作的微型算力中心。

另一个容易忽略的点是算力利用率。6 TOPS 是理论峰值,实际能跑到多少取决于算子与硬件加速器的匹配程度。纯卷积结构的网络,NPU 利用率能到百分之六七十甚至更高;一旦模型里混入大量不支持的算子、动态 shape 或者复杂的激活函数,算力利用率可能掉到百分之三四十以下。也就是说,同一块芯片,模型结构差一点,有效算力可能直接腰斩。这个问题的根源在模型转换环节,下一节展开讲。

1.2 平均帧率、稳定帧率、p99 要分开看,目标定清楚再动手优化

做边缘视觉项目,一定要把帧率拆成两个指标。第一个是平均帧率,代表吞吐量,比如说“一秒钟能处理多少帧”。第二个是稳定帧率,或者叫无掉帧帧率,代表单帧端到端延迟有没有兜底。很多场景比如视觉引导定位,倒不在乎平均帧率是 30 还是 35,更在意每一帧的延迟抖动。如果第 20 帧突然因为内存分配或降频卡了一下,机械臂可能就把工件抓歪了。

我见过一个做机械臂抓取的项目,平均帧率 28fps 看起来很漂亮,但现场就是偶尔抓偏。后来打印了每一帧的端到端延迟,发现 p99 延迟是平均值的 3 倍多。问题并不在模型的推理速度,而是内存分配、CPU 调度抖动、以及网络通信波动叠加造成的偶发大延迟。

所以项目一开始就要定义清楚:你的场景是要高吞吐,还是低延迟稳定性?这两个方向的优化手段完全不同。做实时监控,重点压平均帧率,允许偶发掉帧;做视觉引导,重点压延迟抖动,宁可帧率低一点,也要保证每一帧的时间可控;做轻量级 web 推理服务,要关注并发吞吐,甚至要用 batch 推理把 NPU 吃满。

顺便说一句,很多人喜欢拿训练时的 GPU 帧率来预估部署时的 NPU 帧率,这里经常对不上。训练看重的是吞吐,部署看重的是延迟和稳定性,两者目标不同,硬件架构也完全不同。训练和推理的区别必须心里有数,否则你拿训练日志里的数字去跟客户汇报部署帧率,很容易翻车。

2. 模型落地第一关:rknn-toolkit2 转换与量化决定性能地板

2.1 从 PyTorch 到 RKNN:转换流程和配置细节直接影响最终帧率

RK3588 上跑模型用的是瑞芯微自研的 RKNN 格式,转换工具是 rknn-toolkit2。整体流程是:训练好的 PyTorch 模型先导出 ONNX,再用 rknn-toolkit2 转成 .rknn 格式,最后在板端用 RKNNLite(Python 场景)或 RKNN C API(生产场景)加载推理。

很多人上来就问“RK3588 的模型 demo 在哪个文件夹”,其实 SDK 里的 examples 就是现成参考,路径一般在 rknn-toolkit2 的 examples 目录下。但别急着跑 demo,先搞清楚转换时的几个配置项,它们的优先级更高。

最容易踩的坑有三个。第一是 mean_values 和 std_values 配错。这组参数对应训练时的归一化设置,很多人直接把 PyTorch 代码里常用的 ImageNet 均值填进去,但自己的模型可能用的是别的归一化方案,填错之后模型跑起来不报错,就是识别率崩,排查起来非常头疼。第二是 quant_img_RGB 设反。它标记输入图像通道顺序,如果设成 False 但实际输入是 RGB,模型输出结果会乱套。第三是 calibration 数据集数量不够。做 INT8 量化时,需要几十到几百张有代表性的图片让工具统计激活值分布,有些人只放三五张图,量化后精度惨不忍睹。

这里特别强调一下 calibration 数据集的选择。一定不要直接从训练集里抽图,最好从实际部署场景里现场采集。做工厂视觉引导定位,就拍工厂工位上的实际画面;做监控分析,就截取监控画面的真实帧。我用训练集图片做过校准,量化后模型在实景里掉点很明显,换成实景图片校准后精度基本恢复。这个细节在官方文档里只是一笔带过,但实际效果差别极大。

2.2 INT8 量化省下的是时间,但算子掉 CPU 会让你全盘皆输

量化对帧率的影响几乎是决定性的。同一个模型在 RK3588 上,FP16 推理和 INT8 推理的时间差距通常在一倍以上。NPU 对 INT8 有更完整的算力管线,单位时间能处理的帧数更多。除非模型对精度极其敏感,比如某些关键点回归任务,否则我建议优先上 INT8。

但 INT8 有个大坑:不是所有层都能被 NPU 吃进去。碰到不支持的算子,rknn-toolkit2 会做算子级拆分,把不支持的层放到 CPU 上执行。这是最阴险的坑,因为它不会报错,也不会有明显警告,只会在转换日志里悄悄标注“placement=CPU”。你会感觉明明转成功了、跑起来也没问题,但帧率就是上不去。

怎么查?转换时把 verbose 日志打开,仔细看每一层的分配情况。我在一个项目里遇到过模型结构看起来不复杂,但推理时间怎么都压不下来的情况。查了日志才发现,模型尾部有两个自定义算子被放在了 CPU,这两个算子跑一次要 40ms,直接把整体时间翻倍。后来把自定义算子改写成标准卷积加激活函数的组合,CPU 算子清零,推理时间才回到正常水平。

还有一点要留意:模型里的动态 shape 或动态分支操作,在 RKNN 上支持度有限。转换时如果遇到动态维度,工具可能会把它拆成多个静态子图,子图切换的延时也不小。所以模型定型时就要尽量保持静态输入尺寸和静态计算图,这是 RK3588 边缘 AI 部署的基本素养。

2.3 检测、分类、关键点模型的实际推理时间参考

放一组我实测过的数据(RK3588,INT8,纯 NPU 推理,不包含前后处理):

模型输入分辨率单帧推理耗时适用场景
YOLOv5s640×640约 25-35ms目标检测
YOLOv8s640×640约 35-45ms目标检测
EfficientNetV2-S224×224约 4-8ms图像分类
轻量关键点模型192×192约 5-10ms视觉引导定位

这几组数据能看出几件事。第一,模型结构对推理耗时影响极大,YOLOv8s 比 YOLOv5s 慢不少,因为它的检测 head 结构更复杂,NPU 上算子更多。第二,输入分辨率是耗时的指数级因素,从 640 降到 320,推理时间往往能缩到原来的三分之一甚至四分之一。第三,分类模型通常很轻,瓶颈往往根本不在推理,而在图像采集和预处理链路上。

模型选型层面,如果你对帧率有硬指标,建议先用这两种模型做基准测试,再决定手上的模型要不要压缩、蒸馏或者替换。我用 YOLOv8s 跑过一段时间,后来为了帧率换成 YOLOv5s,精度掉了约 2 个点,但帧率提升超过 40%。在边缘 AI 项目里,这个取舍很常见。

3. 数据链路设计:采集、缩放、格式转换的隐形开销

3.1 在 CPU 上做 resize 和 BGR 转换,帧率直接腰斩

这是我自己最常踩的坑,也是最容易被忽略的。模型输入是 640×640 RGB,摄像头出来的通常是 1920×1080 或 1280×720 的 NV12(MIPI 摄像头)或 YUYV(USB 摄像头)。从原始图像到模型输入,中间要经过缩放、颜色空间转换、归一化三步。如果这三步放在 CPU 上做,你会看到:NPU 推理明明只要 30ms,整帧处理时间却要 50ms 以上,CPU 占用率还被拉满,帧率自然上不去。

为什么很多人会掉进这个坑?因为 RK 官方 demo 里经常直接用 OpenCV 的 cv::resize 和 cv::cvtColor,新手照抄过来就是 CPU 预处理。在小分辨率的图片上问题不大,一旦到 1080p 或 4K,CPU 预处理时间就会暴涨。我实测过,1080p NV12 到 640×640 RGB 的转换加缩放,OpenCV 在 CPU 上跑一次大约 16-20ms,这个时间比一个轻量分类模型的完整推理还长。

关键认知是:RK3588 上的 CPU 不是用来做像素搬运的。A76 大核适合跑逻辑复杂、分支多、数据量小的任务,不适合做逐像素操作。图像数据动辄几 MB 到几十 MB,这种量级的操作应该全部交给 RGA 这类专用硬件,把 CPU 省下来给后处理和业务逻辑。

3.2 零拷贝 + RGA:把预处理时间从 18ms 干到 2ms

RK3588 的 RGA 就是专门干这个活的。RGA 支持 NV12、RGB、BGR 等常见格式之间的转换,也支持硬件缩放。正确的链路是:摄像头的 DMA 缓冲区里的帧直接交给 RGA,RGA 硬件缩放成模型需要的分辨率并转换颜色格式,输出直接写进模型输入内存。整个过程不需要 CPU 参与像素拷贝,所以叫零拷贝。

RGA 的调用有两种方式:老的 librga 接口和新的 im2d 接口。现在新项目我建议直接学 im2d,功能更全,接口也更清晰。大致流程是:初始化 rga_context,把输入输出缓冲区信息填好,调用 imresize 或 imcvtcolor,再等待完成。缓冲区最好用 dma-buf 方式分配,这样摄像头驱动、RGA、NPU 之间才能真正共享同一块物理内存。

这里提醒两个坑。第一个是内存对齐。RGA 对地址和宽高有对齐要求,宽度通常是 16 字节对齐,高度 8 字节对齐,地址最好 64 字节对齐。不对齐的情况下 RGA 有时候不报错,但输出图像边缘会出现绿线或者花屏,排查起来特别迷惑。第二个是缓冲区的生命周期管理。零拷贝意味着所有硬件单元共享同一块内存,必须用引用计数或帧池的方式管理缓冲区的复用,防止某一帧还没推理完就被摄像头驱动覆盖了。

我优化一个项目的预处理链路时,把 OpenCV 的 CPU 处理换成了 RGA 零拷贝方案,预处理时间从 18ms 降到了 2ms 左右,整体帧率从 17fps 直接到了 24fps 以上。这个优化是所有帧率优化里面投入产出比最高的一步。

3.3 摄像头帧率、曝光和后端帧率怎么对齐

摄像头帧率和推理帧率不匹配,也会制造帧率难题。比如摄像头只出 25fps,你后端目标设 30fps,那中间必然有几帧要重复或者等待,表现出来就是帧率上不去。反过来,摄像头是 60fps,但模型只能处理 30fps,系统就要决定是丢帧还是排队积压。这两种场景的处理方式完全不同。

我的建议是:先确认输入源帧率的上限,再设定后端目标。边缘视觉系统里最好用“帧间隔驱动”而不是“sleep 驱动”。C++ 里控制帧率,常见的做法是先记录上一帧完成的时间戳,计算距下一帧目标的间隔,再按需等待。这样系统负载高时自动降帧,负载低时自动贴近目标帧率,不会出现帧率卡顿或帧堆积。

曝光也是一个隐性因素。很多摄像头在低照度下会自动拉长曝光时间,如果视觉算法对运动物体敏感,拖影会导致检测精度下降,看起来像是“帧率不稳”,其实是画面质量波动。有条件的话,在摄像头驱动或 V4L2 参数里把曝光模式设为手动,或者设置自动曝光上限,保证单帧曝光时间不超过总帧间隔的一半。比如目标 30fps,单帧总预算 33ms,曝光时间最好控制在 16ms 以内,运动物体才能保持清晰。

4. 帧率忽高忽低:完整排查链路,从打点开始

4.1 第一步,给整条推理链路打点计时

帧率波动的时候,最忌讳的是“直觉式排查”。一会儿怀疑模型转换有问题,一会儿改摄像头参数,折腾半天反而把环境搞乱了。正确做法是先把整条链路拆成“取帧、预处理、推理、后处理、发送或显示”五段,每段打时间戳,跑 1000 帧,统计每段的平均值、最大值和 p99。

打点本身也要注意一个细节:要在 C++ 层做,不要在 Python 层做。Python 的 GIL 和 GC 会干扰时间测量,而且 Python 调用的开销本身就不小。我建议直接在正式代码里加上性能统计模块,用环形缓冲区记录每一段的耗时,再通过日志或接口暴露出来。这样后续调优时,不需要反复改代码加打印,数据积累也更完整。

有了这五段时间,瓶颈基本一眼就能看出来。比如预处理 p99 突然飙到 60ms,大概率是 CPU 竞争或内存抖动;推理时间整体爬升,要看是否触发降频或者 NPU 排队;后处理时间暴涨,多半是检测目标数量太多,NMS 计算量爆炸。不要凭感觉判断,用数据说话。

4.2 第二步,同时盯住 NPU 负载和 CPU 调度

RK3588 上查看 NPU 负载,最简单的方式是读 /sys/kernel/debug/rknpu/load,这个文件会输出各核 NPU 的负载百分比。注意这个文件通常需要 root 权限,而且要确认内核打开了 debugfs。

看数据的方式很清晰:如果 NPU 负载已经到 90% 以上,说明模型的推理时间确实是瓶颈,优化方向是模型压缩、量化、降低输入分辨率;如果 NPU 负载只有 40%,但帧率就是上不去,那问题一定在数据喂入这一侧——采集跟不上、预处理太慢、或者后处理线程堵塞。

CPU 调度方面,RK3588 的大小核架构有个典型问题:A55 小核性能有限,如果后处理线程或采集线程被调度到小核上跑,耗时可能直接翻倍。解决方法是给线程绑核,用 pthread_setaffinity_np 把关键线程绑定到 A76 大核上。我实测过,关键线程不绑核时后处理耗时抖动明显,绑核之后 p99 下降了 30% 以上。接口很简单,就是把线程和 CPU 核心的亲和力设置为指定掩码,代码量很小,收益却很直接。

4.3 第三步,把温度和风扇数据一起打出来

帧率掉了一半,但 NPU 负载也没爆,CPU 也没瓶颈,这时候大概率是高温降频。RK3588 的温控策略是这样的:芯片温度升高到某个阈值后,PMU 会主动降低 CPU 和 NPU 频率来保护芯片。降频之后你看到的帧率就是“阶梯式下降”——跑几分钟稳在 30fps,突然掉到 20fps,再慢慢爬回 30fps,来回循环。

排查方式很简单:循环读 /sys/class/thermal/thermal_zone*/temp,同时记录帧率,把两条曲线对齐看。不同系统的 thermal_zone 编号可能不一样,需要确认哪个 zone 对应 CPU 和 NPU。如果温度一升高,帧率就掉,那就不是算法的锅,而是散热策略的锅。这时候要检查散热片是否贴好、风扇转速是否正常、设备树里的温控阈值是否合理。

这里还有个容易被忽略的点:NPU 高负载运行 10 分钟后的温度表现很可能和刚开机时完全不同。所以帧率测试一定要跑“长时间压力测试”,至少 30 分钟以上,观察温度和帧率是否稳定,短时间测试容易掩盖降频问题。

5. 环境里的隐形杀手:散热、外设和系统服务

5.1 pwm-fan:怎么确认风扇真的在干活

这是散热问题里最具体、也最容易被忽视的一环。很多 RK3588 板卡用 PWM 风扇,设备树里配一个 pwm-fan 节点,系统根据温度自动调速。我接过一个边缘盒子,设备树里配置的调速曲线到 75℃ 才开始满转,而 NPU 在 65℃ 就开始降频了,结果风扇永远是“迟到”的状态。

怎么验证风扇是否正常工作?两个办法。第一,读 /sys/class/hwmon/hwmon*/fan1_input,能读到转速说明测速线工作正常。第二,手动向 /sys/class/hwmon/hwmon*/pwm1 写入不同占空比,观察转速有没有跟随变化。如果 pwm 变了转速不变,要么风扇控制引脚接错,要么风扇本身不支持 PWM 调速。对照开发板的电路原理图检查 FAN0/FAN1 对应的 PWM 引脚,能少走很多弯路。

还有一个进阶操作是 PWM capture。RK3588 的部分 PWM 控制器支持 capture 模式,可以直接测量风扇反馈信号的频率换算出转速。在调试阶段这个功能特别有用,因为有些板卡的 fan1_input 节点没建好,用 capture 模式能独立确认风扇的转动情况。用示波器量 PWM 输入波形也可以,但开发阶段不一定手头有示波器,capture 模式是软件层面的替代方案。

散热策略调好之后,帧率稳定性会有肉眼可见的提升。这个因素很容易被当成“硬件问题”放到一边,但实际上它的影响比很多算法调优都大。

5.2 外设中断、串口日志和显示链路怎么偷偷吃掉帧率

帧率抖动找不到原因的时候,留意一下外设。接在 I2C/SPI 上的外设,比如 ES8388 音频芯片、BMI088 陀螺仪、某些 MIPI sensor,如果驱动写得不完善,或者中断触发过于频繁,会持续抢占 CPU 资源。我遇到过一接上陀螺仪帧率就掉 3-5fps 的情况,查了半天发现是 sensor 的中断没有做去抖处理,每次触发都唤醒 CPU 执行不必要的回调函数。

系统服务也是个大坑。有些边缘 AI 盒子出厂自带图形桌面(XFCE、Unity 之类),桌面合成器会周期性占用 CPU,哪怕没人操作。实际部署时我一般建议直接关掉桌面,跑纯命令行模式,CPU 占用能降低 10-20%。这个优化最简单,效果却是立刻见效的。

还有显示链路。开机日志里的 RK3588 can't find suitable delayline 这类提示,通常不影响推理主流程,但它表示显示子系统在查找显示时序参数时出了问题。如果你的方案里同时要做本地预览,这条显示链路异常可能抢占内存带宽或显示带宽,间接拖累帧率。另外,刷机时用 recovery/maskrom 模式连接 RKDevTool,要注意 loader 文件(比如 RK3588_miniloader.bin)和系统镜像版本要匹配。我之前用错版本刷过一次机,系统能启动但 NPU 驱动工作异常,推理时间直接翻倍,排查了很长时间才怀疑到系统镜像身上。

6. 可以直接抄的调优清单和实测数据参考

6.1 三个典型场景的推荐配置

根据不同项目的目标,我把配置方向拆成三类。

实时视频监控、多路流分析:优先保证吞吐量。用 MPP 硬编码加 RTSP/RTMP 推流,摄像头接入用 V4L2 加 RGA 做预处理,模型用 INT8。线程拆分要明确:采集线程专管取帧,推理线程专管 NPU,发送线程专管编码推流。这样一个典型的 4 路 1080p 实时分析方案,能做到不掉帧稳定运行。

视觉引导定位:优先保证低延迟和稳定性。输入分辨率可以降到 640×480 甚至更低,模型选轻量级,曝光手动锁定,关键线程绑核,关闭所有非必要系统服务。定位类任务还要特别注意帧时间戳对齐,保证机械臂控制器拿到的位置信息是“当前帧时刻”的位置,而不是延迟了几十毫秒的旧位置。这个时间对齐问题,比单纯的帧率数字更影响抓取精度。

轻量分类、web 端推理服务:优先吃满 NPU。EfficientNetV2-S 这类轻量模型在 RK3588 上单帧推理只要几毫秒,单位时间能处理的图片数量很大,可以考虑 batch 推理。RKNN 的 C API 和 Python API 都支持批量输入,把多路请求拼成 batch 再一次性推理,NPU 利用率能显著提升。

6.2 一个项目的调优前后对比

最后放一组我自己项目的数据(YOLOv8s INT8,1080p 输入,模型输入 640×640,同时做 RTSP 推流):

项目状态预处理耗时推理耗时后处理耗时端到端帧率
初始版本(CPU 预处理、不绑核、默认风扇策略)约 18ms约 40ms约 12ms约 17fps
优化后(RGA 零拷贝、线程绑核、散热策略修正)约 2ms约 40ms约 6ms约 24fps

注意推理耗时基本没变,因为瓶颈不在 NPU,整体帧率提升主要来自预处理的硬件化和后处理耗时下降。这再次验证了那句话:帧率是一条链路问题,不是单点问题。如果我只优化模型而不管数据链路,这个项目可能至今还停在 17fps。

还有个小经验:调优帧率的时候,建议把系统负载一起记录下来,不要在空载状态下测。我调好参数后,空载测 30fps 很稳,一接多路视频流就掉到 22fps,后来才发现是内存带宽饱和。确保用固定的负载场景去对比,相同的数据源、相同的模型、相同的推流路数,这样测出来的数据才有可比性。最后我习惯把整条链路在压力状态下的 p99 数据也一并存档,客户问起来“帧率稳不稳”时,直接甩数据比解释半天更有说服力。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 16:10:42

Obsidian同步方案全解析:五大主流方法实测与选型建议

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

作者头像 李华
网站建设 2026/9/7 16:09:05

需求是意图,QA是证据:从需求到测试证据的完整链路

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

作者头像 李华
网站建设 2026/9/7 16:08:54

批量替换文件夹名关键字的完整实践:Java与PowerShell双实现

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

作者头像 李华
网站建设 2026/9/7 16:08:39

Cat-Catch:支持 HLS/DASH 合并下载的浏览器资源嗅探扩展

Cat-Catch:支持 HLS/DASH 合并下载的浏览器资源嗅探扩展 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch Cat-Catch(猫抓&am…

作者头像 李华