FFmpeg自动化视频剪辑:批量裁剪片头片尾的脚本实现
在实际的视频剪辑工作中我们常常会遇到一些看似简单的需求比如“把这段视频的片头和片尾去掉”、“把中间这段静音的部分剪掉”或者“把几个短视频合并成一个”。对于有经验的剪辑师这些操作可能确实“一秒都不用剪”因为他们熟练掌握了工具和流程。但对于初学者或临时需要处理视频的开发者来说手动打开专业软件、寻找功能、导出视频整个过程可能比写代码还耗时。本文将从一个开发者的视角探讨如何利用脚本和开源工具实现真正“一秒都不用剪”的自动化视频处理。我们将聚焦于一个非常实用的场景批量、自动地裁剪视频的片头片尾。通过编写一个简单的命令行脚本结合强大的 FFmpeg 工具实现指定文件夹内所有视频的自动化处理从而将重复性劳动降至零。无论你是需要处理会议录像、课程视频还是自媒体素材这套方法都能显著提升效率。1. 理解“一秒都不用剪”背后的自动化思路“一秒都不用剪”听起来像是个夸张的说法但其核心思想是将固定的、重复的剪辑规则转化为可执行的程序逻辑。手动剪辑之所以耗时是因为你需要用眼睛看、用手拖动时间轴、用鼠标点击导出。而自动化剪辑则是提前告诉计算机你的规则。1.1 自动化剪辑的关键组件要实现自动化我们需要三个核心部分视频处理引擎一个能够精确读取、修改和输出视频文件的命令行工具。这里我们选择FFmpeg它是一个完整的、跨平台的解决方案用于录制、转换以及流化音视频几乎支持所有格式是多媒体处理领域的“瑞士军刀”。规则定义你需要明确告诉程序“剪哪里”。例如“每个视频都去掉前5秒和后10秒”。这个规则可以很简单固定时长也可以很复杂基于音频静音检测、场景变换分析等。执行脚本一个能够遍历文件、调用FFmpeg、并处理可能错误的程序。我们可以用 Shell 脚本Bash、Python 或任何你熟悉的脚本语言来编写。1.2 为什么选择 FFmpeg 和脚本FFmpeg 能力强大它不仅能裁剪还能合并、转码、压缩、提取音频、添加水印、调整分辨率等。学习它的基本命令就等于掌握了命令行视频处理的基石。脚本可重复且可扩展今天你写了一个裁剪片头片尾的脚本明天你可以轻松修改它让它同时压缩视频体积或者批量添加片尾字幕。一次编写无限次使用。易于集成脚本可以放在服务器上定时运行如处理每日上传的视频也可以集成到你的CI/CD流程中作为内容发布流水线的一环。2. 环境准备安装 FFmpeg 与创建工作区在开始编写脚本之前我们必须确保 FFmpeg 在系统中可用。2.1 安装 FFmpegWindows 用户访问 FFmpeg 官网的下载页面。下载适用于 Windows 的静态构建版本例如ffmpeg-release-essentials.zip。解压到某个目录例如C:\ffmpeg。将C:\ffmpeg\bin添加到系统的环境变量PATH中。打开命令提示符CMD或 PowerShell输入ffmpeg -version如果显示版本信息则安装成功。macOS 用户使用 Homebrew 安装是最简单的方式brew install ffmpeg安装后在终端输入ffmpeg -version验证。Linux 用户如 Ubuntu/Debian使用 apt 包管理器安装sudo apt update sudo apt install ffmpeg同样使用ffmpeg -version验证。2.2 创建项目工作目录为了工作清晰建议创建一个专门的项目目录来存放脚本、原始视频和处理后的视频。mkdir -p ~/projects/auto-video-trim cd ~/projects/auto-video-trim mkdir input_videos output_videosinput_videos: 用于存放待处理的原始视频文件。output_videos: 用于存放脚本处理后的视频文件。3. 核心实现编写自动化裁剪脚本我们将使用 Bash Shell 脚本在 Windows 下可使用 Git Bash 或 WSL 运行来实现。它的逻辑是遍历input_videos文件夹中的所有视频文件对每个文件使用 FFmpeg 裁剪掉指定的片头和片尾然后将结果保存到output_videos文件夹。3.1 脚本代码详解创建一个名为auto_trim.sh的文件并输入以下内容#!/bin/bash # # 自动视频裁剪脚本 (Auto Video Trimming Script) # 功能批量裁剪输入视频的片头与片尾 # # 1. 定义变量 (Configuration) INPUT_DIR./input_videos OUTPUT_DIR./output_videos # 定义要裁剪的时长单位秒 TRIM_START5 # 片头裁剪时长例如去掉前5秒 TRIM_END10 # 片尾裁剪时长例如去掉后10秒 # 支持的视频文件扩展名可根据需要添加 VIDEO_EXTS(mp4 mov avi mkv flv wmv) # 2. 创建输出目录如果不存在 mkdir -p $OUTPUT_DIR # 3. 遍历输入目录中的所有文件 for file in $INPUT_DIR/*; do # 检查是否为文件 if [ -f $file ]; then # 提取文件名和扩展名 filename$(basename -- $file) extension${filename##*.} filename_noext${filename%.*} # 检查文件扩展名是否在支持的列表中 is_videofalse for ext in ${VIDEO_EXTS[]}; do if [ $extension $ext ]; then is_videotrue break fi done if [ $is_video false ]; then echo [跳过] 非视频文件: $filename continue fi echo [处理中] 开始处理: $filename # 4. 使用 FFmpeg 获取视频总时长 # 注意这里使用 -v error 抑制冗余输出-show_entries formatduration 获取时长 duration$(ffprobe -v error -show_entries formatduration -of defaultnoprint_wrappers1:nokey1 $file) # 将时长从字符串转换为浮点数进行计算使用bc命令 total_duration$(echo $duration | bc -l) # 5. 计算裁剪后的结束时间点 # 新时长 总时长 - 片头 - 片尾 end_time$(echo $total_duration - $TRIM_END | bc -l) # 实际裁剪区间从 TRIM_START 秒开始到 end_time 秒结束 start_time$TRIM_START # 6. 执行 FFmpeg 裁剪命令 # -ss: 指定开始时间点 # -to: 指定结束时间点注意-to 是基于原视频的时间点不是持续时间 # -c copy: 使用流复制模式避免重新编码速度极快但要求裁剪点必须在关键帧上。 output_file$OUTPUT_DIR/${filename_noext}_trimmed.${extension} ffmpeg -i $file -ss $start_time -to $end_time -c copy $output_file 2/dev/null # 7. 检查命令执行结果 if [ $? -eq 0 ]; then echo [成功] 输出文件: ${filename_noext}_trimmed.${extension} else echo [失败] 处理文件时出错: $filename # 如果流复制失败可能因为关键帧问题尝试重新编码速度慢但可靠 echo [重试] 尝试使用重新编码模式... ffmpeg -i $file -ss $start_time -to $end_time $output_file 2/dev/null if [ $? -eq 0 ]; then echo [成功] 通过重新编码完成: $filename else echo [严重错误] 无法处理文件: $filename fi fi fi done echo echo 批量处理完成请检查 $OUTPUT_DIR 目录。 echo 3.2 关键代码与参数解析配置变量 (TRIM_START,TRIM_END)这是脚本的核心规则。修改这两个变量的值就能定义所有视频统一的裁剪规则。例如设置TRIM_START10和TRIM_END5表示去掉每个视频的前10秒和后5秒。FFprobe 获取视频时长ffprobe是 FFmpeg 套件中用于分析多媒体文件流的工具。-show_entries formatduration用于获取视频的总时长秒。我们使用bc -l命令进行浮点数计算因为视频时长通常是小数。FFmpeg 裁剪命令-i “$file”指定输入文件。-ss start_time从原视频的start_time秒处开始截取。-to end_time截取到原视频的end_time秒处结束。-c copy这是关键参数。它指示 FFmpeg 进行“流复制”stream copy即不重新编码视频和音频流只是将数据包从输入文件复制到输出文件。这速度极快几乎是瞬间完成且质量无损。但它有一个限制裁剪的开始时间-ss必须落在关键帧I-frame上否则实际开始时间会提前到最近的一个关键帧。错误处理与降级方案脚本首先尝试最快的-c copy模式。如果失败退出状态码$?非零则很可能是关键帧问题。脚本会自动降级到不使用-c copy的模式这会触发重新编码速度慢很多但能确保在任意时间点精确裁剪。2/dev/null用于将 FFmpeg 的标准错误输出重定向到“空设备”从而在脚本运行时隐藏 FFmpeg 冗长的进度和信息日志让输出更清晰。调试时可以去掉它。4. 运行验证与结果分析4.1 准备测试视频将你需要处理的视频文件如my_video.mp4,lecture.mov放入之前创建的input_videos文件夹中。4.2 运行脚本在终端中确保位于脚本所在目录然后运行# 首先给脚本添加执行权限Linux/macOS chmod x auto_trim.sh # 执行脚本 ./auto_trim.sh对于 Windows Git Bash 用户同样可以使用./auto_trim.sh命令运行。4.3 验证输出脚本运行后你会在终端看到类似如下的输出[处理中] 开始处理: my_video.mp4 [成功] 输出文件: my_video_trimmed.mp4 [处理中] 开始处理: lecture.mov [成功] 输出文件: lecture_trimmed.mov 批量处理完成请检查 ./output_videos 目录。 此时打开output_videos文件夹你应该能看到处理好的视频文件。用播放器打开检查片头和片尾是否已被正确裁剪。4.4 验证裁剪精度为了确认裁剪是否精确你可以再次使用ffprobe检查输出视频的时长ffprobe -v error -show_entries formatduration -of defaultnoprint_wrappers1:nokey1 ./output_videos/my_video_trimmed.mp4计算出的时长应该等于原时长 - TRIM_START - TRIM_END。5. 常见问题排查与优化即使是一个简单的脚本在实际运行中也可能遇到各种问题。下面是一个排查指南。5.1 问题一脚本执行报错 “ffmpeg: command not found”现象运行脚本时提示找不到 ffmpeg 或 ffprobe 命令。原因FFmpeg 没有安装或者其可执行文件路径没有添加到系统的PATH环境变量中。解决按照第 2.1 节重新安装 FFmpeg。在终端中执行which ffmpegLinux/macOS或where ffmpegWindows来检查命令是否可用。如果已安装但未在 PATH 中需要手动添加安装目录到 PATH。5.2 问题二输出视频开头有几秒黑屏或卡顿现象使用-c copy模式后裁剪后的视频开头几秒画面静止或混乱之后才正常。原因这就是“关键帧”问题。你指定的-ss参数TRIM_START没有落在关键帧上。FFmpeg 为了执行流复制只能从上一个关键帧开始复制数据导致实际裁剪的开始时间早于你的设定。解决推荐使用内置降级我们的脚本已经包含了降级逻辑。当-c copy失败时会自动尝试重新编码。如果你发现输出视频开头异常可以手动删除输出文件并修改脚本暂时注释掉第一行ffmpeg ... -c copy ...命令直接使用重新编码的模式。精确重新编码模式修改 FFmpeg 命令参数的顺序将-ss放在-i之前这会启用输入 seeking并结合重新编码可以更精确但速度较慢。ffmpeg -ss $start_time -i $file -to $(echo $end_time - $start_time | bc -l) -c:v libx264 -c:a aac $output_file-ss在-i前FFmpeg 会先跳转到指定时间点附近开始解码精度高。-to后面跟的是持续时间duration所以计算方式是结束时间 - 开始时间。-c:v libx264 -c:a aac指定视频和音频编码器这是通用的重新编码参数。5.3 问题三处理某些格式的视频失败现象脚本跳过了某些文件或处理特定格式如.rmvb,.ts时报错。原因脚本的VIDEO_EXTS数组没有包含该格式或者 FFmpeg 需要额外的解码器。解决将不支持的扩展名添加到VIDEO_EXTS数组中例如(“mp4” “mov” “avi” “mkv” “flv” “wmv” “ts”)。对于编码特殊的老格式可能需要为 FFmpeg 安装额外的库。对于大多数常见格式官方静态构建版已足够。5.4 问题四输出视频没有声音或音画不同步现象裁剪后的视频无声或声音比画面慢/快。原因通常发生在重新编码模式下参数设置不当或者原始视频本身音视频流的时间戳PTS就有问题。解决优先使用-c copy只要关键帧允许流复制能完美保持音画同步。检查重新编码命令确保使用了正确的音频编码参数。例如-c:a aac或-c:a copy如果原始音频格式是兼容的。使用-avoid_negative_ts make_zero参数这个参数可以自动处理时间戳问题防止音画不同步。ffmpeg -ss $start_time -i $file -to $(echo $end_time - $start_time | bc -l) -c:v libx264 -c:a aac -avoid_negative_ts make_zero $output_file5.5 自动化裁剪方案对比表方案命令特点优点缺点适用场景极速流复制-ss START -to END -c copy速度极快无损质量处理大文件优势明显。裁剪点必须在关键帧上否则开头会有多余内容。对速度要求高且能接受裁剪点稍有偏差或视频关键帧密集。精确重新编码-ss START -i INPUT -to DURATION -c:v libx264 -c:a aac裁剪时间点精确输出格式统一。速度慢消耗CPU资源视频质量可能因编码而有损。对裁剪精度要求极高或源视频关键帧间隔很长。混合模式本文脚本先尝试流复制失败则降级重新编码。兼顾了大多数情况下的速度和可靠性。脚本逻辑稍复杂需要错误处理。通用推荐方案适合处理来源不一、要求可靠的批量任务。6. 最佳实践与扩展方向掌握了基础裁剪后你可以根据实际需求扩展这个脚本实现真正的“一站式”自动化。6.1 生产环境脚本优化建议日志记录将脚本的输出特别是处理成功和失败的文件名重定向到一个日志文件便于后续审计和排查。./auto_trim.sh trim_log_$(date %Y%m%d).log 21错误处理增强可以为不同的错误类型如文件不存在、编码失败、空间不足定义更详细的退出码和提示信息。配置文件将TRIM_START、TRIM_END、INPUT_DIR等变量提取到一个外部配置文件中如config.ini或settings.yaml使脚本更灵活。进度提示在处理大量文件时可以添加进度条或显示当前处理第几个文件。6.2 扩展功能思路基于静音检测的智能裁剪使用 FFmpeg 的silencedetect滤镜自动检测片头片尾的静音部分并裁剪实现更“智能”的自动化。# 示例检测持续时间超过1秒阈值低于-50dB的静音段 ffmpeg -i input.mp4 -af “silencedetectn-50dB:d1” -f null -你需要解析这个命令的输出获取静音段的开始和结束时间然后作为裁剪参数。批量视频合并在裁剪之后你可能还想把多个短视频合并成一个。FFmpeg 的concat协议或滤镜可以做到。# 创建一个文件列表 filelist.txt # file ‘clip1.mp4’ # file ‘clip2.mp4’ ffmpeg -f concat -safe 0 -i filelist.txt -c copy output_merged.mp4自动压缩与转码在裁剪命令中直接加入转码参数在输出时统一转换为更节省空间的格式如H.265或分辨率。ffmpeg -i input.mp4 -ss 5 -to 100 -c:v libx265 -crf 28 -c:a aac -b:a 128k output_compressed.mp4-crf 28控制视频质量值越大压缩率越高、质量越低通常23-28是合理范围。-b:a 128k设置音频比特率。集成到工作流将脚本部署到服务器通过监控input_videos文件夹例如使用inotifywait工具实现有文件放入就自动处理的“看门狗”服务。通过将 FFmpeg 的命令行能力与脚本的自动化逻辑相结合我们成功地将一个需要手动、重复操作的视频剪辑任务变成了一个“一秒都不用剪”的自动化流程。这个案例的核心价值在于思维模式的转变从手动操作界面转变为用代码描述规则。一旦掌握了这个模式你就可以举一反三应对视频转码、音频提取、水印添加、格式转换等一系列多媒体处理任务让计算机为你完成所有枯燥的重复性工作。

相关新闻

数学建模竞赛零基础通关指南:从算法到论文的实战方法论

数学建模竞赛零基础通关指南:从算法到论文的实战方法论

1. 项目概述:从零到一的数学建模竞赛通关手册如果你点开这篇文章,大概率是刚听说“数学建模”这个词,或者已经报名了比赛,正对着一堆“算法”、“编程”、“论文写作”感到无从下手。别慌,这种感觉我太熟悉了。十年前&…

2026/10/11 9:24:33 阅读更多 →
BioXArena:构建多模态生物医学LLM智能体基准测试平台

BioXArena:构建多模态生物医学LLM智能体基准测试平台

1. 项目概述:当LLM智能体闯入多模态生物医学的竞技场最近,我花了大量时间在折腾一个听起来就很有挑战性的项目:BioXArena。简单来说,这是一个专门用来“考”和“练”大型语言模型智能体的多模态生物医学机器学习任务基准测试平台。…

2026/10/6 21:06:51 阅读更多 →
终端与命令行进阶(5):ripgrep 与现代查找工具

终端与命令行进阶(5):ripgrep 与现代查找工具

上一篇把 fzf 定位成通用选择器,本篇补齐高质量候选的生产端。ripgrep(rg)搜索内容,fd 搜索路径,find 提供最完整的 POSIX/文件属性表达;三者不是互相淘汰,而是覆盖不同精度与可移植性需求。 一…

2026/10/10 16:39:32 阅读更多 →

最新新闻

LiteLLM实战:统一大模型API接口,解决模型切换与网关部署痛点

LiteLLM实战:统一大模型API接口,解决模型切换与网关部署痛点

做AI应用开发这两年,我最大的痛感不是模型能力不够,而是模型API的碎片化。今天用OpenAI,明天想换Claude,后天客户又要求接国产模型,每个厂商的请求格式、返回结构、认证方式、计费口径全都不一样,光是写适配…

2026/10/13 17:34:47 阅读更多 →
LiteLLM:统一大模型接口与代理网关实战指南

LiteLLM:统一大模型接口与代理网关实战指南

1. 统一接口的出发点:多供应商接入的隐性成本很多团队在体验过一两个大模型平台的 API 之后,很容易产生一种错觉:接入新模型不就是换一个model参数的事吗?真做起来才会发现,各家供应商的接口看起来都叫“聊天补全”&am…

2026/10/13 17:34:46 阅读更多 →
DeepSeekV4代号模型工程化实践:LoRA微调与结构化推理

DeepSeekV4代号模型工程化实践:LoRA微调与结构化推理

1. 项目概述:一个代号背后的技术信号与实操价值“202604-DeepSeekV4”这个字符串,乍看像一串时间戳加模型版本号的组合体,但如果你在最近两周翻过技术社区、模型评测平台或开源仓库的更新日志,大概率会发现它频繁出现在高频讨论中…

2026/10/13 17:34:46 阅读更多 →
基于10机39节点的电力系统仿真:Matlab/Simulink建模与暂态稳定分析

基于10机39节点的电力系统仿真:Matlab/Simulink建模与暂态稳定分析

做电力系统研究的人,不管你是刚入门的学生还是在实验室里摸爬滚打了两三年的工程师,肯定都绕不开一个经典系统:10机39节点。我第一次用Matlab和Simulink搭建这个系统时,光是把一堆母线、线路、发电机参数填进模块就折腾了快两周&a…

2026/10/13 17:34:46 阅读更多 →
MPU-6050从手册到自研板:寄存器配置、驱动代码与AD封装全解析

MPU-6050从手册到自研板:寄存器配置、驱动代码与AD封装全解析

简介:MPU-6050集成三轴陀螺仪与三轴加速度计,是消费电子、无人机、机器人与物联网设备中常用的六轴姿态检测方案。这份资源以MPU-6050为核心,面向嵌入式开发者与硬件工程师,提供从芯片底层配置到PCB量产的全链路支持。包体包含14个…

2026/10/13 17:34:46 阅读更多 →
EA4eig:病态矩阵高精度特征值求解的MATLAB稳定器

EA4eig:病态矩阵高精度特征值求解的MATLAB稳定器

简介:本资源是面向算法研究者与MATLAB初/中级使用者的EA4eig单目标数值优化算法实现包,专为CEC 2022基准测试函数设计,聚焦解决高维、多峰、非线性等复杂连续优化问题。算法创新性引入特征交叉策略,在遗传操作中融合父代解的关键维…

2026/10/13 17:33:46 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 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/12 21:05:09 阅读更多 →
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/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练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/12 18:11:17 阅读更多 →