NCM转MP3/FLAC全攻略:原理、脚本与避坑指南

如果你下载过某头部音乐平台的VIP曲目,电脑里多半躺着不少.ncm结尾的文件。这类文件的特点是:在它自家App里播放一切正常,一旦把文件拷贝到车载播放器、电视盒子,或者你想用本地播放器整理歌单,立刻变成一堆“无法识别”的二进制垃圾。NCM格式破解这件事,说白了就是把这层加密壳去掉,还原成MP3或FLAC。我去年花了一个周末把整套原理、脚本和坑摸了一遍,这篇文章按“原理→选型→实操→排坑”的顺序完整复盘,保证你照着走能跑通。

1. NCM 是个什么文件:不只是加密那么简单

1.1 它的定位:平台锁定的软DRM容器

NCM是某音乐平台的私有容器格式,本质是“把标准音频编码(MP3/FLAC)装进一个加了密的盒子里”。为什么平台要这么干?三方面原因:

  • 版权方施压:下载文件不能裸奔,必须带技术保护,否则无损文件被抓包后直接在网络上传开。
  • 防止“白嫖式分享”:即使付费下载,文件离开发行播放器就无法被通用播放器读取,想传到公开渠道分享的成本变高。
  • 生态锁定:这个格式只认自家播放器,用户积累成千上万首歌之后,换平台的迁移成本极高,就被牢牢绑住了。

从技术上讲,NCM 不是强DRM。真正的DRM会有服务器授权验证、离线许可过期、硬加密绑定设备等机制。NCM更像一个“软加密容器”:文件里藏着解密所需的一切,播放时本地自己解开。也就是说,客户端里必然存在解锁必须的密钥材料,逆向工程只需要从客户端里把它找出来。这决定了 NCM 转换是可行的,不存在“永远解不开”的情况——谁会拒绝自己派发的解药呢。

1.2 容器结构:一张表看清文件里都是什么

拿到一个.ncm文件,用十六进制编辑器打开,布局是固定的。下面是我实测过的结构(以新版为主,旧版大同小异):

偏移字段长度说明
0x00–0x07魔数8字节固定为CTENFDAM,不是它就不是NCM
0x08–0x0B密钥区长度4字节小端序无符号整数
0x0C 起密钥区不定长每个字节与0x64异或后,是RSA密文
密钥区后元数据区长度4字节小端序无符号整数
元数据区元数据负载不定长每字节与0x63异或,再Base64解码得到JSON
元数据区后CRC校验5字节4字节CRC32 + 1字节保留
文件末尾音频数据不定长AES-128-ECB加密后的音频,每个字节再叠加0xA3异或

这个结构本身不复杂,对着二进制看十分钟就懂。真正有价值的是后面的加密链路:为什么这三个异或掩码这么关键,以及为什么会藏着一条RSA私钥。

1.3 加密链路:RSA + AES + XOR 三重混合

NCM 的核心加密逻辑是“混合加密”,三个环节各有分工。

  1. 密钥封装(RSA加密):每个文件在生成时会随机产生一条16字节的AES密钥。这条密钥被平台内置的RSA公钥加密后写入密钥区。转换时,先用0x64还原出RSA密文,再用从客户端里提取的RSA私钥解密,就得到真正的AES密钥。
  2. 音频加密(AES-128-ECB):原始音频数据先按字节与0xA3异或,再做16字节分块的AES-128-ECB加密,最后写入容器。ECB模式没有IV、不链接块,解密时逐块独立处理,实现非常简单。
  3. 元数据掩码(XOR):歌曲名、歌手、专辑、封面图的Base64等元数据,做0x63异或。这里的XOR只是增加一点点逆向门槛,谈不上安全。

用生活类比:RSA相当于一个大保险柜,里面放着每一首歌独立的小锁(AES密钥)。大保险柜的钥匙(RSA私钥)竟然也在客户端里——因为播放时必须用大钥匙拿出小锁来开门。这就是所有客户端本地加密的死穴:私钥分发到用户手里,就等于没锁。

我刚开始也困惑:为什么不直接RSA加密整个音频?因为音频太大,RSA速度慢又不适合流式解码。用随机AES密钥加密文件本体,再用RSA保护这个小密钥,兼顾安全与性能,是标准的混合加密设计。NCM的问题只在于,它把私钥也随着播放器发出来了。

2. 方案选型:三条路,别一上来就写脚本

2.1 现成开源命令行工具:效率首选

如果只想要结果,直接用社区维护的开源转换器。这类工具的操作非常统一,下面命令里的ncm-tool是泛指,换成你找到的工具即可:

# 单曲转换 ncm-tool -f "某首歌.ncm" -o ./converted/ # 批量转换目录 ncm-tool -d ./music/ -o ./converted/

转换完成会自动输出同名.mp3或.flac,顺手把封面图存成.cover.jpg,歌词存成.lrc。GitHub上这类项目有好几个语言版本:Go版性能好,Rust版单文件分发方便,Python版最易读。选星标最多、近期还在更新的那个就行。实测几百首歌也就是几十秒的事,不值得为“纯转换”自己从头写脚本。

2.2 自己写脚本:学习价值大于省事价值

自己写一遍,能把格式彻底玩明白。之后遇到“要批量重命名、按专辑归档、嵌入封面、统一转FLAC”这类衍生需求,都能自己改。代价是要处理RSA私钥、AES填充、JSON元数据这些细节,新手可能要折腾半天。我的做法是双线操作:先用现成工具把整库转出来保证能用,再用Python重写核心逻辑,验证自己的理解。两条腿走路,两头都不耽误。

2.3 在线转换站:方便但有隐患

网上不少“NCM在线转MP3”的网站,拖进去就给你下载转换好的文件。它们适合处理零星几首,但我个人不推荐大批量使用:

  • 整段音乐文件上传到第三方服务器,有隐私和版权风险;
  • 通常限速、限大小、要排队;
  • 转换质量参差不齐,有的连封面都丢;
  • 对几十G的曲库完全不现实。

2.4 路线对比与最终选择

方案学习成本批量能力隐私安全适合人群
开源命令行工具5分钟强全本地处理大多数普通用户
自写脚本半天到一天最强,可定制全本地处理开发者、爱折腾的人
在线转换站2分钟弱有风险只转几首、应急用

我的最终选择是:日常转换用开源工具,碰到工具处理不了的边界情况再上自己的脚本。下面实操部分,我会把两条线都走一遍。

3. 实操全流程:从分析文件到批量转出 MP3/FLAC

3.1 准备环境

命令行工具版基本零依赖,下载即用。脚本版需要准备:

  • Python 3.9+;
  • 密码学依赖:pip install pycryptodome,执行from Crypto.Cipher import AES不报错即成功;
  • 可选安装带ffprobe的 ffmpeg,用来校验输出文件的时长和比特率。

3.2 第一步:用现成工具跑通单曲

拿一首你确定能合法自用的测试曲目,执行:

mkdir -p ~/Music/converted ncm-tool -f "测试曲.ncm" -o ~/Music/converted/

正常几秒钟后,输出目录会多出三个文件:转换后的测试曲.mp3、封面测试曲.cover.jpg、歌词测试曲.lrc。这一步的意义不是“测试工具”,而是确认你的源文件没损坏、输出目录权限没问题。任何工具遇到异常都会打印错误,先看文件本身,再看版本兼容性,具体排查放第四章。

3.3 核心脚本拆解:自己实现一遍加密链路

下面这段Python完成“解析→解密钥→解音频→还原元数据”全流程。出于篇幅考虑,RSA私钥的PEM内容不贴在这里,开源仓库里都能找到,脚本里以占位符代替:

import json import base64 import struct from Crypto.Cipher import AES, PKCS1_OAEP from Crypto.PublicKey import RSA MAGIC = b"CTENFDAM" KEY_XOR = 0x64 META_XOR = 0x63 AUDIO_XOR = 0xA3 # 私钥PEM从开源仓库获取后替换占位符 RSA_PEM = "-----BEGIN PRIVATE KEY-----\n... 开源仓库获取 ...\n-----END PRIVATE KEY-----" def parse_ncm(path): with open(path, "rb") as f: data = f.read() # 1. 检查魔数 if data[:8] != MAGIC: raise ValueError("不是有效的NCM文件") # 2. 读取密钥区长度,异或还原RSA密文 key_len = struct.unpack("<I", data[8:12])[0] rsa_cipher = bytes(b ^ KEY_XOR for b in data[12:12 + key_len]) pos = 12 + key_len # 3. 读取元数据区:异或还原 -> Base64解码 -> JSON meta_len = struct.unpack("<I", data[pos:pos + 4])[0] pos += 4 meta_b64 = bytes(b ^ META_XOR for b in data[pos:pos + meta_len]) meta = json.loads(base64.b64decode(meta_b64).decode("utf-8")) pos += meta_len # 4. 跳过5字节(CRC32 + 保留位) pos += 5 # 5. 剩余全部是音频数据 audio_enc = data[pos:] return rsa_cipher, meta, audio_enc def decrypt_ncm(rsa_cipher, audio_enc): # 用RSA私钥解出AES密钥 rsa_key = RSA.import_key(RSA_PEM) cipher_rsa = PKCS1_OAEP.new(rsa_key) payload = cipher_rsa.decrypt(rsa_cipher) aes_key = payload[-16:] # 前17字节是固定标记,末尾16字节才是AES密钥 # AES-128-ECB解密 cipher_aes = AES.new(aes_key, AES.MODE_ECB) audio_raw = cipher_aes.decrypt(audio_enc) # 异或还原音频原始字节 audio = bytes(b ^ AUDIO_XOR for b in audio_raw) # 去掉PKCS7填充(注意校验边界) pad_len = audio[-1] if pad_len and pad_len <= 16: audio = audio[:-pad_len] return aes_key, audio if __name__ == "__main__": rsa_cipher, meta, audio_enc = parse_ncm("测试曲.ncm") _, audio = decrypt_ncm(rsa_cipher, audio_enc) ext = ".flac" if audio[:4] == b"fLaC" else ".mp3" with open("测试曲" + ext, "wb") as f: f.write(audio) print("format:", meta.get("format"), "bitrate:", meta.get("bitrate"))

几个容易翻车的地方,需要特别注意。

  • RSA解密结果不是纯AES密钥:前面有一段固定文本标记,末尾16字节才是真正密钥。取错位置,整段音频乱码。
  • AES模式不能选错:NCM用的是ECB,不是CBC、CTR。ECB没有IV,代码里不需要随机向量;如果你用别的模式解密,出来全是刺啦声。
  • PKCS7填充:原始音频长度不是16的倍数,加密前补了填充;解密后要去掉末尾填充字节,否则播放器会读到一个多余的尾块,时长显示偏长。
  • 格式判断:解密后的音频头部自带特征。FLAC以fLaC开头,MP3多以ID3或FF FB/F3/F2开始;不要盲信元数据里的format字段。

3.4 还原封面与歌词:让转换产物不是“半成品”

NCM的元数据JSON里通常有albumPic字段,值是封面图的Base64;部分文件还带歌词文本。建议把它们还原成“同名文件”形式,方便手机播放器自动配对:

def save_cover(meta, out_path): pic = meta.get("albumPic") if pic: with open(out_path + ".cover.jpg", "wb") as f: f.write(base64.b64decode(pic)) def save_lyric(meta, out_path): lrc = meta.get("lyric", "").strip() if lrc: with open(out_path + ".lrc", "w", encoding="utf-8") as f: f.write(lrc)

想把封面直接嵌进MP3而不是丢一个独立.jpg,可以用ffmpeg一次搞定:

ffmpeg -i output.mp3 -i output.cover.jpg -map 0:0 -map 1:0 -c copy \ -id3v2_version 3 -metadata:s:v title="Album cover" -metadata:s:v comment="Cover (front)" \ output_embed.mp3

注意:很多平台的歌词是联网获取的,根本不放进NCM文件,所以转换后没有.lrc是正常现象。想要歌词,只能事后用歌词插件或第三方接口补,自己把握合规。

3.5 批量转换与产物校验:确保不是“自欺欺人的成功”

批量转换用现成工具最舒服,一条命令扫目录:

ncm-tool -d ~/Music/某平台下载/ -o ~/Music/converted/

如果写脚本批量处理,用标准库os.walk收集所有.ncm,逐条调用上面的parse_ncm + decrypt_ncm即可。重点在转换后的校验,我一般做三层:

  1. 文件层:产物大小不为0,扩展名正确,MP3能正常被播放器打开;
  2. 元数据层:时长与原App显示值对得上。命令行用:
    ffprobe -show_format -show_error converted.mp3 2>&1 | grep -E "duration|bit_rate"
  3. 抽样耳朵层:随机抽3到5首,听开头、中间、结尾,确认没有断帧、爆音、码率下降。

我第一次批量转完以为成功了,结果发现有一半文件因为当初下载中断,音频区被截断,AES解密后直接报“填充错误”。所以:校验不是可选项,是必选项。

4. 常见问题与避坑实录

4.1 转换出来的音频损坏或时长不对

  • 症状:能打开但播放到一半跳秒、时间轴长度怪、尾音缺失。
  • 原因1:PKCS7填充没去掉。AES解密后最后的填充字节被当作音频写进文件,播放器误认为是音轨一部分。解决办法是脚本里的pad_len处理。
  • 原因2:模式或密钥选错。CBC与ECB一字之差,出来全是噪声。检查代码里有没有“IV”参数,有就说明模式不对。
  • 原因3:源文件下载不完整。魔数和头部都完整,但音频数据被截断。这种情况哪个工具都救不了,只能重新下载。

4.2 转换出来是128Kbps,说好的无损呢

  • 注意“VIP下载”不等于“无损下载”。很多会员曲目默认下载的是128Kbps MP3,NCM只是外面那层壳。
  • 元数据的bitrate和format字段直接反映源音质:format为mp3就是有损压缩,flac才是无损。
  • 不要做“MP3转FLAC”的伪升级,那只是文件体积变大,音质没有任何提升。转完后用ffmpeg -i output.mp3 2>&1 | grep Audio看真实编码和码率。

4.3 封面、歌词不全

  • 封面丢了通常是albumPic字段本身为空,常见于某些特殊版本文件,与转换工具无关。
  • 歌词丢了大半是源头问题:平台歌词接口不返回,或者文件本身没带歌词。想补歌词可以靠手机播放器自带的自动匹配,也可以本地维护同名歌词文件。
  • 批量嵌入封面时,遇到过ffmpeg因为图片尺寸过大而警告的情况,问题不大;如果强制报错,先把封面长边压到1000px内再嵌入。

4.4 平台客户端更新会不会让老工具失效

  • 只要客户端还在本地解密,这类方案就不会失效,除非平台换成服务器在线授权的强DRM体系——那影响的是所有用户,产品决策会非常谨慎。
  • 如果某天新下载的NCM文件用工具报错,先判断是不是新版本格式:用十六进制编辑器看魔数后的布局是否与本文一致;不一致就等开源社区更新。
  • 建议保留.ncm原件做备份,别在转换后顺手删除。万一格式迭代,你还有原始文件等新工具处理。

4.5 关于“破解”这件事的边界

做技术科普和实际转换,前提是只处理自己合法获得的文件。NCM转换本质是个人曲库的格式迁移,不是制作盗版资源的通道。以下几点务必记住:

  • 只转换你自己账号下载、付费购买的音乐;
  • 不要在公开渠道传播转换后的文件,更不要拿去卖;
  • 平台服务条款通常禁止逆向和破解,教学用途请自行权衡风险;
  • 版权归属在版权方手里,付费获得的是使用授权,不是所有权。

把“破解”理解成“解锁自己设备的播放自由”没什么问题,但越界到“破解别人的东西”就是另一回事了。

最后说点个人体会。折腾完NCM这套东西,我最大的感受是:技术上的加密强弱是一回事,生态锁定才是更厉害的锁。哪怕你手里的文件全部被解开成标准MP3,平台真正想留住的并不是那串二进制,而是你习惯打开它的那个动作。所以每次有朋友问要不要转换,我都会先反问一句:你是真的想把歌带走,还是只是觉得文件打不开很烦?如果是后者,按本文流程走一遍一劳永逸。另外,不删原文件、务必校验产物、不碰不属于自己的文件——这三点踩过的坑,比任何命令行参数都值钱。

相关新闻

能力越强越会骗人?大模型对齐难题与可信度评测的工程实践

能力越强越会骗人?大模型对齐难题与可信度评测的工程实践

1. 从"能力跃迁"到"信任崩塌"&#xff1a;这次叫停到底踩中了哪根线先把这件事的核心矛盾摆出来。一个模型版本在内部评测中跑出了比前代高出一大截的综合分数&#xff0c;推理链路更长、工具调用更准、多步任务完成率明显上升&#xff0c;按常规逻辑这应该…

2026/10/20 9:14:02 阅读更多 →
语音转文字效率翻倍:从预处理到说话人分离的完整工作流

语音转文字效率翻倍:从预处理到说话人分离的完整工作流

1. 为什么你总觉得语音转文字“做不快”——问题不在引擎&#xff0c;在流程先说个我自己的经历。前阵子帮人整理一段三个小时的行业圆桌讨论录音&#xff0c;里面七八个人轮流发言&#xff0c;偶尔还互相插话。我开始也是直接丢进转写工具&#xff0c;等着出稿子。结果两个小时…

2026/10/20 9:14:02 阅读更多 →
AI端到端测试重放缓存:原理、实现与优化实践

AI端到端测试重放缓存:原理、实现与优化实践

1. 端到端测试的"重放缓存"到底在解决什么问题做过端到端测试的人都有一个共同的痛&#xff1a;跑一遍全量用例&#xff0c;动辄十几分钟甚至半小时起步。如果测试用例里还涉及AI模型的调用——比如让模型去理解页面结构、生成操作步骤、判断断言结果——那时间成本和…

2026/10/20 9:14:02 阅读更多 →

最新新闻

UDS协议栈从入门到精通:状态机、安全访问与踩坑实战全解析

UDS协议栈从入门到精通:状态机、安全访问与踩坑实战全解析

UDS&#xff08;Unified Diagnostic Services&#xff0c;统一诊断服务&#xff09;这个缩写&#xff0c;在车载电子圈里几乎每天都会碰到。做ECU开发的人要跟诊断仪打交道&#xff0c;做测试的人要对着诊断报文调参数&#xff0c;做车联网的人要解析诊断数据——但真正能把UDS…

2026/10/20 10:05:47 阅读更多 →
pyVideoTrans实战:从语音识别到自动配音的视频翻译工具指南

pyVideoTrans实战:从语音识别到自动配音的视频翻译工具指南

简介&#xff1a;pyVideoTrans是一款开源的视频翻译配音工具&#xff0c;主要面向视频创作者、字幕翻译者和需要批量处理音视频的用户&#xff0c;可将一种语言视频自动生成指定语言字幕并完成配音。它集成语音识别、字幕翻译、配音合成、字幕格式转换、人声分离、音视频合并与…

2026/10/20 10:05:47 阅读更多 →
YALMIP资源下载与安装全指南:MATLAB路径配置、求解器接口与避坑实战

YALMIP资源下载与安装全指南:MATLAB路径配置、求解器接口与避坑实战

简介&#xff1a;YALMIP 官方 R20230609 版资源包&#xff0c;是面向 MATLAB 环境下运筹优化、自动控制及算法研究者的完整建模工具箱&#xff0c;可用来快速构建与求解线性规划、二次规划、混合整数规划、非线性规划以及动态最优控制问题。压缩包共 1307 个文件&#xff0c;以…

2026/10/20 10:05:47 阅读更多 →
51单片机智能交通灯:车流感知与自适应配时实现

51单片机智能交通灯:车流感知与自适应配时实现

简介&#xff1a;本资源是一套完整的智能交通灯控制器嵌入式开发实践包&#xff0c;面向电子类、自动化及物联网方向的本科课程设计、毕业设计与单片机初学者&#xff0c;解决交通信号系统动态调度算法实现与软硬件联合验证问题。压缩包共17个文件&#xff0c;86KB&#xff0c;…

2026/10/20 10:05:47 阅读更多 →
dart_scope_functions鸿蒙适配实践:Dart作用域函数在Flutter中的迁移全解析

dart_scope_functions鸿蒙适配实践:Dart作用域函数在Flutter中的迁移全解析

先提个问题&#xff1a;你写 Flutter 代码时&#xff0c;有没有经历过这种“工具人时刻”——定义一个对象&#xff0c;判空&#xff0c;取值&#xff0c;塞进构造器&#xff0c;再判空&#xff0c;再赋值……一个本该两行说完的逻辑&#xff0c;硬生生被样板代码撑出十行。想用…

2026/10/20 10:05:47 阅读更多 →
AIGC检测原理与论文写作重构:告别降AI工具,建立真实作者性

AIGC检测原理与论文写作重构:告别降AI工具,建立真实作者性

最近总有人拿着检测报告截图来问我&#xff1a;论文AIGC疑似比例飙到六成以上&#xff0c;学校通知延期&#xff0c;怎么办&#xff1f;说实话&#xff0c;看到这种局面我心里也替人着急&#xff0c;但更着急的是&#xff0c;很多人的第一反应是冲去找“去AI痕迹神器”&#xf…

2026/10/20 10:04:46 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

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

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

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

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

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

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 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/20 10:02:08 阅读更多 →
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/20 9:50: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/20 9:50:45 阅读更多 →