PHP字符缓冲流在短视频平台实战:从ob_start到Range断点续传
做短视频平台PHP源码开发的朋友应该都撞见过这种诡异场景一个视频点播接口业务逻辑简单到不行可一到生产环境视频稍微大一点服务器内存就以肉眼可见的速度往下掉最后整个接口卡死播放器只能原地转圈。排查SQL、排查缓存、排查并发全都找不到原因真正的问题往往藏在PHP最难对付的字符缓冲流处理上。这篇内容就把我在短视频项目里对字符缓冲流的理解和实战经验捋一遍。它不只是教你用ob_start而是把“字符缓冲流”这个概念对应到PHP的缓冲层、流包装器、文件读取机制上讲清楚在短视频平台这种高并发、大文件、流式播放的场景下它到底有哪些特有功能以及怎么用才不会把自己坑死。1. 一次视频加载崩溃让我重新审视PHP的字符缓冲流1.1 现象视频越下越大内存越飙越高先说那次事故。一个短视频点播接口最初只放一些小尺寸MP4相安无事。后来运营上传一批高清素材问题立刻冒出来用户只要拖动进度条接口响应时间从几百毫秒直接飙到十几秒再往后服务器报内存耗尽进程被杀播放器黑屏一片。我一开始怀疑是数据库索引失效或者Redis缓存穿透查了一圈都不是。最后翻代码发现视频输出接口长这样// 老代码看着没毛病实际是定时炸弹 ob_start(); readfile($videoPath); ob_end_flush();问题就出在这里。ob_start()开启了一个输出缓冲层readfile()不是“读一点发一点”而是把整个文件内容全部灌进这个缓冲区。一个几百MB的视频文件PHP进程内存里就要同时装下这么大一份数据。内存限制设256M视频到300M直接崩溃。更隐蔽的是即使视频没有超过内存限制这种写法也会让首个字节的到达时间变得极慢因为要等整个文件读完才开始发送。事后复盘我意识到自己根本没搞懂“缓冲”在不同场景下的两面性小文本输出需要缓冲来合并碎片大视频文件却最怕被整体缓冲。1.2 字符缓冲流在PHP语境里到底指什么有Java基础的朋友都知道Java里有个明确的字符缓冲流比如BufferedReader、BufferedWriter用来减少读写次数、提高效率。PHP没有一模一样的类名但“字符缓冲流”这个概念是完全成立的它由三块组成ob_系列输出缓冲函数ob_start()、ob_get_contents()、ob_get_clean()、ob_end_flush()等负责在PHP内部拦截输出内容。流包装器php://output、php://memory、php://temp其中php://memory直接在内存里读写php://temp超过指定字节后自动落到临时文件。文件流式读写fopen()、fread()、fseek()、fpassthru()按字节流方式处理数据。这三块合在一起才是完整意义上的字符缓冲流。用生活化的比喻直接echo输出就像水管直通客户端水管细会卡ob_start()就像在中间修一个水塔先把水蓄起来再平稳放出去。普通网页用小水塔没问题视频平台却经常要把水管直接对接大水库中间蓄水反而会把水塔撑爆。知道这个原理之后我再回过头去看短视频平台的PHP源码发现所有涉及输出的模块——模板渲染、JSON接口、视频文件、弹幕推送——其实都在跟字符缓冲流打交道只是很少有人把它们当成一个整体去设计。2. 短视频平台落地模板、接口、大文件三类缓冲的搭建搞清楚原理就要动手把它落到短视频平台的每一个输出环节里。我在项目里把字符缓冲流分成了三层来搭模板渲染层、接口响应层、大文件传输层。每一层的目标不一样代码写起来也完全不同。2.1 模板渲染层用ob_start捕获子模板统一拼装主页面短视频平台虽然主打App但Web端、活动页、后台管理都跑着PHP模板。早期项目里子模板边include边输出主模板再拼装页面内容七零八落地发给浏览器一个800KB的页面能被切成几十个网络包白屏时间非常难看。后来统一改成缓冲拼装function renderPage(string $mainTpl, array $blockTpls): string { $blocks []; foreach ($blockTpls as $key $tpl) { ob_start(); include $tpl; $blocks[$key] ob_get_clean(); } ob_start(); include $mainTpl; return ob_get_clean(); }这段代码的核心逻辑是每个子模板先丢进ob_start()捕获ob_get_clean()拿回内容并关闭缓冲所有子模板内容收集完成后再丢进主模板统一输出。好处很明显页面所有HTML一次性发送浏览器解析更快子模板之间也不会互相污染变量作用域更干净。这里有一个必须养成的习惯——ob_start()和ob_get_clean()/ob_end_clean()/ob_end_flush()一定成对出现。我见过太多人开了缓冲不关一层套一层最后页面尾部多出一堆莫名其妙的空白字符。模板数量多的时候可以在公共基类里封装一个渲染入口统一管理缓冲生命周期别到处裸调ob_start()。2.2 接口响应层给JSON输出加一层“安检”短视频平台的后端接口数量比页面多得多视频列表、推荐流、用户关注、弹幕拉取全部走JSON。这类接口最怕响应被污染。有一次线上接口偶尔返回的不是JSON前面多了一行“PHP Warning: Undefined array key”App端直接解析失败。当时就是靠字符缓冲流兜住的。统一在接口入口包一层function apiResponse(callable $handler, array $data []) { ob_start(); $result $handler($data); $spilled ob_get_clean(); if (trim($spilled) ! ) { // 记录日志但坚决不让它进入响应体 error_log([api pollution] . $spilled); } header(Content-Type: application/json; charsetutf-8); echo json_encode($result, JSON_UNESCAPED_UNICODE); }这样做的意义在于任何PHP警告、第三方SDK的echo调试输出都会被缓冲层拦下来只有真正调用json_encode之后的内容才能通过响应通道发给客户端。缓冲层在这里扮演的角色是“安检门”而不是“暂存区”。跨域JSONP接口同理。callback参数拼接要在JSON完整生成之后再做$json json_encode($data, JSON_UNESCAPED_UNICODE); echo $_GET[callback] . ( . $json . );绝不能在业务代码里提前echo任何字符否则JSONP包裹后必出语法错误。2.3 大文件传输层fread加flush而不是readfile一把梭视频文件输出是短视频平台的核心场景也是最容易踩爆内存的地方。前面说过readfile()加ob_start()是炸弹那正确姿势是什么我现在的标准写法是分段读取加即时刷新$fp fopen($videoPath, rb); if (!$fp) { header(HTTP/1.1 404 Not Found); exit; } while (!feof($fp)) { echo fread($fp, 65536); flush(); } fclose($fp);fread()每次只读取64KB到内存flush()立刻把这64KB交给SAPI层发送给FastCGI或Web服务器。这样PHP进程的常驻内存增量只有几十KB无论视频是100MB还是2GB内存曲线都是平的。有人可能会问readfile()本身不是也会流式输出吗对但一旦外面套了ob_start()它就不流式了。更麻烦的是如果框架或第三方插件在入口统一开了输出缓冲readfile()同样会被吸进去。所以我的原则是大文件输出路径上禁止有任何ob_start()残留入口检查ob_get_level()必须是基础值。3. 真正“特有”的功能Range断点续传、渐进播放与弹幕聚合前面说的缓冲方式放在普通网站也能用还谈不上“特有”。真正让字符缓冲流在短视频平台发挥不可替代作用的是下面这几个能力——普通网页一辈子用不上视频平台离了它们就没法活。3.1 视频点播的Range请求为什么必须靠流式定位短视频播放器拖拽进度条、断点续传底层靠的是HTTP Range协议。客户端发一个Range: bytes1024-2048服务器只返回这一小段数据。要实现这个能力PHP必须能精确跳到文件的任意字节位置读取——这就是fopen()fseek()fread()的组合拳。精简版实现思路$fp fopen($videoPath, rb); $size filesize($videoPath); $start 0; $end $size - 1; if (isset($_SERVER[HTTP_RANGE])) { // 这里只处理单区间多区间直接忽略Range返回完整文件 if (preg_match(/bytes(\d)-(\d*)/, $_SERVER[HTTP_RANGE], $m)) { $start intval($m[1]); if ($m[2] ! ) { $end intval($m[2]); } if ($start $end || $start $size) { header(HTTP/1.1 416 Requested Range Not Satisfiable); header(Content-Range: bytes */ . $size); exit; } header(HTTP/1.1 206 Partial Content); header(Content-Range: bytes . $start . - . $end . / . $size); } } header(Content-Type: video/mp4); header(Content-Length: . ($end - $start 1)); fseek($fp, $start); $remaining $end - $start 1; while ($remaining 0) { $chunk fread($fp, min(65536, $remaining)); echo $chunk; flush(); $remaining - strlen($chunk); } fclose($fp);这套逻辑的关键点在于状态码必须是206响应头必须带Content-Range和精确的Content-Length数据读取必须从fseek定位后的位置开始。如果用了readfile()整段输出播放器拿不到正确字节范围拖拽就会失败这是短视频平台源码里最基本也最容易被忽略的一块。3.2 边下边播与进度拖拽缓冲区的“不完整”才是关键短视频用户耐心很有限首帧时间超过两三秒就划走了。播放器加载视频时通常只请求最开始的一小段比如前2MB拿到就能开始渲染画面同时继续请求后续分片。这个“只给一部分”的逻辑恰好是字符缓冲流的另一种活用。我接手过一份源码视频接口不做Range支持每次都是完整文件输出用户一拖进度条播放器就长时间黑屏。后来加上范围处理后视频秒开率提升非常明显。这个场景里缓冲块的大小需要拿捏块太大比如一次fread1MB内存平稳但首帧延迟变高块太小比如1KB网络包太碎吞吐量上不去。实测下来竖屏短视频用64KB比较合适高清长视频可以放大到256KB甚至1MB视机器配置和带宽决定。3.3 弹幕聚合与批量刷新php://temp当临时蓄水池弹幕是短视频平台的特色功能。用户发一条弹幕后台要保存入库还要推给同一视频的其他观看者。如果每个弹幕都立刻写一次数据库高峰期瞬间几百条写入请求库的压力非常大。我的做法是利用php://temp流做字符缓冲聚合。它和php://memory的区别在于数据量不大时驻留内存一旦超过指定阈值比如2MB自动落到系统临时文件不会撑爆内存还保留了流式读写的灵活性。$buf fopen(php://temp/maxmemory:2097152, r); foreach ($danmakuBatch as $msg) { fwrite($buf, $msg[video_id] . | . $msg[uid] . | . $msg[text] . PHP_EOL); } // 累计到一定条数或定时器触发时统一取出 rewind($buf); $payload stream_get_contents($buf); fclose($buf); // $payload 批量入库、批量推送评论点赞、实时在线数这类高频短消息也可以用同样的思路先在临时流里攒一批达到阈值或时间窗口再统一处理。这种聚合方式把原本的N次小IO合并成几次大IO数据库连接数明显下降推送接口也能减少网络包数量。4. 缓冲层引发的三个经典故障从BOM到JSON污染字符缓冲流用好了是利器用歪了就是连环坑。我在短视频项目里踩过不少挑三个最典型的详细说说排查过程避免大家再走弯路。4.1 视频流开头多了一串乱码UTF-8 BOM的锅有一次某个MP4视频在播放器里总是前几百毫秒花屏换个视频又正常非常诡异。用十六进制工具看了文件开头发现前三个字节多出了EF BB BF。这个二进制序列是UTF-8的BOM标记。它不是视频内容的一部分而是某个被include的PHP文件编码不规范自带BOM。PHP执行时会把BOM当作普通字符输出如果这段输出混进了视频流播放器就会把BOM误判成视频头的一部分导致解析错乱。排查链路是这样的先确认响应是纯视频流还是混入了文本。用curl -v看返回头再对前几十字节做hex dump。发现EF BB BF后检查入口文件、公共函数文件是否使用带BOM的UTF-8编码。统一用无BOM的UTF-8重新保存所有PHP文件低版本编辑器经常默认带BOM团队要做编码规范。在视频输出接口最前面加一行防御性代码ob_end_clean();把前面可能残留的输出全部清掉。当然这不能替代修复编码问题只能兜底。4.2 JSON接口平白多出一行PHP Warning那次事故让我养成了“接口出口必过缓冲”的习惯。短视频推荐流接口某天突然报解析失败App抓包看到响应体开头多了一行PHP Warning: Trying to access array offset on value of type null后面才是正常JSON。这行Warning是某个数组取值时下标不存在触发的默认配置下display_errors开着Warning直接打进响应体。排查思路先用curl -i观察响应Body前几个字符确认多出来的内容。打开PHP错误日志找到具体触发位置。修复业务代码里的空值判断这是根治。同时在接口出口用ob_start()ob_get_clean()拦截可能漏网的输出双保险。生产环境建议直接把display_errors关掉只在日志里记录错误。但对于PHP源码项目第三方代码不可控缓冲兜底是成本最低的保护手段。4.3 ob_start嵌套过深响应迟迟不回来还有个更隐蔽的坑模板引擎开一个ob_start缓存插件开一个第三方监控SDK又开一个一个80KB的页面被重重缓冲憋在PHP进程里客户端要等所有嵌套缓冲全部关闭才算完事。低并发时感觉不到一上量响应时间陡增。排查方法很简单在接口或页面关键位置临时加一行响应头header(X-Ob-Level: . ob_get_level());正常入口层级应该是0如果php.ini开了全局output_buffering则是一个固定基数。如果看到4、5甚至更高说明有代码只开缓冲没关闭。逐个定位确保每个ob_start()都有对应的关闭操作。我还在监控日志里把ob_get_level()异常偏高的请求单独记录下来防止线上复发。5. 缓冲参数、FastCGI分层与生产环境配置建议聊完功能和应用最后说说生产环境里缓冲参数怎么配。这部分很琐碎但直接影响稳定性和性能我直接给出可参考的配置思路。5.1 output_buffering、chunk size与memory_limit的搭配php.ini里有几个参数跟缓冲直接相关很多新手会配错。output_buffering 4096 implicit_flush Off memory_limit 256Moutput_buffering4096意味着PHP会在内部先把输出攒到4KB再交给SAPI适合HTML页面避免大量小echo导致网络包碎片。implicit_flushOff则是不要每次echo都立刻刷新缓冲区否则flush()就失去意义。但这只是小页面场景。视频文件输出路径强烈建议在代码里不要依赖这个全局配置直接用fread循环和flush()控制。memory_limit也不是越高越好对于正确的流式读取来说256M已经非常宽松如果视频输出还需要上百MB内存说明代码写错了。块大小选择我结合项目实际情况给个经验值场景推荐块大小理由HTML模板渲染4KB-8KB页面体积小块太大无意义短视频MP4输出64KB-256KB平衡吞吐和首帧延迟长视频/高清视频256KB-1MB减少循环次数充分利用带宽弹幕/评论聚合按条数或时间窗口以业务维度为准不是字节维度5.2 PHP缓冲和Nginx FastCGI缓冲是两层别混着调很多人忽略了一个事实PHP的ob_缓冲只是第一层PHP提交给FastCGI后Nginx还有自己的fastcgi_buffering。两层缓冲区叠加效果不是112而是内存翻倍。我的经验是小接口JSON、HTMLPHP层做缓冲和压缩Nginx层开着也没关系反正数据量小。大视频文件如果PHP直接输流传给NginxNginx的fastcgi_buffering会把整个文件都吸到自己的缓冲区里照样内存爆炸。这时可以在Nginx配置里对视频路径关闭缓冲location /video/ { fastcgi_buffering off; }或者更彻底一点PHP只做权限校验和真实路径校验然后通过X-Accel-Redirect响应头把文件交给Nginx直接读取PHP进程完全不碰文件内容。这是处理大文件最高效的方案适合内部架构允许的情况。要注意的是关闭fastcgi_buffering后Nginx会边收边发如果PHP侧还是用readfile加ob_start的老写法那么瓶颈依然在PHP层Nginx只是从帮凶变成旁观者。所以分层逻辑必须一致PHP层用小缓冲快速发送Nginx层对视频路径关闭缓冲。5.3 生产环境设置的参考清单最后整理一份我在短视频平台PHP源码项目里使用的检查清单上线前过一遍能避开绝大多数缓冲相关的坑[ ] 所有PHP文件统一保存为无BOM的UTF-8编码。[ ]display_errors关闭log_errors开启。[ ] 模板渲染使用ob_startob_get_clean成对封装不裸调。[ ] 所有JSON接口出口经过统一缓冲清理非预期输出。[ ] 大文件输出禁止外套ob_start使用fopenfreadflush。[ ] 视频点播接口支持单区间Range请求正确返回206和Content-Range。[ ] 高频短消息使用php://temp聚合控制写库和推送频次。[ ] 关键接口运行时记录ob_get_level()异常层级主动告警。[ ] Nginx层对视频路径关闭fastcgi_buffering或改用X-Accel-Redirect。[ ] 压测时观察PHP内存曲线确认大文件输出不随时间无限上涨。在我负责的短视频项目里把字符缓冲流这套逻辑理顺之后视频加载成功率有明显提升接口内存告警基本消失。调试阶段还有个很实用的小技巧不确定响应哪里被污染时直接在出口临时打印ob_get_contents()看一眼缓冲区里到底攒了什么很多诡异现象当场就能定位。字符缓冲流不是什么高大上的玄学它就是把“什么时候输出、输出多少、要不要攒一批再输出”这件事想清楚短视频平台这种高流量场景尤其值得花时间把它理顺。

相关新闻

基于BEMT的螺旋桨性能计算:Matlab实现与前进比扫描分析

基于BEMT的螺旋桨性能计算:Matlab实现与前进比扫描分析

螺旋桨性能计算,网上能搜到的资料大多停在“给出推力公式、画个效率曲线”的层面。真到了要分析一个具体螺旋桨几何在不同前进比下的性能时,就会发现公式和实际结果之间还隔着一大堆细节:桨叶扭转角怎么分布、每个半径处翼型工作在什么攻角、…

2026/10/5 4:31:33 阅读更多 →
基于ThinkPHP和Vue的旅游景点数据分析与推荐系统实现

基于ThinkPHP和Vue的旅游景点数据分析与推荐系统实现

1. 从需求到架构:这套旅游景点数据分析与推荐系统要解决的核心问题1.1 为什么旅游景点需要一套分析和推荐系统先说个我自己的观察。这几年大家的出行方式变了很多,从以前"报团跟着走"变成"自己查攻略做计划",但真到订行程…

2026/10/5 4:31:33 阅读更多 →
MapReduce与Hive协同构建电商消费行为分析体系

MapReduce与Hive协同构建电商消费行为分析体系

1. 这不是“跑个MapReduce就完事”的玩具项目,而是真实电商场景下的消费行为闭环分析我第一次接手用户消费行为分析这个需求时,客户给的原始数据是23TB的原始日志,分散在HDFS上17个不同命名空间的目录里,字段缺失率最高达41%&…

2026/10/5 4:31:33 阅读更多 →

最新新闻

cracer纪念版红队工具包:开箱即用的域渗透与横向移动补给站

cracer纪念版红队工具包:开箱即用的域渗透与横向移动补给站

简介:cracer纪念版渗透测试工具包是一套面向网络安全初学者与渗透测试实践者的集成化工具集合,聚焦Web漏洞探测、内网渗透、密码爆破及信息收集等核心攻防场景,助力用户快速搭建本地靶场环境并开展实战演练。资源为549.31MB的ZIP压缩包&#…

2026/10/5 5:02:44 阅读更多 →
Ripple Community Wallet连接Ledger硬件钱包:WebHID签名流程与防盲签安全机制详解

Ripple Community Wallet连接Ledger硬件钱包:WebHID签名流程与防盲签安全机制详解

Ripple Community Wallet连接Ledger硬件钱包:WebHID签名流程与防盲签安全机制详解 【免费下载链接】XRP-community-wallet Fully decentralized and the most secure XRP & EVM wallet - built by the community, for the community. 项目地址: https://gitco…

2026/10/5 5:02:44 阅读更多 →
2026大模型实操地图:从指令遵循到Agent部署的工程化指南

2026大模型实操地图:从指令遵循到Agent部署的工程化指南

1. 这不是一份“榜单”,而是一张2026年大模型生态的实操地图你点开这个标题,大概率不是想看又一份“XX大模型排名Top10”的媒体通稿。我干这行十年,从早期TensorFlow 1.x时代手写op,到如今每天和千卡集群、推理引擎、Agent编排打交…

2026/10/5 5:02:44 阅读更多 →
2026年AI辅助论文初稿实操流程与避坑指南

2026年AI辅助论文初稿实操流程与避坑指南

2026年了,关于“论文初稿能不能用AI”这件事,我觉得已经没什么可争论的了——答案显然是能,而且身边不少人在用。真正值得聊的问题变成了:为什么同样用AI辅助,有人三周写出初稿,导师还夸思路清楚&#xff1…

2026/10/5 5:02:44 阅读更多 →
SDD规范驱动的AI开发:Harness如何实现可控化代码生成

SDD规范驱动的AI开发:Harness如何实现可控化代码生成

1. 这不是又一个“AI写代码”噱头:SDD规范驱动 Harness工程化,到底在解决什么真问题?最近两周,我连续被三个不同行业的技术负责人拉进会议室,问的都是同一个问题:“你们团队用的DeepSeek Harness&#xff…

2026/10/5 5:02:44 阅读更多 →
WorkBuddy实战:智能家居竞品调研从三天压缩到三小时

WorkBuddy实战:智能家居竞品调研从三天压缩到三小时

前两天临时接到一个任务,要在三天内给领导交一份智能家居行业的竞品调研报告。换作以前,这种活意味着我要在十几个网站之间来回切换,翻官网、查财报、扒第三方数据,光收集资料就能耗掉一整天,更不用说整理成结构清晰的…

2026/10/5 5:01:44 阅读更多 →

日新闻

马斯克杀回智能体战场,Grok 4.5万亿参数撑腰,Cursor接手数字白领项目:用TaoToken统一Key跑通多模型Agent工作流

马斯克杀回智能体战场,Grok 4.5万亿参数撑腰,Cursor接手数字白领项目:用TaoToken统一Key跑通多模型Agent工作流

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

2026/10/5 0:00:22 阅读更多 →
AI编程工具插件机制详解:plugin.json配置与加载失败排查指南

AI编程工具插件机制详解:plugin.json配置与加载失败排查指南

1. 从“plugins”这个词说起:它到底在解决什么问题如果你最近在折腾 AI 编程工具,尤其是 Cursor、Codex CLI、Claude Code 这类带 CLI 的编辑器或命令行助手,那你大概率绕不开一个词——plugins。这个词本身不新鲜,从浏览器到 IDE…

2026/10/5 0:00:23 阅读更多 →
第26课:OpenClaw|日志审计与问题诊断:把日志链路改到 TaoToken 的排查清单

第26课:OpenClaw|日志审计与问题诊断:把日志链路改到 TaoToken 的排查清单

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

2026/10/5 0:00:23 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/5 1:10:22 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/5 3:06:17 阅读更多 →

月新闻

我发现了一个新思路:用 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/4 11:40:45 阅读更多 →
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/4 9:43:54 阅读更多 →
黑夜航拍船只数据集训练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/4 20:14:29 阅读更多 →