# 区分无音轨与静音，并验收 AAC 导出

确认必需音轨确实存在且经过 AAC 转码仍可解码。样本数与 RMS 数值检查不等于听音、清晰度或音质评审。

完整包只使用 Node 标准库。FFmpeg 需使用自己已有的安装，本包不分发二进制；不在 PATH 时将 FFMPEG_BIN 设为其绝对路径。

在本目录运行，并选择不存在的新输出目录，脚本拒绝覆盖。受内存管理的工作站可在 Node 命令前加本地串行执行包装器。不需要提供商密钥，夹具不会向设备外发请求。

```sh
node run-recipe.mjs --out ./my-run
```

实际记录：7项检查通过，包含1项预期拒绝，Node v24.18.0。ffmpeg version 6.0 Copyright (c) 2000-2023 the FFmpeg developers

准备

- 准备 Node.js 与支持 AAC 的 FFmpeg，必要时设置 FFMPEG_BIN；不下载外部音乐或语音。
- 辨认三类输入：原创 440Hz 正弦 WAV、数字静音 WAV，以及一秒无音轨视频。静音 WAV 有 16000 个零样本；无音轨文件根本没有可映射的音频流。
- 选用全新输出目录，并保留记录首跑的 initial-failed-run.json。修正版流复制不使用 -shortest，实际保留十帧视频。

## 01. 创建三种不同的音频状态

脚本直接用 Node Buffer 写出 WAV 头部和 PCM 样本，再分别把纯音与静音封装进原创视频。存在但样本为零的音轨，与文件里没有音轨，是两个不同条件。

## 02. 显式要求映射音轨

导出 aac-export.mp4 时明确映射 0:v:0、0:a:0，视频复制，音频以 AAC 64kbit/s 编码。无音轨夹具应让必需映射失败，不用可选映射掩盖缺失。

## 03. 解码样本并测量能量

将 AAC 解码为单声道 16kHz、16位有符号 PCM。本次返回 16384 样本，合成纯音 RMS 为 0.1391365。计数允许有限 AAC 填充，不把带填充的原始样本直接称为精确播放时长。

## 04. 分开验收编码、静音与视频

实际检查日志显示 Audio: aac；视频仍完整解码十帧，静音轨样本值全部为零。首跑曾因 -shortest 截早，失败回执已保留；修正脚本后七项检查全部通过。

验收

- 导出音轨能明确映射并解码为非空、偶数字节的16位 PCM。
- AAC 解码样本在 16000 至 17024 之间，本次为 16384。
- 原创正弦解码 RMS 在 0.1 至 0.2 之间，本次为 0.1391365。
- 实际 FFmpeg 日志明确标识音频编码为 AAC。
- 导出视频仍有十帧完整的 320×180 画面。
- 存在的静音轨解码为零值，无音轨明确映射失败；七项检查通过。

排错

声称是静音文件，却提示没有音轨。只检查必需的音轨映射；静音波形也必须有实际音频流，可改用配套 silent-track 夹具验证该条件。

解码样本数略多于一秒。固定输出 16kHz，对照有限 AAC 填充范围，不把所有填充样本都写成精确显示时长。

封装后复制的视频提前结束。在等时长夹具流复制中只移除 -shortest，再核对十帧完整性；初次失败回执保留了这个真实问题。

公开回执副本仅归一化本地 checkout 路径，publicPathNormalization 保存原始回执 SHA-256；未改动原件保留在非公开资产之外。真实回执位于 executed/。failure-receipt.json 记录预期负向案例，不表示套件断言失败。原创新夹具会重新生成到指定新目录，包内保留实跑输入输出便于复核。子进程使用参数数组、禁用 shell，设15秒超时与8MB输出上限。临时原始数据和本机 HTTP 服务在 finally 清理。

checksums.json 覆盖自身与 ZIP 以外的全部分发文件，避免循环自引用；ZIP 内包含同份清单。下载后可重算，但比较前提是预期清单可信。execution-receipt.json 记录实际脚本运行前后哈希，ZIP 也会由发布目录的资产清单绑定。

保留音轨日志与数值样本检查，编辑交付前另行听音并检查同步。本配方没有完成这两种人工评审。

2026-10-14 实际读取的来源

- FFmpeg command-line documentation: maps, codecs and error exit：https://ffmpeg.org/ffmpeg.html
- Node.js child process API: bounded argument-array execution：https://nodejs.org/api/child_process.html

initial-failed-run.json 保留初次真实失败；executed/ 为修正后的最终实跑。
