news 2026/9/4 3:05:54

本地免费AI视频整合包:原理、模块与部署排错全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
本地免费AI视频整合包:原理、模块与部署排错全解析

最近很多做短视频、直播切片和二次创作的朋友都在问:市面上那些“加速补光修脸修色补帧、多人动作和背景替换、AI动作迁移和角色替换”的视频处理工具,能不能在本地免费跑起来?

答案是可以的。现在很多社区作者会把多个开源模型和脚本封装成一个“一键绿色懒人整合包”,双击启动、本地推理、无需联网、不限抽卡次数。这类整合包看起来像个黑盒,但内部原理其实并不复杂:无非是把画质修复、补帧、姿态驱动、人像分割、调色等几类开源模型组合成一条视频处理流水线。

我自己研究这类本地工作流时,也踩过不少坑:有的整合包换台电脑就闪退,有的模型权重下了一半就断,有的处理完视频人脸崩坏、动作跳帧。这促使我把整套流程拆开研究了一遍。本文我会围绕本地AI视频/图像整合包的部署思路,讲清楚功能模块、环境搭配、启动脚本、抽卡套路和常见报错,并给出可复制的本地处理方案。如果你也想搞清楚这类工具背后是怎么工作的,或者打算自己组装一套本地工作流,这篇文章很值得收藏。

1. 这类“整合包”到底是什么

很多人第一次看到“一键整合包”这个名字,会误以为它是一个独立的商业软件,或者某个官方发布的工具。其实更准确地说,它是一个“为特定业务目标打包好的本地AI工具集合”。

从技术组成来看,一个典型的整合包通常包含三部分:

  1. 开源模型:负责具体的能力,比如人脸修复、姿态识别、背景替换、视频插帧。这部分往往是免费开源的,不同功能对应不同模型。
  2. WebUI或命令行工具:把模型包装成可交互页面或脚本,方便不懂代码的人调用。
  3. 批处理脚本和启动器:自动配置 Python、依赖库、模型路径、显存选项,实现“双击运行”。

这类工具解决了什么问题呢?

首先是免费。很多云端AI视频工具按次收费,处理一段几分钟的视频费用不低,而本地部署只需要自己出电费和硬件损耗。 其次是隐私。素材不出本机,不用担心上传到云端带来的版权和隐私顾虑。 最后是批量可控。本地工作流可以无限生成,反复抽卡,这是云端按量计费很难做到的。

但请注意,整合包不是“官方产品”,包内的模型、脚本、权重文件通常来自不同开源项目,协议差异很大。使用前建议确认其开源协议和模型权重来源,避免拿去商用后产生版权风险。后面我会单独用一节讲合规问题。

2. 功能模块与技术原理拆解

项目标题中提到的功能很多,其实可以拆成六个技术方向。理解它们各自属于哪类模型,排错时才有方向。

2.1 加速补光、修色与画质修复

“加速补光”听上去很玄,其实是两个动作:

  • 提高视频帧率、补足动态模糊,这是补帧。
  • 对画面亮度、白平衡、对比度进行校正,这是调色。

“修脸修色”在AI工具里通常指对人脸区域进行增强。常见开源思路是先用目标检测框出人脸,再用GAN类的修复模型重建人脸细节。经典的模型包括 GFPGAN、CodeFormer 等。这类模型擅长把模糊、过暗、低分辨率的人脸恢复成较清晰的状态,但使用倍数不宜过高,否则会出现“塑料感”。

下面这行代码是一个典型的人脸修复调用思路。需要说明的是,不同开源仓库命令差异很大,这里只是演示逻辑,不要直接照搬:

python inference_codeformer.py \ --input_path ./inputs/face \ --output_path ./results/face \ --w 0.7 \ --has_aligned \ --face_upsample

参数中的w用于控制“保留原图和重构之间的平衡度”。w越大,人脸越贴近模型重新生成的结果,修复越彻底,但也可能丢失更多原图特征。

2.2 补帧:让动作连贯的关键

视频补帧,本质上是在两帧之间生成中间帧,让画面从 24fps 变成 48fps、60fps 甚至更高。动作迁移类模型处理出来的视频帧率往往不高,通过补帧能明显提升流畅度,也方便后续剪辑。

目前应用较多的是基于光流或者基于神经网络的插帧模型。社区常见的名称如 RIFE、IFRNet 等,但具体以整合包内置的脚本为准。补帧有两种处理方式:

  • 直接补帧生成视频。
  • 先抽帧再补帧再合成。

对于动作迁移类的多人视频,更推荐先逐帧处理完(修脸、换背景),最后再做视频补帧。这样能减少模型间的互相干扰,处理链更稳定。

2.3 多人动作迁移与角色替换

这是整合包最吸引人的功能,也是技术原理最复杂的部分。

动作迁移可以这样理解:给模型一张“角色参考图”,再给一段“动作姿态序列”,模型在理解人物外貌特征的同时,把参考图的角色渲染成目标动作。它涉及姿态估计、扩散生成、视频时序一致性等多个任务。多人动作迁移则是在单人的基础上,增加多目标跟踪和多人姿态分离的问题。

角色替换与动作迁移不同。动作迁移是“同一个人或同一个角色做新动作”,角色替换则是“把A的外貌贴到B的动作或姿态上”。不过在很多整合包里,两者常常混用,界面上可能都叫“换人”。

关键区别如下:

能力输入输出常见技术方向
动作迁移人物参考图 + 动作视频/姿态序列参考角色做目标动作姿态引导的扩散生成
角色替换原视频 + 新角色参考图保留动作/场景,替换人脸或外观人脸重建/视频重渲染
多人动作多人视频 + 姿态分离多角色分别驱动的合成视频多人姿态估计 + 单角色生成循环

这类功能对显卡显存要求很高。实际跑超过 1 个人物时,处理时间和显存占用会成倍增长。若整合包标明“多人动作和背景替换”,你需要重点确认显卡显存是否足够。

2.4 背景替换

背景替换一般走两条路线:

  • 传统分割路线:用语义分割模型把人、物、背景拆开,再合成新背景。
  • 生成式路线:通过图像生成模型重绘背景区域,但很容易导致人物边缘变形。

在视频处理中,为了保证人物边缘不闪烁,通常需要按帧处理后再做时间上的平滑处理。整合包的稳定表现,往往不是因为某个模型有多强,而是在边缘平滑和关键帧策略上做了不少工程优化。

2.5 无限抽卡:并不是“无限制随机”

很多人把“无限抽卡”理解成无限随机生成。其实在本地视频整合包语境下,它更接近“批量生成候选结果 + 人工挑选”的交互思路。

实现抽卡通常有两种方式:

  1. 固定业务流程,随机参数化:随机改变随机种子、修复强度、调色强度、补帧倍数等参数,生成多份结果供挑选。
  2. 先生成缩略预览,再选择性高清放大:先以小分辨率、短片段抽卡,觉得满意后再执行完整高分辨率流程。

上面第二种其实是工程上的重要策略。AI视频生成耗时不短,如果每次抽卡都全分辨率、完整时长跑一遍,效率会很低。聪明的整合包会先抽几个关键帧生成预览图,确认构图和动作OK,再进行全片渲染。

我强烈建议你平时使用这类工具时,也养成“先预览、后精修”的习惯。

3. 环境准备:本地部署的硬件与系统要求

项目标题中没有给出具体版本,因此下面的版本说明以常见整合包为参考。具体版本请以你拿到的整合包说明文档为准。

核心环境如下:

项目建议配置说明
操作系统Windows 10/11 64位 或 Ubuntu 20.04+大多数整合包以 Windows 为主
显卡NVIDIA 显卡,显存 8GB 以上画面修复至少 4GB,多人动作迁移建议 12GB+
显卡驱动最新稳定版不要用过旧驱动
CUDA视模型依赖而定常见为 CUDA 11.8 或 12.1
Python3.10 或 3.11很多仓库优先支持这两个版本
内存16GB 起步,32GB 更稳视频预加载时内存占用很高
磁盘至少预留 30GB模型文件动辄几个GB,处理过程还会产生大量中间帧

如果你没有 NVIDIA 显卡,AMD 或者 Apple Silicon 的电脑也不是完全不能用,但很多整合包默认只适配 NVIDIA 的 CUDA 生态,需要你自己找对应分支,折腾成本较高。

另外,所有AI相关整合包都强烈建议关闭 Windows 的实时杀毒或为目录添加白名单,否则一些PyInstaller打包出来的exe或Python依赖容易被误报。下载和运行前最好校验哈希,确认文件来自可信来源。

4. 认识你的整合包目录结构

拿到一个本地一键整合包后,不要急着双击启动,先看目录。大多数整合包目录结构类似下面这样:

VideoAI_Studio/ ├─ 启动.exe / start.bat ├─ python/ ├─ models/ │ ├─ face_restore/ │ ├─ pose/ │ └─ segmentation/ ├─ scripts/ │ ├─ preprocess.py │ ├─ restore_face.py │ ├─ frame_interpolation.py │ └─ compose_video.py ├─ inputs/ ├─ outputs/ └─ config/

解释一下各目录的作用:

  • python/:整合包自带的独立Python环境,不干扰系统Python。
  • models/:放各种模型权重文件,通常很大。
  • scripts/:核心处理脚本。
  • inputs/outputs/:默认输入输出目录。
  • config/:存放各类参数配置。

理解这个结构后,你至少可以做三类事情:

第一,遇到报错时能快速判断是缺模型、缺依赖还是脚本问题。 第二,想更换新版本模型时,可以按目录名对应替换。 第三,你想改造批处理流程,或增加自定义功能时,可以找到对应脚本位置。

以 Windows 启动脚本为例,一个简化版start.bat往往长这样:

@echo off chcp 65001 >nul set BASE_DIR=%~dp0 cd /d "%BASE_DIR%" echo 正在检测Python环境... if exist "%BASE_DIR%python\python.exe" ( echo 使用内置Python "%BASE_DIR%python\python.exe" "%BASE_DIR%scripts\launcher.py" ) else ( echo 未找到内置Python,尝试使用系统Python python "%BASE_DIR%scripts\launcher.py" ) pause

这个脚本做的事情很简单:先切换到当前脚本所在目录,检测内置Python是否存在,存在就优先使用内置环境,否则退回系统Python。这样做的好处是——不会因为用户机器上Anaconda、系统Python版本太乱导致启动失败。

所以“绿色版”通常不是指真的不写入注册表,而是指把整个依赖栈带在目录里,移走即删,不影响系统环境。

5. 核心处理流程:从原始视频到成片

不管整合包界面做得多漂亮,后台核心处理逻辑基本都是同一套。下面我用一个可运行的流程示例来说明——假设我们要对一段源视频做人脸修复、背景替换、调色、补帧,并最终导出成片。

5.1 建立项目目录

先在整合包根目录下创建一个实验项目:

projects/demo_01/ ├─ source.mp4 # 原始视频 ├─ frames/ # 抽出的原始帧 ├─ processed/ # 处理后的帧 ├─ output/ # 导出目录 └─ temp/ # 中间缓存

5.2 按帧导出视频

视频处理的第一步通常是抽帧。基于OpenCV的抽帧脚本在大多数Python环境中都可运行:

# scripts/extract_frames.py import cv2 import os video_path = "projects/demo_01/source.mp4" frames_dir = "projects/demo_01/frames" os.makedirs(frames_dir, exist_ok=True) cap = cv2.VideoCapture(video_path) if not cap.isOpened(): raise RuntimeError(f"无法打开视频: {video_path}") fps = cap.get(cv2.CAP_PROP_FPS) total = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) print(f"视频帧率: {fps:.2f}, 总帧数: {total}") count = 0 while True: ret, frame = cap.read() if not ret: break # 6位数字命名,方便排序 cv2.imwrite(os.path.join(frames_dir, f"frame_{count:06d}.png"), frame) count += 1 if count % 200 == 0: print(f"已导出 {count}/{total} 帧") cap.release() print(f"抽帧完成,共 {count} 张")

抽帧的意义在于:很多图像级AI模型只能一张一张处理图片,无法直接读视频。逐帧处理后,再用最终合成步骤把帧拼接回视频。这样既灵活,也好针对处理失败的帧单独重跑。

5.3 对画面做修复与调色

这一步是整合包中“修脸修色”的实现核心。下面代码只是为了说明逻辑,实际应用中你会调用包内集成的GFPGAN或CodeFormer,而不是自己写修复网络。

# scripts/image_enhance_pipeline.py from PIL import Image, ImageEnhance, ImageFilter import os def enhance_image(input_path, output_path, brightness=1.1, color=1.05, sharpen_radius=2, sharpen_percent=150): """亮度调节、色彩增强、锐化处理""" img = Image.open(input_path) # 调整亮度,模拟补光 img = ImageEnhance.Brightness(img).enhance(brightness) # 调整色彩饱和度 img = ImageEnhance.Color(img).enhance(color) # 轻度锐化 img = img.filter(ImageFilter.UnsharpMask( radius=sharpen_radius, percent=sharpen_percent, threshold=3 )) # 可选:高分辨率放大,使用 Real-ESRGAN 等模型时单独调用 img.save(output_path) return output_path frames_dir = "projects/demo_01/frames" processed_dir = "projects/demo_01/processed" os.makedirs(processed_dir, exist_ok=True) names = sorted(os.listdir(frames_dir)) for name in names: if not name.endswith(".png"): continue enhance_image( os.path.join(frames_dir, name), os.path.join(processed_dir, name), brightness=1.08, color=1.03 ) print("调色与锐化完成")

注意:上面的代码只能做基础调色和锐化,不是真正的AI修复。真正的AI人脸修复需要调用训练好的生成模型,很多整合包在WebUI里会有“人脸修复倍数”“增强系数”等参数,原理就是先把人脸区域裁剪出来,用GAN模型修复,再放回原图并做边缘融合。是否调用以及调用的参数由配置文件控制。

5.4 背景替换的分割思路

背景替换需要“分割”能力。下面是一个使用分割模型的基本调用思路。以常见的分割工具库为例,代码看起来会是这样的:

# scripts/segmentation_example.py """ 背景替换思路演示。 这里以 segmentation pipeline 为示例,实际模型路径需按整合包内模型调整。 """ import numpy as np def replace_background(frame, mask, new_background): # mask: 0表示背景, 1表示前景 mask_3 = np.stack([mask, mask, mask], axis=-1) result = frame * mask_3 + new_background * (1 - mask_3) return result # 实际使用时,你需要先加载分割模型得到 mask # mask = model.predict(frame)["person"] # 这一步涉及模型权重加载和预处理,不同仓库差异较大

理解上面的思路就好。背景替换的难点不是“把新背景拼上去”,而是如何得到稳定、边缘不发光的 mask。处理视频时,如果一帧一帧用不同mask,人物边缘会出现抖动甚至闪烁,这也是为什么很多成品工具会引入时间平滑。

5.5 补帧与视频合成

处理完全部帧后,就需要把帧重新合成视频,再执行补帧。合成视频可借助FFmpeg:

ffmpeg -r 30 -i projects/demo_01/processed/frame_%06d.png -c:v libx264 -pix_fmt yuv420p projects/demo_01/output/result_30fps.mp4

你不需要背这条命令,只需知道几个关键点:

  • -r 30:强制输出帧率为30fps。
  • -i后面的路径格式要与抽帧命名一致。
  • -c:v libx264:使用H.264编码,通用性好。
  • -pix_fmt yuv420p:保证兼容大部分播放器。

合成出视频后,如果还需要补帧到60fps,有两种方案:

第一种:合成低帧率视频后,调用补帧模型处理整个视频。 第二种:在脚本里对相邻两次帧进行插补,再重新合成。

后一种可以做到任意倍率插帧,但需要专门的插帧模型。很多补帧模型要求输入视频路径和输出视频路径,典型的命令行风格如下:

python inference_rife.py --video projects/demo_01/output/result_30fps.mp4 --output projects/demo_01/output/result_60fps.mp4 --multiplier 2

不同整合包命令不一致,“multiplier”这类参数也可能叫“exp”(倍数),需要以实际包内脚本为准。

5.6 编写批处理串起整个流程

到这里,你已经理解了全流程:抽帧 → 修复调色 → 分割/替换/动作处理 → 合成 → 补帧。把这些步骤串成一个脚本,是“一键式”背后的核心逻辑。

# scripts/run_pipeline.sh #!/bin/bash set -e python scripts/extract_frames.py python scripts/image_enhance_pipeline.py python scripts/apply_segmentation.py python scripts/compose_video.py python scripts/frame_interpolation.py --multiplier 2 echo "处理完成,结果输出到 output 目录"

一套好的整合包,本质上就是给用户把这些串联步骤封装成了界面按钮而已。一旦你理解了底层流程,遇到“某个功能没有效果”“处理到一半失败”时,排查思路会清晰很多:先定位是抽帧问题、模型推理问题还是视频合成问题。

6. 常见问题与排查思路

本地AI处理工具永远伴随着各种环境问题,这里整理一个高频问题表:

问题现象常见原因解决思路
双击启动后闪退缺Visual C++运行库、路径含中文或空格、模型未下载完整先看启动日志,安装运行库;把路径改为纯英文目录;重新校验模型
报CUDA out of memory显存不足降低分辨率、关闭背景替换或多人物同时处理;将处理任务拆分为多个小批次
人脸修复效果过假增强倍数过大降低人脸修复的“w”参数,或关闭深度融合只做轻度修复
背景替换边缘闪烁单帧分割不稳定、没有时序平滑调低阈值,启用整合包提供的时序平滑/关键帧插值选项
运行到一半卡住内存不足、临时文件过多扩展swap/虚拟内存,清理temp目录
模型加载很慢权重文件放在机械硬盘把模型目录移动或复制到SSD上
处理完视频没有声音AI处理流程只处理画面高质量加工时单独保留原视频音轨,用FFmpeg最后合并音画
杀毒软件误报exe打包器特征被误判在信任来源确认前提下添加白名单;获取源码自行打包更安全

这里重点说一下“运行到一半卡住”和“处理完没有声音”。

运行到一半卡住,多数不是死机,而是Windows假死。AI推理时显存占满、内存又不够,系统可能无响应数分钟。你可以在任务管理器里观察GPU和内存占用,如果Python进程仍在读盘、操作GPU,就耐心等待;如果CPU占用变0且持续不动,才是真的进入异常状态。

没有声音这个问题很典型。很多工具只做了“视频帧处理”,拿到AI生成的人脸视频后再补帧,却忘了保留原视频的音轨。遇到这种情况,直接把原视频和AI处理后的无声视频做一次音画合并即可:

ffmpeg -i original.mp4 -i processed_silent.mp4 -map 0:a? -map 1:v -c:v copy -c:a aac -shortest output_with_audio.mp4

需要注意先确认两个视频时长是否一致,如果不一致建议以帧数对齐后的版本为准。

7. 使用这类工具的合规建议与版权边界

这是在使用整合包时很容易忽略但非常重要的一部分。

首先,整合包里的模型、权重并非全部可以随意商用。开源协议常见有MIT、Apache 2.0、GPL等,也有只允许科研使用的协议。GFPGAN、CodeFormer这类修复模型可以用于个人老照片修复,但当用于商业化修图服务时,要检查模型的具体授权条款。

其次,人物肖像权问题在动作迁移、角色替换类功能中尤为突出。把真实人物图片作为输入生成内容,要获得本人授权;将明星、公众人物等照片用于生成式内容,更可能涉及人格权侵权。即便工具本身是免费的,也不能把“免费模型”等同于“可以任意使用他人肖像”。

再有一点容易被忽略:模型权重文件的来源决定了安全边界。不少整合包为了压缩体积,会把权重文件放在网盘分享链接里,被恶意替换的情况屡见不鲜。下载权重后推荐先做哈希校验。安全起见,优先从官方GitHub仓库下载原始权重,再按整合包要求的目录结构放置。我个人的习惯是:官方没有放出明确授权声明、且解析脚本不开源的整合包,一律不进生产环境。

这也解释了为什么项目标题强调“免费开源模型部署”。开源是指你可以看到实现代码、可以审查它到底做了什么,这比闭源黑盒工具安全得多。

8. 如何维护你的整合包环境

拿到整合包并成功跑通一次后,推荐你做以下几件事,能省掉后面很多意外:

  1. 为关键配置建立快照:首次调好各项参数后,把config目录备份一份。
  2. 单独管理模型目录:不要随便删除models目录里的文件,即使你不确定用途。可以先移出测试,能够正常运行再清理。
  3. 关注模型更新和版本说明:整合包社区更新很快,新版本可能修复已知bug,也可能改变参数格式。升级前先看更新日志文档,并把旧版本目录完整保留。
  4. 留意Python依赖之间的互相影响:如果整合包提供requirements.txt,不建议随意执行pip install,因为不同模型之间可能对同一种库有不同版本要求——比如某个模型需要numpy 1.x,另一个模型需要2.x。此时最好的做法是使用虚拟环境或整合包自带隔离环境。
  5. 固定输入输出的路径规范:所有输入文件统一放到inputs目录,别名不要带空格和中文。Windows下有些依赖库对中文路径支持不好,哪怕现在能跑,不同版本也容易出问题。

9. 几个可以继续深入的方向

如果你已经跑通一个整合包,想做更进一步的学习,可以从这几个方向着手:

  • 学习人脸修复模型的结构:观察GFPGAN和CodeFormer在“真实场景退化”和“人脸重构”上的不同表现,并调节参数理解它们之间互相制衡的关系。
  • 研究动作迁移的时间一致性:单帧生成效果很好不代表视频不闪。解决视频闪烁是AI视频落地中最有工程价值的难题之一。
  • 尝试自己组装一条简化流水线:使用FFmpeg实现抽帧和合成,用Python调用开源修复模型处理人脸,再用补帧模型生成流畅视频。即使每一步都很基础,组装过程中你会被迫理解所有接口的细节。
  • 掌握FFmpeg基础命令:视频处理中FFmpeg是隐藏主角,无论抽帧、合成、音频合并还是压缩,都需要它。

如果你觉得本文讲清楚了这类整合包的原理和使用思路,可以收藏备用,后续折腾的时候遇到问题回来查一查,应该能少走不少弯路。

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

NSGA-II多目标优化算法Matlab工具箱:从原理到实战应用

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

作者头像 李华
网站建设 2026/9/4 3:05:11

Grok Build v1.0.14发布解析:CLI可靠性提升与工作流改进

这两年做 AI 编程、Agent 工作流、自动化构建的开发者,大概都有过一个很熟悉的瞬间:工具本身很强,但它在命令行里突然报错、中途断掉、配置找不对路径,导致整条流水线卡死。这种体验在 Cursor、Codex CLI、各类 AI CLI 工具里反复…

作者头像 李华
网站建设 2026/9/4 3:03:30

手机摔了、泡了、冻了之后,怎么判断还能不能用?

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

作者头像 李华
网站建设 2026/9/4 3:03:13

微信小程序商城订单状态机、支付回调与超时关单实战解析

如果只把“珠宝首饰交易小程序”理解成一个小程序壳子加一个 Vue3 管理后台,那项目推进到一半大概率会卡住。卡住的点通常不是某个三级页面没做出来,也不是路由没配通,而是订单状态一多、支付回调一进来、超时关单一开启,整套流程…

作者头像 李华
网站建设 2026/9/4 3:02:32

监控摄像头+BirdNet-Go:构建无人值守鸟类自动识别系统

如果你也在做类似的户外声音监测项目,你会发现一个很现实的断层:模型识别很容易,持续无人值守地采集和判断很难。用监控摄像头搭鸟类自动识别系统,核心难点并不在“认鸟”。BirdNET 这类模型已经能把“这段音频里是什么鸟”这件事…

作者头像 李华
网站建设 2026/9/4 3:02:16

AI视频生成模型Flux 3本地部署与工程实践指南

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

作者头像 李华