WebCodecs视频解码器配置:codec与description实战解析
把 WebCodecs 的 VideoDecoder 跑通难的不是 API 本身而是配置项。我之前在公司做低延迟播放内核被问得最多的就是 codec 和 description 这两个字段codec 到底填什么description 到底是哪个二进制为什么明明按文档传了还是报错。这篇文章就把这两个字段从原理到实战彻底讲清楚包括怎么从 MP4 里把配置信息导出来、怎么手写 H.264 的 avcC、怎么排查配置成功但不出画面这类经典问题。适合用 WebCodecs 做播放器、低延迟链路、音视频工具脚本的开发者也适合那些刚入门、在官方文档面前一脸懵的朋友。1. 为什么配置 codec 和 description 让人头大先搞懂解码器的初始化协议1.1 WebCodecs 不是猜谜解码器传统video标签处理视频时浏览器内部做了大量推导工作容器解析、参数集扫描、流状态维护基本是把它丢给播放器剩下不用管。但 WebCodecs 把解码器暴露成最底层的状态机它要求你在创建解码器之前就把流的身份信息讲清楚。拿 H.264 来说一个码流能正常解码依赖 SPS序列参数集里的分辨率、帧率、profile、level以及 PPS图像参数集里的熵编码模式、参考帧数量等信息。如果这些信息缺失解码器连一帧都解不出来。传统播放器可以扫描码流自动找参数集但 WebCodecs 的 API 形状是先创建解码器、再喂数据没有留扫描的余地所以必须由你提前准备好。这就是 codec 和 description 存在的意义codec 告诉解码器这是什么编码格式、什么档次、什么等级description 把参数集或配置记录直接塞给解码器省得它自己猜。1.2 description 就是容器里那个配置 box 的数字化身MP4 里每个视频 track 都会携带一个配置 box比如 H.264 的 avcC、HEVC 的 hvcC、AAC 的 esds。这个 box 里存的就是解码器需要的说明书版本、profile、level、SPS、PPS、长度前缀格式等等。在 WebCodecs 的 config 里description字段就是这个配置记录的原始字节通常是一个ArrayBuffer或Uint8Array。解码器初始化时读一次之后每个 EncodedVideoChunk 只需要带经过长度前缀标记的样本数据不需要反复携带参数集。你可以把 codec 理解成告诉对方这是哪种文档格式把 description 理解成把文档规范细则一起递过去。只给格式名不给细则对方大概率读不了。1.3 浏览器报错信息经常不指向真正问题实际使用中VideoDecoder 的 error 回调会给一个DOMException常见的消息有Failed to parse description、NotSupportedError、TypeError。但这些报错往往只告诉你这一层挂了不会告诉你到底是 codec 字符串写错、description 里 SPS 少了还是长度前缀对不上。所以你需要自己掌握排查链路后面我会专门写一节。2. codec 字符串逐段拆解avc1/hvc1/vp09/av01 的命名规则与获取办法2.1 avc1.PPCCLLH.264 的 profile、constraint 和 levelWebCodecs 里 H.264 的标准 codec 字符串格式是avc1.PPCCLL这六个十六进制字符分三段PPprofile_idc比如 42 表示 Baseline、4D 表示 Main、64 表示 High。CCconstraint flags表示流遵守的约束条件很多编码器输出 00 或 E0。LLlevel_idc表示档位十六进制的 1F 就是 Level 3.128 是 Level 4.033 是 Level 5.1。常见写法可以参考下面这张表codec 字符串含义avc1.42001FBaseline Level 3.1低画质场景常见avc1.4D0028Main Level 4.0avc1.640028High Level 4.0很多 1080p 视频用这个avc1.640033High Level 5.1高码率 4K 片源常见注意avc1表示码流符合 AVCC 格式长度前缀分隔 NALU如果某些工具输出的是avc3那是另一种样本格式。WebCodecs 里一般用avc1。2.2 hvc1 与 hev1H.265 的复杂参数序列H.265 的 codec 字符串比 H.264 长得多格式是hvc1.加上一串用点分隔的十六进制参数具体包含 profile、compatibility 标志、约束标志、level。比如hvc1.1.6.L93.B0就是很常见的 H.265 Main Profile Level 5.1 写法。这里有个重要区别hvc1表示参数集VPS/SPS/PPS放在 stsd 的 hvcC 配置记录里hev1表示参数集可能直接带在关键帧样本里。WebCodecs 配置中理论上两者都支持但我实测下来优先用hvc1更稳因为这和把 hvcC 作为 description 传入的姿势最匹配。H.265 的 codec 字符串手写很容易出错实际项目里我建议直接靠工具生成不要自己拼。后面会讲用 ffprobe 的完整办法。2.3 vp09 和 av01WebRTC 时代越来越常见的编码VP9 的 codec 字符串类似vp09.PP.LL.DD...其中 PP 是 profileLL 是 levelDD 是 bit depth 等参数。一个能用的最小写法是vp09.00.10.08表示 profile 0、level 1.0、8 位色深。更严格的做法是从 ffprobe 拉完整参数串。AV1 的字符串格式是av01.PP.LL.TT.DD...帧常见的是av01.0.08M.080 代表 profile 008M 代表 level 8.0 主档最后的 08 代表 8-bit。这些字符串通常不需要你手写ffprobe 或 mp4box 会给。2.4 用 ffprobe 把 codec 字符串和 time_base 一次拿全我强烈建议把这个命令记下来。它不仅帮你拿到 codec 相关字段还能用 time_base 帮你换算 WebCodecs 需要的时间戳ffprobe -v quiet \ -select_streams v:0 \ -show_entries streamcodec_name,profile,level,width,height,coded_width,coded_height,time_base,avg_frame_rate,extradata,extradata_size \ -of json input.mp4输出大概长这样{ streams: [ { codec_name: h264, profile: High, level: 51, width: 1920, height: 1080, coded_width: 1920, coded_height: 1080, time_base: 1/15360, avg_frame_rate: 25/1, extradata: 015764...., extradata_size: 47 } ] }注意 ffprobe 输出的level是十进制整数比如 51 对应 Level 5.1转成十六进制就是 0x33。profile是字符串 High对应 profile_idc 0x64。如果 profile 是 Baseline 则对应 0x42Main 对应 0x4D。组合起来就是avc1.640033也就是上面表格里的 High5.1。time_base这个字段很容易被忽略但它直接决定 WebCodecs 的 EncodedVideoChunk 时间戳换算。WebCodecs 的时间戳单位是微秒如果你从 MP4 容器里拿到的 pts 是基于 time_base 的整数需要换算成微秒pts_us pts * 1000000 / (1 / time_base)比如 time_base 是 1/15360那么一帧对应的微秒数是pts * 15360 / 1000000实际公式不要记反后面我会再讲一次。音频也类似AAC 的 codec 字符串通常是mp4a.40.2这种格式AudioDecoder 的 description 需要传 AudioSpecificConfig。做法和视频一致用 ffprobe 从音频流拿 extradata。3. description 从哪来三条靠谱的提取路径3.1 路径一ffprobe 直接导出 extradataffprobe 的extradata字段就是容器里的配置记录对 H.264 来说就是 avcC 的内容。命令行这样写ffprobe -v error \ -select_streams v:0 \ -show_entries streamextradata,extradata_size \ -of defaultnoprint_wrappers1 input.mp4输出extradata01576400... extradata_size47得到的是一串十六进制字符串。后面你用 JavaScript 转成Uint8Array即可function hexToUint8Array(hex) { const bytes new Uint8Array(hex.length / 2); for (let i 0; i bytes.length; i) { bytes[i] parseInt(hex.slice(i * 2, i * 2 2), 16); } return bytes; }大多数 MP4 文件的 avcC 很小通常几十字节ffprobe 不会截断。但如果遇到 HEVC 的 hvcC 包含很多参数集或者视频是多轨的你就得用别的方法。3.2 路径二在浏览器里从 init segment 解析如果你做的不是本地上传文件播放而是 MSE/DASH 场景你手里没有物理 MP4 文件只有网络请求拿到的 init segment。这时候可以在浏览器里用 mp4box.js 或类似库解析。一个大致的做法是const mp4box MP4Box.createFile(); mp4box.onError (e) console.error(e); mp4box.appendBuffer(initSegment); const info mp4box.getInfo(); info.tracks.forEach((track) { console.log(track.codec); // 类似 avc1.640028 // 再往下挖 track 的 stsd 配置数据 });用 mp4box.js 一定要确认拿到的二进制是否带 box header。WebCodecs 的description要求的是从configurationVersion开始的配置记录内容不包含 avcC 这个 box 的 type 和 size 头。如果库返回的是完整 box你需要去掉前 8 字节再传给解码器。3.3 路径三从 Annex B 裸流里抓 SPS/PPS这个场景比较硬核适合做直播接收端。如果你的输入不是 MP4而是 RTMP、WHIP、裸 H.264 流那么码流里 SPS 和 PPS 会以 start code00 00 01或00 00 00 01开头NAL type 为 7 的是 SPS8 的是 PPS。抓取思路很简单扫描 start code。读 start code 后第一个字节的低 5 位判断 NAL type。如果是 7 或 8从 start code 后面截取到下一个 start code 为止这段就是 SPS 或 PPS。有了 SPS/PPS 之后用下一章的方法把它们打包成 avcC。这个方法对于首帧关键帧前面的参数集尤其好用因为代码逻辑不复杂后面我会给一个可以放到项目里的 helper。4. 手写 avcC 配置从 SPS/PPS 到 VideoDecoder 能吃的 ArrayBuffer4.1 avcC 的字节布局AVCDecoderConfigurationRecord 的布局是固定的直接用字节表来看偏移长度含义01configurationVersion固定为 111AVCProfileIndication即 SPS 第 1 字节21profile_compatibility即 SPS 第 2 字节31AVCLevelIndication即 SPS 第 3 字节41高 6 位保留低 2 位是 lengthSizeMinusOne51高 3 位保留低 5 位是 numOfSequenceParameterSets62第一个 SPS 的长度8NSPS 内容...1numOfPictureParameterSets...2第一个 PPS 的长度...MPPS 内容因为 H.264 的 SPS 前四个字节天然就是 profile、compatibility、level所以 avcC 前四个字节可以直接从 SPS 拷贝。lengthSizeMinusOne表示后续每个 EncodedVideoChunk 里 NALU 的长度前缀用了几个字节减一常见值是 3代表 4 字节大端长度前缀。4.2 makeAvcC 完整代码下面这个函数可以把 SPS 和 PPS 打包成 WebCodecs 能直接用的ArrayBufferfunction makeAvcC(sps, pps) { // 6 字节头部 2 字节 SPS 长度 SPS 内容 // 1 字节 PPS 数量 2 字节 PPS 长度 PPS 内容 const totalSize 6 (2 sps.length) 1 (2 pps.length); const buffer new ArrayBuffer(totalSize); const view new DataView(buffer); const bytes new Uint8Array(buffer); let off 0; view.setUint8(off, 1); // configurationVersion view.setUint8(off, sps[1]); // AVCProfileIndication view.setUint8(off, sps[2]); // profile_compatibility view.setUint8(off, sps[3]); // AVCLevelIndication view.setUint8(off, 0xff); // 11111111低 2 位为 3 view.setUint8(off, 0xe1); // 111 00001低 5 位表示 SPS 数量为 1 view.setUint16(off, sps.length, false); off 2; bytes.set(sps, off); off sps.length; view.setUint8(off, 1); // numOfPictureParameterSets 1 view.setUint16(off, pps.length, false); off 2; bytes.set(pps, off); return buffer; }调用方式const sps hexToUint8Array(67640028...); // 从流中抓到的 SPS const pps hexToUint8Array(68ebec...); // 从流中抓到的 PPS const description makeAvcC(sps, pps); const support await VideoDecoder.isConfigSupported({ codec: avc1.640028, description, codedWidth: 1920, codedHeight: 1080, });T 提示sps[1]、sps[2]、sps[3]使用的前提是你传入的 SPS 是完整的 NAL unit且第一个字节是 NAL header0x67 开头第二个字节才是 profile_idc。如果工具给出的是去掉 NAL header 的原始 SPS 数据需要自己调整偏移。4.3 lengthSizeMinusOne 和样本数据格式的对应关系这是配置成功之后最容易翻车的地方。WebCodecs 对 H.264 样本数据的要求和 MP4 的 AVC 样本格式一致每个 NALU 前面都有长度前缀长度前缀的字节数由 description 里的lengthSizeMinusOne 1决定。如果 description 里设置的是0xfflengthSizeMinusOne3那么喂给 EncodedVideoChunk 的 data 就必须是这种形态[4字节大端长度][NALU内容][4字节大端长度][NALU内容]...但如果你手上的原始码流是 Annex B 格式直接喂进去会报错或花屏。需要先把 start code 分隔的 NALU 转成长度前缀分隔。一个简单的转换逻辑function annexbToLengthPrefixed(annexb) { const naluList []; let i 0; // 扫描 start code while (i annexb.length - 4) { if (annexb[i] 0 annexb[i 1] 0) { if (annexb[i 2] 1) { naluList.push(i 3); i 3; continue; } else if (annexb[i 2] 0 annexb[i 3] 1) { naluList.push(i 4); i 4; continue; } } i; } // 根据 start code 位置切分并改写 const out []; for (let j 0; j naluList.length; j) { const start naluList[j]; const end j 1 naluList.length ? naluList[j 1] - (annexb[naluList[j 1] - 3] 1 ? 3 : 4) : annexb.length; const nalu annexb.subarray(start, end); const len nalu.length; if (len 0xffffffff) throw new Error(NALU too large); out.push(new Uint8Array([(len 24) 0xff, (len 16) 0xff, (len 8) 0xff, len 0xff])); out.push(nalu); } const total out.reduce((acc, arr) acc arr.length, 0); const result new Uint8Array(total); let offset 0; for (const arr of out) { result.set(arr, offset); offset arr.length; } return result; }这一步做完再配合正确的 description 和 codec解码器大概率就能正常出帧了。5. 配置成功后依然翻车实测中的坑与排查清单5.1 isConfigSupported 返回 false先查这几个字段VideoDecoder.isConfigSupported(config)返回supported: true才说明浏览器认可你的配置。如果返回 false优先检查codec 字符串是否按 RFC 6381 写。H264、x264、h.264这种写法都不行必须avc1.PPCCLL。大小写是否准确。比如AVC1在部分浏览器里也通过但最好统一小写。description 是否真的是配置记录不带多余的 box header。硬件不支持当前 profile。比如部分移动端对 HEVC High 10、AV1 10-bit 的硬解支持有限prefer-hardware会导致 isConfigSupported 返回 false。这里分享一个排查技巧先用support.config看看浏览器处理后到底收下了什么再和自己传的原始 config 对比。经常能发现浏览器把codedWidth/codedHeight做了修正。5.2 配置成功但解码一直报错、黑屏如果 isConfigSupported 通过了但 VideoDecoder 的 error 回调疯狂触发最常见的原因有两类第一类description 和实际码流不一致。比如你从一个视频文件里导出的 avcC却拿去解另一个分辨率、另一个 profile 的流。SPS 和 PPS 是强绑定关系任何一个字段不对都可能解不出来。项目里务必保证一个轨道对应一个 description不要缓存复用。第二类样本数据格式不对。就是上一节说的 Annex B 和长度前缀混用问题。还有一种情况是 MP4 里恰好用 2 字节长度前缀但你写死 4 字节。如果在特殊封装里记得先读 avcC 的第 4 个字节动态解析出 lengthSizeMinusOne再按对应规则处理样本。5.3 时间戳单位微秒不是毫秒EncodedVideoChunk 的timestamp和duration单位都是微秒这个我踩过很多次。如果你的 demuxer 给出的时间戳是以毫秒或秒为单位需要换算微秒 秒 * 1000000 微秒 毫秒 * 1000如果是 MP4 容器给出的 pts/dts基于 track 的 timescale那么微秒 pts / timescale * 1000000顺手把 timescale 也存下来做音视频同步时会省很多事。很多人配置全对、解码也正常但播放时画面一顿一顿十有八九是时间戳单位没换算。5.4 颜色空间和显示尺寸偏色问题往往被忽略WebCodecs 的 config 里有colorSpace字段包含 primaries、transfer、matrix、fullRange。如果视频是广色域或者 HDR但不声明 colorSpace浏览器可能按默认 BT.709 去解释结果就是偏灰、偏绿、颜色发闷。codedWidth/codedHeight和实际显示尺寸不一定一样。有些视频为了对齐编码宏块coded 尺寸会大于 visible 尺寸比如 1922x1082 这样。codedWidth/codedHeight应该填编码后的真实尺寸显示时再按宽高比缩放不要直接把 1920x1080 填进去。如果你拿到 coded 尺寸后仍出问题可以用VideoFrame.displayWidth/displayHeight做最终展示裁剪。5.5 常见问题排查决策表症状最可能原因处理方式isConfigSupported 抛 TypeErrorcodec 字符串不符合规范用 ffprobe 重新生成 codec 字符串isConfigSupported 返回 supported: falsedescription 格式不对或硬件不支持 profile检查 avcC 是否从 configurationVersion 开始尝试 no-preferenceerror 回调报 Failed to parse descriptiondescription 不是合法的配置记录确认没有把 box header 传进去解码成功但黑屏description 与当前流不匹配或样本格式不对更新 description检查 NALU 长度前缀画面一顿一顿时间戳单位错误统一换算为微秒颜色偏绿发灰缺少 colorSpace 配置从 ffprobe 拉 color_primaries/color_transfer/color_space 并映射进 config5.6 实际项目中什么时候手写什么时候交给库如果你只是做播放器外壳建议用 mediabunny、hls.js 的 WebCodecs 分支这类现成库它们已经帮你处理好了 demux、description 提取、chunk 时间戳换算不需要自己写。但如果你想做低延迟推流预览、自定义解码器、或者想真正理解 WebCodecs那字节级的 parsing 能力是绕不开的。我自己现在排查问题时的习惯是拿到一个打不开的视频第一件事就是 ffprobe 把 extradata 拉出来用 hex 编辑器对一遍 SPS/PPS再决定是不是 description 的锅。大多数疑难杂症到这一步就已经定位了。

相关新闻

UDP组播实战:海康IPC设备自动探测与发现机制详解

UDP组播实战:海康IPC设备自动探测与发现机制详解

简介:面向安防系统集成与网络开发者的海康网络摄像机自动探测示例工程,基于UDP组播与ONVIF协议实现设备发现,适合有一定Socket基础、希望掌握局域网设备搜索机制的开发者研读,在大型监控系统或设备集成项目中均有参考价值。压缩包…

2026/10/11 4:43:45 阅读更多 →
开关电源环路稳定性分析:从传递函数到相位裕度实战指南

开关电源环路稳定性分析:从传递函数到相位裕度实战指南

打开示波器看到输出波形在“跳舞”,是调开关电源过程中最容易让人头秃的时刻。前阵子帮朋友看一块12V转5V的Buck模块,空载时一切正常,一带载就“滋滋”响,波形像被谁捏住了脖子。有经验的同事过来扫了一眼,说“环路相位…

2026/10/11 4:47:40 阅读更多 →
YashanDB迁移实践:7步从Oracle平滑切换上线

YashanDB迁移实践:7步从Oracle平滑切换上线

数据库选型这件事,做过一次就知道有多折腾。最近我一个内部业务系统重构,数据量不算大但兼容性要求卡得很死,最后用 YashanDB 把整套应用从 Oracle 迁移过来并顺利上线,整个过程我拆成了 7 个步骤,从环境准备一直做到线…

2026/10/9 17:43:27 阅读更多 →

最新新闻

从Shape案例彻底搞懂Java抽象类设计与落地细节

从Shape案例彻底搞懂Java抽象类设计与落地细节

写这篇的时候,我心里其实挺有感触的。很多人学抽象类,都是从 Shape 这个类入手的——课本上画个圆、画个矩形,定义个area()方法,然后就没下文了。结果到了实际项目里,一用就懵:抽象类到底该放哪些方法&…

2026/10/12 5:53:28 阅读更多 →
Winform仿QQ登录界面开发:无边框窗体、验证码与密码加密实现详解

Winform仿QQ登录界面开发:无边框窗体、验证码与密码加密实现详解

简介:一份基于C# Winform技术开发的QQ登录界面源码,以QQ2013版为仿制对象,面向桌面应用初学者和GUI设计爱好者,可帮助快速掌握Winform控件布局与视觉定制。压缩包仅1.37MB,共129个文件,内含93个png界面素材…

2026/10/12 5:53:28 阅读更多 →
2026年SAP开发者必学十大技术:从CDS到AI智能体

2026年SAP开发者必学十大技术:从CDS到AI智能体

作为一个从ECC时代一路改到S/4HANA、从ABAP报表写到BTP扩展的SAP老从业者,这两年最常被同行问的问题就是:2026年了,到底该学点什么才不被淘汰?说实话,SAP这套技术栈比外面很多互联网框架都要老,但正因为老&…

2026/10/12 5:53:28 阅读更多 →
AI助手跨会话记忆方案:claude-mem安装配置与核心机制拆解

AI助手跨会话记忆方案:claude-mem安装配置与核心机制拆解

你有没有遇到过这种情况:跟AI助手聊得正起劲,把项目背景、踩过的坑、选型理由从头到尾讲了一遍,结果一关窗口,下次会话它全忘了。你又得把同样的话再说一遍,甚至第三遍、第四遍。我老早就想解决这个问题。给AI助手加一…

2026/10/12 5:53:28 阅读更多 →
北京环路矢量面数据工程实践:坐标转换、拓扑修复与圈层分析

北京环路矢量面数据工程实践:坐标转换、拓扑修复与圈层分析

简介:北京市二环至六环环路矢量面数据,是一份基于2020年全国道路数据提取、经拓扑检查等处理生成的实用GIS数据,面向城市规划、地理信息分析、交通研究等人员,解决环路矢量面数据零散难找的问题。压缩包共含36个文件,以…

2026/10/12 5:53:28 阅读更多 →
Python成绩统计作业复盘:从平行列表到字典与函数重构

Python成绩统计作业复盘:从平行列表到字典与函数重构

第二次作业发下来的那天,课程群里比平时安静了不少。第一次作业只要照着课堂示例把代码拼一拼,第二次题目一出,大家才发现要面对的是一整套流程:录入、存储、计算、排序、统计、输出。这道成绩统计题几乎在每个Python入门课程里都…

2026/10/12 5:52:28 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/12 0:16:43 阅读更多 →

月新闻

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