NAudio 中枚举 ACM 驱动程序(ACM Drivers):识别系统音频编解码器并定位可用 WaveFormat
音视频音频处理【免费下载链接】NAudioAudio and MIDI library for .NET项目地址https://gitcode.com/gh_mirrors/na/NAudio点击查看免费下载本文基于 NAudio 官方文档 Docs/EnumerateAcmDrivers.md 展开并结合 src/NAudio.WinMM/Compression 下的源码实现与 tests/NAudio.Windows.Tests/Acm/AcmDriverTests.cs 测试用例进行纵深解析。读完本文你将掌握什么是 ACM 编解码器、NAudio 中哪个类依赖 ACM 做格式转换、如何用AcmDriver.EnumerateAcmDrivers()三级遍历枚举出系统上所有驱动、标签与格式以及如何解读枚举输出包括 PCM 与非 PCM 格式的差异从而为WaveFormatConversionStream挑选出真实可用的目标WaveFormat。一、ACMMedia Foundation 之前的 Windows 音频压缩 APIACMAudio Compression Manager音频压缩管理器是 Windows 上一套处理压缩音频的老式 API历史早于 Media Foundation。它由msacm32.dll提供核心实现通过“驱动Driver”的形式把各种音频编解码器codec暴露给系统。从某种意义上讲这套体系在今天已经不那么重要了——大部分新开发的代码会优先使用 Media Foundation TransformsMFT或 DMO 来处理压缩音频。但实际项目中你仍会遇到这样的情况某些编解码器以 ACM 形式提供时反而更容易获取而在 Media Foundation 中未必能找到对应的 Transform。此时了解并善用 ACM 驱动枚举就是一项很有实用价值的排查手段。在 NAudio 中真正使用 ACM 编解码器的类主要是WaveFormatConversionStream位于 src/NAudio.WinMM/WaveFormatConversionStream.cs。当你构造它时需要同时提供一个源WaveFormat和一个目标WaveFormat二者之间的转换有两种典型方向从压缩音频到 PCM —— 这是解码Decoder从 PCM 到压缩音频 —— 这是编码Encoder。需要特别强调你不能随便挑两个WaveFormat定义就指望转换一定成功。ACM 只支持受驱动支持的转换你只能执行系统上真实存在的受支持变换supported transforms。这就是为什么提前枚举系统上安装的 ACM 驱动、看清每个驱动支持的格式具有不可替代的价值——它能直接告诉你该用什么样的WaveFormat才能成功调用某个编解码器。二、三级枚举的整体思路NAudio 将 ACM 驱动体系的枚举设计为清晰的三级结构对应三个核心类层级枚举入口返回类型含义第一级AcmDriver.EnumerateAcmDrivers()IEnumerableAcmDriver系统上安装的全部 ACM 驱动第二级driver.FormatTagsIEnumerableAcmFormatTag某个驱动支持的所有“格式标签”如 PCM、GSM、DviAdpcm 等编码类型第三级driver.GetFormats(formatTag)IEnumerableAcmFormat某个标签下所有具体的格式采样率、位深、声道数的组合对应源码中AcmDriver.cs 是入口类内部通过 P/Invoke 调用acmDriverEnum、acmFormatTagEnum、acmFormatEnum三个 Windows ACM API 完成遍历public static IEnumerableAcmDriver EnumerateAcmDrivers() { drivers new ListAcmDriver(); MmException.Try(AcmInterop.acmDriverEnum(new AcmInterop.AcmDriverEnumCallback(DriverEnumCallback), IntPtr.Zero, 0), acmDriverEnum); return drivers; }回调中每收到一个驱动句柄就包装成一个AcmDriver对象并加入列表private static bool DriverEnumCallback(IntPtr hAcmDriver, IntPtr dwInstance, AcmDriverDetailsSupportFlags flags) { drivers.Add(new AcmDriver(hAcmDriver)); return true; }这个过程初看有些绕但由此获得的信息对定位“到底该用哪个WaveFormat才能成功使用某个 codec”几乎是决定性的。三、完整枚举代码示例下面这段代码会遍历系统上所有 ACM 驱动并打印出它们各自的格式详情。它完整演示了上面提到的三级遍历是本文的核心实操样本来自 Docs/EnumerateAcmDrivers.mdforeach (var driver in AcmDriver.EnumerateAcmDrivers()) { StringBuilder builder new StringBuilder(); builder.AppendFormat(Long Name: {0}\r\n, driver.LongName); builder.AppendFormat(Short Name: {0}\r\n, driver.ShortName); builder.AppendFormat(Driver ID: {0}\r\n, driver.DriverId); driver.Open(); builder.AppendFormat(FormatTags:\r\n); foreach (AcmFormatTag formatTag in driver.FormatTags) { builder.AppendFormat(\r\n); builder.AppendFormat(Format Tag {0}: {1}\r\n, formatTag.FormatTagIndex, formatTag.FormatDescription); builder.AppendFormat( Standard Format Count: {0}\r\n, formatTag.StandardFormatsCount); builder.AppendFormat( Support Flags: {0}\r\n, formatTag.SupportFlags); builder.AppendFormat( Format Tag: {0}, Format Size: {1}\r\n, formatTag.FormatTag, formatTag.FormatSize); builder.AppendFormat( Formats:\r\n); foreach (AcmFormat format in driver.GetFormats(formatTag)) { builder.AppendFormat( \r\n); builder.AppendFormat( Format {0}: {1}\r\n, format.FormatIndex, format.FormatDescription); builder.AppendFormat( FormatTag: {0}, Support Flags: {1}\r\n, format.FormatTag, format.SupportFlags); builder.AppendFormat( WaveFormat: {0} {1}Hz Channels: {2} Bits: {3} Block Align: {4}, AverageBytesPerSecond: {5} ({6:0.0} kbps), Extra Size: {7}\r\n, format.WaveFormat.Encoding, format.WaveFormat.SampleRate, format.WaveFormat.Channels, format.WaveFormat.BitsPerSample, format.WaveFormat.BlockAlign, format.WaveFormat.AverageBytesPerSecond, (format.WaveFormat.AverageBytesPerSecond * 8) / 1000.0, format.WaveFormat.ExtraSize); if (format.WaveFormat is WaveFormatExtraData format.WaveFormat.ExtraSize 0) { WaveFormatExtraData wfed (WaveFormatExtraData)format.WaveFormat; builder.Append( Extra Bytes:\r\n ); for (int n 0; n format.WaveFormat.ExtraSize; n) { builder.AppendFormat({0:X2} , wfed.ExtraData[n]); } builder.Append(\r\n); } } } driver.Close(); Console.WriteLine(builder.ToString()); }对这段代码结合源码还有几个实操细节值得强调先Open()再访问FormatTags从 AcmDriver.cs 可以看到FormatTags属性在内部执行acmFormatTagEnum前会先检查driverHandle如果驱动尚未Open()会直接抛出InvalidOperationException(Driver must be opened first)。GetFormats(formatTag)也有同样的检查AcmDriver.cs。枚举后记得Close()Close()内部调用acmDriverClose并置空句柄而AcmDriver实现了IDisposableDispose()最终也会调用Close()见 AcmDriver.cs。更稳妥的写法是把driver包在using里。GetFormats内部会为WAVEFORMATEX分配 1024 字节缓冲区源码注释说明formatTag.FormatSize不可靠某些 codec 的MaxFormatSize也不可靠因此枚举格式时统一分配 1024 字节以保证容纳AcmDriver.cs。位速率换算AverageBytesPerSecond * 8 / 1000.0将字节/秒换算为 kbps例如 8000 字节/秒对应 64.0 kbps。四、解读输出以 GSM 6.10 为例枚举的输出通常非常冗长——如果你在系统上额外安装了一些编解码器输出规模还会进一步膨胀。下面是 GSM 6.10 编解码器输出的一个片段Long Name: Microsoft GSM 6.10 Audio CODEC Short Name: Microsoft GSM 6.10 Driver ID: 48141232 FormatTags: Format Tag 0: PCM Standard Format Count: 8 Support Flags: Codec Format Tag: Pcm, Format Size: 16 Formats: Format 0: 8.000 kHz, 8 Bit, Mono FormatTag: Pcm, Support Flags: Codec WaveFormat: Pcm 8000Hz Channels: 1 Bits: 8 Block Align: 1, AverageBytesPerSecond: 8000 (64.0 kbps), Extra Size: 0 Format 1: 8.000 kHz, 16 Bit, Mono FormatTag: Pcm, Support Flags: Codec WaveFormat: Pcm 8000Hz Channels: 1 Bits: 16 Block Align: 2, AverageBytesPerSecond: 16000 (128.0 kbps), Extra Size: 0 Format 2: 11.025 kHz, 8 Bit, Mono FormatTag: Pcm, Support Flags: Codec WaveFormat: Pcm 11025Hz Channels: 1 Bits: 8 Block Align: 1, AverageBytesPerSecond: 11025 (88.2 kbps), Extra Size: 0这个片段告诉我们几个要点Long Name/Short Name前者是驱动完整名称Microsoft GSM 6.10 Audio CODEC后者是简短名称Microsoft GSM 6.10。在 AcmDriverDetails.cs 中短名称缓冲区为 32 字符、长名称为 128 字符二者由acmDriverDetails填充。Driver ID驱动句柄IntPtr也是后续打开驱动、建立转换流的凭据。Format Tag与Format SizePcm标签的格式大小为 16 字节即标准WAVEFORMATEX头无扩展数据的尺寸。Block Align与AverageBytesPerSecond例如 8 kHz/16 位/单声道Block Align 为 2 字节每秒平均 16000 字节换算即 128.0 kbps。这些字段正是构造WaveFormat时需要用到的关键参数。Support Flags: Codec表示该驱动作为编解码器提供服务详见下文 Flags 一节。五、非 PCM 格式与 WaveFormatExtraData对于非 PCM 格式WaveFormat结构往往需要在标准 16 字节WAVEFORMATEX之后追加额外的编码参数Extra Bytes此时format.WaveFormat的实际类型是WaveFormatExtraDataExtraSize大于 0ExtraData数组中保存这些额外的字节。枚举代码中的最后一个分支正是负责把这段扩展数据以十六进制打印出来。下面是一个DviAdpcm即 IMA ADPCM 类格式的例子。可以看到该格式的WaveFormat结构需要两个额外的字节值分别是 0xF9 和 0x01 Format 1: 8.000 kHz, 4 Bit, Stereo FormatTag: DviAdpcm, Support Flags: Codec WaveFormat: DviAdpcm 8000Hz Channels: 2 Bits: 4 Block Align: 512, AverageBytesPerSecond: 8110 (64.9 kbps), Extra Size: 2 Extra Bytes: F9 01这条输出极具实战价值如果你打算用WaveFormatConversionStream把某段音频解码或编码为 DviAdpcm就必须构造出带相同 Extra Bytes0xF9、0x01的WaveFormatExtraData否则驱动无法正确理解你提交的格式转换可能直接失败。这也再次印证了文档的核心论断——枚举出来的信息对“构造正确的WaveFormat”是决定性的。六、核心 API 的源码级速查围绕枚举流程NAudio 在 src/NAudio.WinMM/Compression 下提供了如下关键类型理解它们的属性有助于你更精准地筛选驱动与格式AcmDriverAcmDriver.cs成员说明EnumerateAcmDrivers()静态枚举全部已安装 ACM 驱动底层调用acmDriverEnumFindByShortName(shortName)静态按短名称查找驱动找不到返回nullIsCodecInstalled(shortName)静态判断某个 codec 是否已安装按短名称匹配AddLocalDriver(driverFile)静态从.acm/DLL 文件加载本地驱动底层依次调用NativeLibrary.TryLoad与acmDriverAddRemoveLocalDriver(localDriver)静态卸载之前用AddLocalDriver添加的本地驱动ShowFormatChooseDialog(...)静态弹出系统 ACM 格式选择对话框ShortName/LongName驱动短/长名称来自acmDriverDetailsDriverId驱动 IDIntPtr句柄FormatTags该驱动的格式标签集合要求先Open()GetFormats(formatTag)某标签下的全部格式要求先Open()Open()/Close()打开/关闭驱动句柄对应acmDriverOpen/acmDriverCloseMaxFormatSize通过acmMetrics(MaxSizeFormat)查询 ACM 互操作所需的最大格式大小AcmFormatTagAcmFormatTag.cs属性说明FormatTagIndex标签序号FormatTag标签对应的WaveFormatEncoding如Pcm、DviAdpcmFormatSize该标签下格式结构的大小含扩展部分源码注释提示它并不可靠StandardFormatsCount该标签下的标准格式数量SupportFlags驱动的支持标志见下文枚举FormatDescription标签的人类可读描述缓冲区 48 字符见 AcmFormatTagDetails.csAcmFormatAcmFormat.cs属性说明FormatIndex格式序号FormatTag格式所属的WaveFormatEncodingSupportFlags该格式的支持标志WaveFormat构造出的完整WaveFormat对象内部从WAVEFORMATEX指针反序列化而来WaveFormatByteSizeWaveFormat结构的总字节数FormatDescription格式描述例如 8.000 kHz, 16 Bit, Mono缓冲区 128 字符见 AcmFormatDetails.csSupport Flags 枚举AcmDriverDetailsSupportFlags.csSupportFlags是一个[Flags]枚举可能同时包含多个位。核心取值如下标志值含义Codec0x00000001该驱动是编解码器Converter0x00000002该驱动是格式转换器Filter0x00000004该驱动是滤波器Hardware0x00000008支持硬件Async0x00000010支持异步操作Local0x40000000本地驱动Disabled0x80000000驱动当前被禁用筛选时例如只关心编解码能力可判断(flags AcmDriverDetailsSupportFlags.Codec) ! 0。七、配套便捷方法与典型应用除了三级枚举AcmDriver.cs 还提供两个高频使用的便捷静态方法它们同样以枚举为基础AcmDriver.IsCodecInstalled(shortName)遍历所有驱动、比对ShortName判断某个 codec 是否已安装。例如在测试 AcmDriverTests.cs 中IsCodecInstalled(MS-ADPCM)在标准 Windows 上应返回true而一个不存在的名字则返回false。AcmDriver.FindByShortName(shortName)返回第一个短名称匹配的驱动对象常用于拿到特定 codec 后直接Open()并枚举其格式。测试CanEnumerateFormats正是以AcmDriver.FindByShortName(MS-ADPCM)开头见 AcmDriverTests.cs。一个典型的实战链路是先FindByShortName或IsCodecInstalled确认目标 codec 存在 → 枚举其FormatTags与GetFormats找到合适的格式 → 用枚举得到的WaveFormat含必要的WaveFormatExtraData构造WaveFormatConversionStream完成编解码。八、线程安全msacm32 的进程级锁值得特别留意的是 AcmInterop.cs 类注释中记录的一个重要实现事实NAudio 曾观察到在多线程并发调用msacm32.dll时会出现访问冲突access violations详见源码中引用的 NAudio 历史 issue #355、#629。因此 NAudio 采取防御性措施——用一个进程级的可重入锁AcmInterop.AcmLock串行化所有 msacm32 的 P/Invoke 调用。这意味着驱动枚举、格式枚举等操作在执行期间会阻塞进程内其他 ACM 相关工作ACM 操作在进程内实际上是单线程化的AcmStream.cs 的类注释进一步建议对高吞吐场景优先考虑 Media Foundation 或基于 DMO 的解码/编码方案。这一点在写并发音频处理代码时非常关键——不要在多个线程中同时发起 ACM 调用也不要因为枚举操作短暂阻塞而误以为死锁。九、测试验证与结论NAudio 仓库的集成测试 AcmDriverTests.cs标注[Category(IntegrationTest)]需要在真实 Windows 环境运行覆盖了与本文直接相关的全部环节可作为你验证环境与理解的参照CanEnumerateDrivers验证EnumerateAcmDrivers()返回非空且每个驱动的DriverId非零、ShortName非空CanOpenAndCloseDriver对每个驱动执行Open()/Close()CanEnumerateFormatTags对每个驱动枚举FormatTags并输出标签详情CanEnumerateFormats用FindByShortName(MS-ADPCM)找到驱动后遍历其全部格式FindsStandardCodec/DoesntFindNonexistentCodec验证IsCodecInstalled的命中与不命中路径。总结来说虽然 ACM 是 Windows 上偏“古老”的音频压缩体系但在某些 codec 只有 ACM 版本可用的场景下掌握AcmDriver.EnumerateAcmDrivers()驱动的三级枚举就能准确回答“系统上到底有哪些编解码器、每个编解码器支持哪些精确的WaveFormat含扩展字节”从而为WaveFormatConversionStream的编解码调用构造出真正可用、可成功的格式参数。赞分享音视频音频处理【免费下载链接】NAudioAudio and MIDI library for .NET项目地址https://gitcode.com/gh_mirrors/na/NAudio点击查看免费下载相关推荐Fallout 1 CE音乐系统与ACM格式解码深度解析Fallout 1 CE音乐系统与ACM格式解码深度解析 引言后核战世界的音频复兴 在辐射Fallout系列的经典游戏中音频系统不仅是营造沉浸式后核战世游戏开发NodeGui 中 SelectionFlag 枚举详解驱动 QItemSelectionModel 选择行为的位标志体系NodeGui 中 SelectionFlag 枚举详解驱动 QItemSelectionModel 选择行为的位标志体系 SelectionFlag 是 N桌面应用跨平台上一篇OptiScaler跨GPU游戏超分辨率优化工具使用指南下一篇约定式提交Conventional Commits1.0.0-beta.1 规范详解以结构化提交信息驱动版本管理与 CHANGELOG 自动化创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

SSD主控量产模式修复:慧荣群联闪迪协议深度解析

SSD主控量产模式修复:慧荣群联闪迪协议深度解析

1. 这不是“一键修复”,而是主控芯片级的固态硬盘外科手术你手边那块突然变砖、不识别、掉速严重、频繁报错的SSD,大概率不是颗粒坏了,而是它的“大脑”——主控芯片——在固件层面出了问题。市面上那些标榜“秒恢复”的U盘式修复工具&#x…

2026/10/9 7:30:09 阅读更多 →
Claude Code 报错 Unable to verify if domain code.claude.com is safe to fetch:用 settings.json 关闭 WebFet

Claude Code 报错 Unable to verify if domain code.claude.com is safe to fetch:用 settings.json 关闭 WebFet

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

2026/10/9 7:29:08 阅读更多 →
Dapr分布式应用运行时实战:Sidecar构建块与生产部署指南

Dapr分布式应用运行时实战:Sidecar构建块与生产部署指南

1. 分布式应用开发的真实痛点,Dapr 到底在解决什么先说个背景。这几年只要聊微服务、聊云原生,“分布式应用运行时”这个词出现的频率越来越高,Dapr 就是其中最具有代表性的一个落地项目。我在实际项目里做过不少分布式系统,从早期…

2026/10/9 7:29:08 阅读更多 →

最新新闻

黑白纸片题解:从二维矩阵到单调栈,最大全黑矩形面积详解

黑白纸片题解:从二维矩阵到单调栈,最大全黑矩形面积详解

1. 题目原题:黑白纸片到底求什么1.1 回忆版题目描述3月15号上午顺丰春招笔试,第二题叫《黑白纸片》,刷了一圈讨论区,考生普遍反馈:题面很好懂,真正写起来才发现建模才是关键。我先把回忆版的题面整理如下&a…

2026/10/9 7:54:23 阅读更多 →
Java+小程序名片系统:可控落地的全栈实践指南

Java+小程序名片系统:可控落地的全栈实践指南

简介:这是一套面向高校计算机专业学生与Java全栈初学者的微信小程序名片管理系统实战项目,适用于课程设计、毕业设计及小程序开发入门实践。系统采用前后端分离架构,前端基于微信小程序原生开发,后端可选SSM或SpringBoot框架&…

2026/10/9 7:54:23 阅读更多 →
家用商用电器企业主数据管理MDM蓝图方案

家用商用电器企业主数据管理MDM蓝图方案

本蓝图方案面向家用商用电器集团的 IT 项目组、业务部门负责人、实施顾问。针对多工厂集团存在主数据标准不统一、料号重复、图纸 BOM 无法跨厂共享、各业务系统割裂等痛点。 文档覆盖 MDM 主数据、销售、生产、物料、财务五大模块,梳理集团多工厂组织架构,定义完整业务流程清…

2026/10/9 7:54:23 阅读更多 →
impeccable工程实践:可验证的质量刻度与故障可解释性

impeccable工程实践:可验证的质量刻度与故障可解释性

1. “impeccable”不是一句空话:当这个词突然在技术圈高频出现,背后藏着什么信号?最近翻看几份开源项目的更新日志、某跨平台系统的设计文档草稿,甚至一份面向初学者的CLI工具教学笔记,都反复撞见一个词——impeccable…

2026/10/9 7:54:23 阅读更多 →
SIP2协议ACS模拟器:从帧结构到自助借还联调避坑指南

SIP2协议ACS模拟器:从帧结构到自助借还联调避坑指南

简介:这是面向图书馆自助服务开发与测试场景的ACS自助借还服务端模拟工具源码包,基于C#编写,遵循SIP2协议,主要用于模拟ACS服务端行为,帮助开发者或测试人员验证自助借还客户端的交互流程。资源共包含117个文件&#x…

2026/10/9 7:54:23 阅读更多 →
计算机网络试题库高效刷题指南:从分层模型到避坑技巧

计算机网络试题库高效刷题指南:从分层模型到避坑技巧

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

2026/10/9 7:53:22 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

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/8 15:26:32 阅读更多 →
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/8 15:26:40 阅读更多 →
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/8 10:10:36 阅读更多 →

月新闻

我发现了一个新思路:用 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/8 21:13:17 阅读更多 →
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/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练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/9 6:17:20 阅读更多 →