mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-08 10:56:15 -08:00
docs(audio): [PKG-AUDIO-01] freeze released synchronization contract
This commit is contained in:
1 parent
26b2983daf
commit
8c0a2feed3
12 files changed
+418
-5
No files matched your search
@@ -35,6 +35,10 @@ BASE-01 于 2026-09-10 固定核心与 chapter 的 npm 发布内容,数据在
|
||||
|
||||
## 公共 API 报告
|
||||
|
||||
Audio Track 的后续包基线由 PKG-AUDIO-01 独立冻结,见
|
||||
[契约和重跑](audio-track-contract.md) 及 [1.1.0 归档来源](audio-track-release.json)。
|
||||
它不改写本目录初始 BASE 快照,媒体/类型/设备通过范围由后续任务提供。
|
||||
|
||||
BASE-02 已在内置浏览器取得核心/chapter 的同步 API 和描述符快照,见 [覆盖与重跑](api-coverage.md) 和 [冻结报告](public-api.json)。事件/生命周期、DOM、类型、分发和其他包仍由各自任务补齐。
|
||||
|
||||
## 事件与生命周期报告
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
# Audio Track 1.1.0 兼容基线
|
||||
|
||||
PKG-AUDIO-01;源码起点 26b2983daf9edf9c798ce6a1638deeb3c36ba778。
|
||||
固定来源、逐文件 SHA-256、npm SRI、历史源码及比较结果见
|
||||
[audio-track-release.json](audio-track-release.json)。不覆盖 BASE-01 的历史快照。
|
||||
|
||||
## 来源与范围
|
||||
|
||||
npm 观察到 1.0.0、1.1.0,采集时 latest 为 1.1.0。本次实际归档范围为 **1.1.0**,
|
||||
不是所有历史版本。六文件归档完整性通过,manifest、README、公开声明与起点源码
|
||||
在 LF 规范化后相同,发布 ESM 与源码工厂经 AST 提取/esbuild 规范化后相同。
|
||||
这证明比较范围内的逻辑一致,不能代替真实媒体行为测试。
|
||||
|
||||
registry gitHead daf133b22630b4a0eecfa3336bbddab0e9119d96 对应本地包版本 1.0.2,
|
||||
不是该 npm 1.1.0 源码的充分证明;因此保留归档完整性和独立工厂比较。
|
||||
manifest 无 runtime/peer 依赖、无核心/浏览器/TS 最低版本承诺。
|
||||
旧核心对照使用现有冻结的 5.4.0;这只是具体检查点,不宣称最低支持版本为 5.4.0。
|
||||
|
||||
## 公开形状及调用
|
||||
|
||||
```js
|
||||
const attach = artplayerPluginAudioTrack({ url: '/audio.aac', offset: 0, sync: 0.3 })
|
||||
// ArtPlayer 注册时调用 attach(art)
|
||||
const result = art.plugins.artplayerPluginAudioTrack
|
||||
result.update({ url: '/next.aac', offset: 0.2 })
|
||||
const audio = result.audio // 同一 HTMLAudioElement,可直接操作
|
||||
```
|
||||
|
||||
工厂配置为必传对象;工厂同步返回安装函数,安装同步返回 `{ name, audio, update }`。
|
||||
name 固定为 `artplayerPluginAudioTrack`,update 同步返回 undefined。没有额外公开 destroy、
|
||||
事件、UI、CSS、静态版本或 SDK。插件创建独立 Audio 元素,不替换主视频,也不自动静音主视频;
|
||||
因此含原音轨的主视频可能与外部音频同时播放,这是现有行为,不静默改变音量策略。
|
||||
每次安装创建独立状态;配置在安装时解构,调用工厂后、安装前的对象修改会生效。
|
||||
|
||||
| 输入或行为 | 1.1.0 源码/发布实现事实 | 兼容与后续验证 |
|
||||
| --- | --- | --- |
|
||||
| url | 初始仅 truthy 时赋给 audio.src,preload 为 auto | URL 字符串交给浏览器解析,无 SDK |
|
||||
| offset | 默认 0,目标 audio 时间是 art.currentTime + offset | 正数音频领先、负数滞后;负目标/超时长在 02 实测 |
|
||||
| sync | 默认 0.3,仅绝对偏差严格大于阈值才 seek | 等于阈值不写;未校验负数、NaN、Infinity,不能凭猜测新增拒绝规则 |
|
||||
| update | truthy 且不同 URL 才赋 src;playing 时调用 play;之后才更新 offset/sync | 同 URL 不重载,空 URL 不清源;JS 允许只传 offset/sync,且不立即同步 |
|
||||
| audio | 公开真实元素,同一引用贯穿安装/更新/销毁 | 不换为不可访问封装,不用新元素实现每次切源 |
|
||||
| 音量/倍率 | 初始 volume/muted 来自 art;倍率 video?.playbackRate 或 1 | 后续 video:volumechange/ratechange 同步,无自有主视频 mute |
|
||||
| play 拒绝 | 三个调用点各自 catch 并 console.warn 原错误 | 没有返回给调用者的 play Promise、没有自定义错误事件 |
|
||||
|
||||
| ArtPlayer 事件 | 外部音频行为 |
|
||||
| --- | --- |
|
||||
| play | 有 URL 才同步目标时间,随后 audio.play |
|
||||
| pause | audio.pause |
|
||||
| seek | 有 video/URL 才同步时间 |
|
||||
| video:timeupdate | art.playing 时同步时间 |
|
||||
| video:ratechange | 读 art.video.playbackRate |
|
||||
| video:volumechange | 同步 art.volume 和 art.muted |
|
||||
| video:waiting | audio.pause |
|
||||
| video:playing | 有 URL 且 art.playing 才 audio.play,不主动 sync |
|
||||
| destroy | pause、src = ''、load,按此顺序 |
|
||||
|
||||
没有定时器或自建请求;浏览器拥有媒体加载。当前九个 emitter 回调没有插件自身解绑,
|
||||
依赖核心销毁清空事件。没有 closed 状态,外部保留的 update 可在销毁后写入新 src。
|
||||
这些是源码观察,02 用受控复现及真实媒体验证;不能只凭观察称内存泄漏已复现。
|
||||
|
||||
## 类型和分发
|
||||
|
||||
公开默认导出为 `(option: Option) => (art: Artplayer) => Result`,Option.url 必需、
|
||||
offset/sync 可选;Result.audio 为 HTMLAudioElement,update(option: Option): void。
|
||||
Option/Result 未具名导出,消费者可用 Parameters/ReturnType 提取;04 保留这些旧合法调用。
|
||||
JS 的 update({ offset: 1 }) 与声明不一致,允许拓宽 update 为部分配置,但不弱化字段类型。
|
||||
docs 编辑器声明还同时包含 export default/export =,由 04 做语义验证及生成修正,
|
||||
本步不声称编辑器或 TS 消费已经通过。
|
||||
|
||||
root exports 使用 types + import(mjs)/require(js),legacy import/require 都指向 legacy.js;
|
||||
main/module/types/legacy 的完整值冻结在 manifest。UMD 全局名与默认导出一致。
|
||||
保留 `/legacy`、旧文件路径、同步注册和未加载 DOM 时的导入边界;实际各格式消费由 02/04/06 验证。
|
||||
当前版本保持 1.1.0,REL-09 按用户要求准备 2.0.0,未获 npm 发布授权。
|
||||
|
||||
## 文档、样本与差异归属
|
||||
|
||||
README 仅说明插件名、Demo 和 MIT;其 `example=audio-track` 与真实
|
||||
`docs/assets/example/audio.track.js` 不一致。common.js 直接拼接名称,无连字符转换。
|
||||
实际示例使用本地 sprite-fight.mp4 + sprite-fight.aac,二者存在;没有演示 update、
|
||||
偏移边界或销毁。06 应修链接并以正式 8082 demo 验证,不能拿静态文件存在作为播放通过。
|
||||
|
||||
| 风险 | 当前证据等级 | 负责任务 |
|
||||
| --- | --- | --- |
|
||||
| AUDIO-LIFE-01:销毁后 update 可写 src,监听/异步播放归属缺少终止守卫 | 源码事实,未作浏览器泄漏结论 | 02/03/05 |
|
||||
| AUDIO-SYNC-01:偏移边界及切源/缓冲恢复缺少媒体时序证据 | 待取证,不预设所有当前行为是缺陷 | 02/03/05 |
|
||||
| AUDIO-TYPE-01:update 部分配置和编辑器声明不一致 | 源码/声明事实 | 04 |
|
||||
| AUDIO-DEMO-01:README 示例名不匹配、维护说明缺失 | 源码/文件事实 | 06 |
|
||||
|
||||
## 重跑
|
||||
|
||||
`node refactor/scripts/audio-contract.mjs`:重验固定归档、六文件、manifest、历史 Git 内容与工厂。
|
||||
首次仅从固定 npm URL 下载至忽略缓存;不安装、不执行归档脚本、不覆盖基线。
|
||||
`node --test refactor/scripts/audio-contract.test.mjs`:包含该验证及规范化工具的有意行为变化检查。
|
||||
本步不改生产代码/声明/构建产物;所有媒体、类型和设备验收仍是后续任务。
|
||||
@@ -0,0 +1,113 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"task": "PKG-AUDIO-01",
|
||||
"capturedAt": "2026-09-11T17:44:31.880Z",
|
||||
"sourceCommit": "26b2983daf9edf9c798ce6a1638deeb3c36ba778",
|
||||
"registryObservation": {
|
||||
"registryUrl": "https://registry.npmjs.org/artplayer-plugin-audio-track",
|
||||
"distTags": {
|
||||
"latest": "1.1.0"
|
||||
},
|
||||
"versions": [
|
||||
"1.0.0",
|
||||
"1.1.0"
|
||||
],
|
||||
"publishedAt": "2026-03-12T14:21:57.424Z",
|
||||
"note": "Observed metadata; not a promise of future latest version or support for every older release."
|
||||
},
|
||||
"release": {
|
||||
"name": "artplayer-plugin-audio-track",
|
||||
"version": "1.1.0",
|
||||
"metadataUrl": "https://registry.npmjs.org/artplayer-plugin-audio-track/1.1.0",
|
||||
"tarball": "https://registry.npmjs.org/artplayer-plugin-audio-track/-/artplayer-plugin-audio-track-1.1.0.tgz",
|
||||
"integrity": "sha512-pvvHvTSqC2+sBelwYyjAv2CVmaQgG9KpX+i96t/e8oyZRX/JuepC9iSVIp7GzB3AtliFzhVamksT+8lXvD3RCg==",
|
||||
"sha256": "7e84f6a2f4bfada428a77ef04b749bf3db53e0149fa1afe7bf5749d925e801ff",
|
||||
"archiveBytes": 2205,
|
||||
"registryGitHead": "daf133b22630b4a0eecfa3336bbddab0e9119d96",
|
||||
"files": {
|
||||
"package/README.md": "9a03352433ae90cb9d3198e17571c9bb598334b84a77a3a1df2c4b000ce8347d",
|
||||
"package/dist/artplayer-plugin-audio-track.js": "473f39f1d750f0722cca7e857c12c3c978ebe3c3b2352e325f1248318e508683",
|
||||
"package/dist/artplayer-plugin-audio-track.legacy.js": "d8dc74bce76112d7430c98e3165605e32fde5d3c603be4b496eac58f574576cb",
|
||||
"package/dist/artplayer-plugin-audio-track.mjs": "4ac599bc5a1a6ecb0cb1942d4269528bfb2cd9d047f988de61fe671a77ad14cd",
|
||||
"package/package.json": "c466ae55c40e8f6bdd97bec20fcf916c8c4f44eef3e47694638be005eb445df7",
|
||||
"package/types/artplayer-plugin-audio-track.d.ts": "27bc0dfedacb7e0188cb668ac8708874a86b00d489f1636037c2465d3344437e"
|
||||
},
|
||||
"manifest": {
|
||||
"name": "artplayer-plugin-audio-track",
|
||||
"version": "1.1.0",
|
||||
"description": "audio-track plugin for ArtPlayer",
|
||||
"author": "Harvey Zhao <laozhaochaguan@gmail.com>",
|
||||
"license": "MIT",
|
||||
"homepage": "https://artplayer.org",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/zhw2590582/ArtPlayer.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/zhw2590582/ArtPlayer/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"html5",
|
||||
"video",
|
||||
"player"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./types/artplayer-plugin-audio-track.d.ts",
|
||||
"import": "./dist/artplayer-plugin-audio-track.mjs",
|
||||
"require": "./dist/artplayer-plugin-audio-track.js"
|
||||
},
|
||||
"./legacy": {
|
||||
"types": "./types/artplayer-plugin-audio-track.d.ts",
|
||||
"import": "./dist/artplayer-plugin-audio-track.legacy.js",
|
||||
"require": "./dist/artplayer-plugin-audio-track.legacy.js"
|
||||
}
|
||||
},
|
||||
"main": "dist/artplayer-plugin-audio-track.js",
|
||||
"module": "./dist/artplayer-plugin-audio-track.mjs",
|
||||
"types": "types/artplayer-plugin-audio-track.d.ts",
|
||||
"legacy": "dist/artplayer-plugin-audio-track.legacy.js",
|
||||
"browserslist": "last 1 Chrome version"
|
||||
}
|
||||
},
|
||||
"source": {
|
||||
"packages/artplayer-plugin-audio-track/package.json": "c466ae55c40e8f6bdd97bec20fcf916c8c4f44eef3e47694638be005eb445df7",
|
||||
"packages/artplayer-plugin-audio-track/README.md": "9a03352433ae90cb9d3198e17571c9bb598334b84a77a3a1df2c4b000ce8347d",
|
||||
"packages/artplayer-plugin-audio-track/types/artplayer-plugin-audio-track.d.ts": "27bc0dfedacb7e0188cb668ac8708874a86b00d489f1636037c2465d3344437e",
|
||||
"packages/artplayer-plugin-audio-track/src/index.js": "470237ebd62e8fb8537e809db03fd02871844d41c03d422a22956bd2756ac28e",
|
||||
"docs/assets/example/audio.track.js": "9ed26b2ee006e1a430db68b2a1b308c4801dd3a4cc87c74e8a8f5ccf3456ac8d",
|
||||
"docs/assets/ts/artplayer-plugin-audio-track.d.ts": "e0815cb05be2366957df77f0de81a46f863c4d8e0a0697fac1258c4f48da85ea"
|
||||
},
|
||||
"comparisons": [
|
||||
{
|
||||
"file": "package.json",
|
||||
"publishedLF": "c466ae55c40e8f6bdd97bec20fcf916c8c4f44eef3e47694638be005eb445df7",
|
||||
"workspaceLF": "c466ae55c40e8f6bdd97bec20fcf916c8c4f44eef3e47694638be005eb445df7",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"file": "README.md",
|
||||
"publishedLF": "9a03352433ae90cb9d3198e17571c9bb598334b84a77a3a1df2c4b000ce8347d",
|
||||
"workspaceLF": "9a03352433ae90cb9d3198e17571c9bb598334b84a77a3a1df2c4b000ce8347d",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"file": "types/artplayer-plugin-audio-track.d.ts",
|
||||
"publishedLF": "27bc0dfedacb7e0188cb668ac8708874a86b00d489f1636037c2465d3344437e",
|
||||
"workspaceLF": "27bc0dfedacb7e0188cb668ac8708874a86b00d489f1636037c2465d3344437e",
|
||||
"equal": true
|
||||
}
|
||||
],
|
||||
"functionComparison": {
|
||||
"sha256": "6a758f0a88567283ae44bc9d1fa0906161f6ce9d384803637d7124c2dc1b87da",
|
||||
"typescript": "5.9.3",
|
||||
"esbuild": "0.27.7",
|
||||
"scope": [
|
||||
"artplayerPluginAudioTrack"
|
||||
],
|
||||
"excludes": [
|
||||
"bundler wrappers"
|
||||
],
|
||||
"note": "Historical source at sourceCommit; normalized factory comparison is not runtime acceptance."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
# PKG-AUDIO-01:Audio Track 发布契约
|
||||
|
||||
状态:本步契约验收完成。起点为 HLS 诊断检查点 26b2983d;后者仍未完成,不构成依赖阻塞。
|
||||
|
||||
范围:固定 audio-track 1.1.0 的 npm 归档、声明、源码和 demo 差异,记录同步、
|
||||
暴露 audio、update 和事件契约。本步不修改生产行为。后续 02 建行为测试,03 整理
|
||||
同步与资源,04 迁移严格 TS 和兼容声明,05/06 完成组合、设备与分发验收。
|
||||
|
||||
## 来源和结果
|
||||
|
||||
真实 npm 1.1.0 归档 2205 字节、六文件,SHA-512 SRI、SHA-256、成员哈希及入口存在性通过。
|
||||
manifest、README、声明与历史源码 LF 内容一致,完整工厂 AST 规范化比较一致。
|
||||
registry gitHead 对应包版本 1.0.2,故没有把该字段当成 1.1.0 源码证明。
|
||||
来源和范围见 [冻结输入](../baselines/audio-track-release.json),
|
||||
详细旧行为与映射见 [契约](../baselines/audio-track-contract.md)。
|
||||
|
||||
识别出 AUDIO-LIFE-01/SYNC-01/TYPE-01/DEMO-01,分别交由 02~06;都是源码事实或待取证,
|
||||
没有声称已复现真实音频泄漏或已修复。包括公开 audio、严格同步阈值、无自动主视频静音、
|
||||
update 部分配置、错误警告、源更新及销毁顺序,旧合法接口均维持原状。
|
||||
修正文档环境矩阵对本包的能力描述:它同步独立外部 Audio,不负责 HLS 轨道拓扑选择。
|
||||
|
||||
## 验证与范围
|
||||
|
||||
- `node refactor/scripts/audio-contract.mjs`:六文件归档及历史源码检查通过。
|
||||
- `node --test refactor/scripts/audio-contract.test.mjs`:两项通过;额外验证格式变化不误判,
|
||||
真实函数行为变化不能获得相同规范化指纹,缺失工厂明确失败。
|
||||
- 定向 ESLint:首次报告对象换行三处,修正格式后复验通过。
|
||||
- 计划与风险表生成/校验、Git diff 空白检查通过:216 任务、126 风险,没有豁免未解决项。
|
||||
|
||||
新增一个只读契约检查入口及其 Node 测试,复用已有 esbuild/TypeScript/tar 依赖,
|
||||
无新安装依赖或 lock 变更。首次会下载已冻结归档至忽略缓存;不会安装/执行归档代码,
|
||||
不会更新持久基线。`yarn test:baseline` 的既有文件模式自动纳入这两项。
|
||||
生产源码、声明、demo、构建产物完全未改,因此本步不重建、不声称浏览器或类型消费者通过。
|
||||
|
||||
## 提交、回退与接续
|
||||
|
||||
独立完成提交主题:`docs(audio): [PKG-AUDIO-01] freeze released synchronization contract`。
|
||||
仅回退本任务新增基线/检查及任务文档即可恢复先前状态;无生产行为回退需求。
|
||||
基线本身长期不可覆盖,后续修改另建证据。下一步 PKG-AUDIO-02 建立可重跑的旧版行为、
|
||||
边界与错误测试,03/04 按证据拆分、修复、迁移 TS;包内实际模块地图随实现交付。
|
||||
剩余所有包、设备、CI/CD、major 及三轮复盘继续保留。未 push/tag/publish/merge。
|
||||
@@ -36,7 +36,7 @@ Node10 是 TS 模块解析模式名,不代表支持 Node.js 10。现代 es2020
|
||||
| artplayer-plugin-ads / 2.1.0 | 广告图片/视频、本片恢复、跳过、错误/销毁;本地短广告和主片 | 发布范围及所有浏览器场景待;无需借 IMA 结果代替自有广告逻辑 | PKG-ADS-01/02/05/06 |
|
||||
| artplayer-plugin-ambilight / 1.1.0 | Canvas 采样、CORS、resize、后台/销毁;同源及受控跨源 MP4 | 待真实画布和资源测量 | PKG-AMBILIGHT-01/02/05/06 |
|
||||
| artplayer-plugin-asr / 2.1.0 | PCM 音频输出/暂停/销毁;AudioContext + 调用方服务 | 待音频环境与调用方 WebSocket 验证;示例服务版本未知,不在 PR 调线上服务 | PKG-ASR-01/02/05/06、EX-03 |
|
||||
| artplayer-plugin-audio-track / 1.1.0 | 音轨切换与同步;固定双音轨/单音轨/无音轨样本 | 待轨道来源和支持窗口确认、Safari/桌面实测 | PKG-AUDIO-01/02/05/06 |
|
||||
| artplayer-plugin-audio-track / 1.1.0 | 独立外部 Audio 与主视频时钟同步;本地 MP4+AAC,偏移/切源/缓冲/失败样本 | 1.1.0 发布及调用契约见 [包基线](baselines/audio-track-contract.md);旧核心 5.4.0 为具体对照点,桌面/Safari 实测待完成 | PKG-AUDIO-01/02/05/06 |
|
||||
| artplayer-plugin-auto-thumbnail / 1.1.0 | 帧提取/跳转、CORS、回收;本地 MP4+跨源失败 | 待 Canvas/seek/移动内存行为 | PKG-AUTO-THUMB-01/02/05/06 |
|
||||
| artplayer-plugin-chapter / 1.1.0 | 区间、边界/重叠、hover/update、进度条组合;MP4+固定章节 | 发布 1.1.0 已冻结;最小注册/两段 DOM 已验,边界和新旧组合待 | PKG-CHAPTER-01/02/04/05/06、PILOT-01 |
|
||||
| artplayer-plugin-chromecast / 1.1.0 | Cast SDK、发送/接收会话、取消/断线、本机恢复;接收端可访问媒体 | SDK 动态地址已记录;真实接收设备和 sender 版本未知、待运行 | PKG-CAST-01/02/05/06 |
|
||||
|
||||
+3
-2
@@ -4,7 +4,7 @@
|
||||
|
||||
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 216 项,范围 22 个包及工作区/示例。
|
||||
|
||||
状态:todo 150 / doing 1 / blocked 0 / done 65 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
|
||||
状态:todo 149 / doing 1 / blocked 0 / done 66 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
|
||||
|
||||
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
|
||||
| ID | 范围 / 步骤 | 前置依赖 | 交付物 | 验收条件 | 风险 | 状态 |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| PKG-AUDIO-01 | artplayer-plugin-audio-track<br>核对包契约与历史用法 | BASE-05 | url/offset/sync、audio 实例暴露、update 与音量语义 | 源码/声明/README/demo/发布包差异已登记;公开形状和版本范围冻结 | H | todo |
|
||||
| PKG-AUDIO-01 | artplayer-plugin-audio-track<br>核对包契约与历史用法 | BASE-05 | url/offset/sync、audio 实例暴露、update 与音量语义 | 源码/声明/README/demo/发布包差异已登记;公开形状和版本范围冻结 | H | done |
|
||||
| PKG-AUDIO-02 | artplayer-plugin-audio-track<br>建立特有行为与错误测试 | PKG-AUDIO-01, ENG-03, ENG-05 | 偏移、倍率、seek、waiting/playing、加载错误和 autoplay 拒绝 | 旧版本行为可重跑,成功/失败/切源/销毁有必要断言 | H | todo |
|
||||
| PKG-AUDIO-03 | artplayer-plugin-audio-track<br>整理内部职责与资源 | PKG-AUDIO-02, CORE-10 | 外部 audio 的同步策略、监听与源更新生命周期 | 结构变化和缺陷修复分开记录;原 API/事件/资源生命周期通过 | H | todo |
|
||||
| PKG-AUDIO-04 | artplayer-plugin-audio-track<br>迁移自有源码和公开类型 | PKG-AUDIO-03, ENG-04, ENG-06, CORE-07 | Option/Result/audio、update 输入和事件类型 | 严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容 | H | todo |
|
||||
@@ -466,6 +466,7 @@
|
||||
- PKG-CHAPTER-02: [记录](changes/2026-09-10-PKG-CHAPTER-02-tests.md) [记录](baselines/chapter-validation.json)
|
||||
- PKG-CHAPTER-03: [记录](changes/2026-09-10-PKG-CHAPTER-03-typescript-modules.md) [记录](baselines/chapter-migration-validation.json)
|
||||
- PKG-CHAPTER-04: [记录](changes/2026-09-10-PKG-CHAPTER-04-public-types.md) [记录](baselines/chapter-types-validation.json)
|
||||
- PKG-AUDIO-01: [记录](changes/2026-09-12-PKG-AUDIO-01-contract.md) [记录](baselines/audio-track-contract.md) [记录](baselines/audio-track-release.json)
|
||||
- PKG-HLS-01: [记录](baselines/hls-control-contract.md) [记录](baselines/hls-control-release.json) [记录](changes/2026-09-11-PKG-HLS-01-contract.md)
|
||||
- PKG-HLS-02: [记录](hls-validation.md) [记录](baselines/hls-sdk.json) [记录](baselines/hls-validation.json) [记录](changes/2026-09-11-PKG-HLS-02-tests.md)
|
||||
- PKG-HLS-03: [记录](changes/2026-09-12-PKG-HLS-03-modules.md) [记录](baselines/hls-modules-validation.json) [记录](hls-validation.md)
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
# 进度与证据
|
||||
|
||||
## 最新完成:PKG-AUDIO-01 外部音轨发布契约
|
||||
|
||||
冻结 npm audio-track 1.1.0 六文件及完整性,manifest/README/声明和起点一致,
|
||||
发布工厂与源码规范化比较通过。两项可重跑检查通过;音频同步、update 部分配置、
|
||||
销毁后引用和示例链接差异已分别登记,实际行为与媒体测试由 02 接续。
|
||||
源码/声明/产物未改,本步不代表音频浏览器或类型验收通过。
|
||||
|
||||
HLS 诊断检查点已提交 26b2983d,HLS-SDK-01 仍 doing,两项 Firefox 风险仍 open。
|
||||
当前 216 项、66 done、1 doing、149 todo。Audio-01 按任务独立本地提交后核实,
|
||||
继续 Audio-02,避免未归因的 HLS 平台问题阻塞无依赖的其他包。
|
||||
详见 [契约](baselines/audio-track-contract.md) 和 [记录](changes/2026-09-12-PKG-AUDIO-01-contract.md)。
|
||||
|
||||
## HLS 诊断 checkpoint:已缩小范围,尚未关闭风险
|
||||
|
||||
独立诊断 runner 已加入直接 Hls、发布核心、候选核心对照,以及 HTTP/route、worker/观察器、
|
||||
|
||||
@@ -126,3 +126,7 @@
|
||||
| HLS-ENV-01 | open / 已复现 | Windows WebKit 缺失 MSE,HLS 播放矩阵尚缺 Safari 证据 | PKG-HLS-05, REL-09, REVIEW-02 |
|
||||
| HLS-CRASH-01 | open / 已复现 | Firefox Hls 1.5.17 worker 销毁可在原生 video 与候选核心复现崩溃 | PKG-HLS-SDK-01, PKG-HLS-05, REVIEW-02 |
|
||||
| HLS-PLAYBACK-01 | open / 已复现 | Firefox 旧核心与 Hls 1.7.2 切组后视频档位未完成切换 | PKG-HLS-SDK-01, PKG-HLS-05, REVIEW-02 |
|
||||
| AUDIO-LIFE-01 | open / 源码/产物事实 | Audio Track 销毁后 update 与媒体/订阅缺少终止守卫 | PKG-AUDIO-02, PKG-AUDIO-03, PKG-AUDIO-05 |
|
||||
| AUDIO-SYNC-01 | open / 待取证 | Audio Track 偏移边界和切源/缓冲恢复尚缺真实时序证据 | PKG-AUDIO-02, PKG-AUDIO-03, PKG-AUDIO-05 |
|
||||
| AUDIO-TYPE-01 | open / 源码/产物事实 | Audio Track update 部分配置与公开/编辑器声明不一致 | PKG-AUDIO-04 |
|
||||
| AUDIO-DEMO-01 | open / 源码/产物事实 | Audio Track README 示例链接名称不匹配且缺维护说明 | PKG-AUDIO-06 |
|
||||
@@ -2643,6 +2643,70 @@
|
||||
],
|
||||
"compatibleResolution": "区分 SDK、测试媒体/时序和宿主问题,保留真实档位/解码断言及 trace;不扩大等待或只验证菜单。",
|
||||
"closureCriteria": "直接 Hls 与新旧核心对照定位切换停滞,验证处置和正常/连续组切换,不能以重复通过关闭。"
|
||||
},
|
||||
{
|
||||
"id": "AUDIO-LIFE-01",
|
||||
"title": "Audio Track 销毁后 update 与媒体/订阅缺少终止守卫",
|
||||
"confirmation": "source-observed",
|
||||
"status": "open",
|
||||
"owners": [
|
||||
"PKG-AUDIO-02",
|
||||
"PKG-AUDIO-03",
|
||||
"PKG-AUDIO-05"
|
||||
],
|
||||
"evidence": [
|
||||
"refactor/baselines/audio-track-contract.md",
|
||||
"refactor/baselines/audio-track-release.json"
|
||||
],
|
||||
"compatibleResolution": "保留公开 audio 和同步 update,封闭销毁后的资源写入并管理插件订阅,验证待决播放拒绝。",
|
||||
"closureCriteria": "受控复现和新旧核心真实媒体切源/销毁验证通过,不以源码观察代替泄漏证据。"
|
||||
},
|
||||
{
|
||||
"id": "AUDIO-SYNC-01",
|
||||
"title": "Audio Track 偏移边界和切源/缓冲恢复尚缺真实时序证据",
|
||||
"confirmation": "unverified",
|
||||
"status": "open",
|
||||
"owners": [
|
||||
"PKG-AUDIO-02",
|
||||
"PKG-AUDIO-03",
|
||||
"PKG-AUDIO-05"
|
||||
],
|
||||
"evidence": [
|
||||
"refactor/baselines/audio-track-contract.md",
|
||||
"refactor/baselines/audio-track-release.json"
|
||||
],
|
||||
"compatibleResolution": "固定严格阈值、偏移正负、倍率和音量语义;实测负目标/超时长及连续切源,按证据修复。",
|
||||
"closureCriteria": "正常/边界/失败/缓冲恢复有媒体与受控断言,实际支持环境缺口明确处理。"
|
||||
},
|
||||
{
|
||||
"id": "AUDIO-TYPE-01",
|
||||
"title": "Audio Track update 部分配置与公开/编辑器声明不一致",
|
||||
"confirmation": "source-observed",
|
||||
"status": "open",
|
||||
"owners": [
|
||||
"PKG-AUDIO-04"
|
||||
],
|
||||
"evidence": [
|
||||
"refactor/baselines/audio-track-contract.md",
|
||||
"refactor/baselines/audio-track-release.json"
|
||||
],
|
||||
"compatibleResolution": "拓宽已有 JS 合法部分 update,保留 url/offset/sync 字段精度和 Parameters/ReturnType 提取,生成语义正确编辑器声明。",
|
||||
"closureCriteria": "当前与旧编译器的正反例、CJS/ESM/legacy 入口及实际编辑器通过。"
|
||||
},
|
||||
{
|
||||
"id": "AUDIO-DEMO-01",
|
||||
"title": "Audio Track README 示例链接名称不匹配且缺维护说明",
|
||||
"confirmation": "source-observed",
|
||||
"status": "open",
|
||||
"owners": [
|
||||
"PKG-AUDIO-06"
|
||||
],
|
||||
"evidence": [
|
||||
"refactor/baselines/audio-track-contract.md",
|
||||
"refactor/baselines/audio-track-release.json"
|
||||
],
|
||||
"compatibleResolution": "修正 audio.track 示例路径,补真实模块地图及 update/生命周期说明。",
|
||||
"closureCriteria": "README、示例、公开声明一致,8082 正式 demo 和包分发验证通过。"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { execFileSync } from 'node:child_process'
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { transform } from 'esbuild'
|
||||
import ts from 'typescript'
|
||||
import { archiveFiles, ensureArchive, hash, readMember, refactorDir } from './releases.mjs'
|
||||
|
||||
const root = path.resolve(refactorDir, '..')
|
||||
export const normalizeLF = value => value.toString().replace(/\r\n/g, '\n')
|
||||
|
||||
export async function audioFunctionHash(code) {
|
||||
const source = ts.createSourceFile('audio.js', code, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS)
|
||||
assert.equal(source.parseDiagnostics.length, 0, 'Invalid audio source')
|
||||
const functions = source.statements.filter(item => ts.isFunctionDeclaration(item) && item.name?.text === 'artplayerPluginAudioTrack')
|
||||
assert.equal(functions.length, 1, 'Expected exactly one audio factory')
|
||||
const normalized = await transform(functions[0].getText(source).replace(/^export\s+default\s+/, ''), {
|
||||
loader: 'js',
|
||||
target: 'es2020',
|
||||
minifySyntax: true,
|
||||
minifyWhitespace: true,
|
||||
})
|
||||
return hash(normalized.code)
|
||||
}
|
||||
|
||||
export async function verifyAudioContract() {
|
||||
const baseline = JSON.parse(fs.readFileSync(path.join(refactorDir, 'baselines/audio-track-release.json'), 'utf8'))
|
||||
const { release } = baseline
|
||||
const archive = await ensureArchive(release)
|
||||
assert.deepEqual(archiveFiles(archive), Object.keys(release.files).sort())
|
||||
for (const [member, expected] of Object.entries(release.files))
|
||||
assert.equal(hash(readMember(archive, member)), expected, `Changed release member: ${member}`)
|
||||
const manifest = JSON.parse(readMember(archive, 'package/package.json'))
|
||||
assert.deepEqual(manifest, release.manifest)
|
||||
for (const entry of [manifest.main, manifest.module, manifest.types, manifest.legacy])
|
||||
assert(Object.hasOwn(release.files, `package/${entry.replace(/^\.\//, '')}`))
|
||||
assert(/^[a-f\d]{40}$/.test(baseline.sourceCommit))
|
||||
const historical = new Map()
|
||||
for (const [file, expected] of Object.entries(baseline.source)) {
|
||||
const content = normalizeLF(execFileSync('git', ['show', `${baseline.sourceCommit}:${file}`], { cwd: root }))
|
||||
assert.equal(hash(content), expected, `Changed historical source: ${file}`)
|
||||
historical.set(file, content)
|
||||
}
|
||||
for (const comparison of baseline.comparisons) {
|
||||
const published = hash(normalizeLF(readMember(archive, `package/${comparison.file}`)))
|
||||
const source = hash(historical.get(`packages/${release.name}/${comparison.file}`))
|
||||
assert.equal(published, comparison.publishedLF)
|
||||
assert.equal(source, comparison.workspaceLF)
|
||||
assert.equal(published === source, comparison.equal)
|
||||
}
|
||||
const sourceHash = await audioFunctionHash(historical.get(`packages/${release.name}/src/index.js`))
|
||||
const publishedHash = await audioFunctionHash(readMember(archive, `package/${manifest.module.replace(/^\.\//, '')}`).toString())
|
||||
assert.equal(sourceHash, baseline.functionComparison.sha256)
|
||||
assert.equal(publishedHash, sourceHash)
|
||||
console.log(`Verified ${release.name}@${release.version}: archive, ${Object.keys(release.files).length} members, historical sources and normalized factory`)
|
||||
return { baseline, archive }
|
||||
}
|
||||
|
||||
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url))
|
||||
await verifyAudioContract()
|
||||
@@ -0,0 +1,14 @@
|
||||
import assert from 'node:assert/strict'
|
||||
// eslint-disable-next-line test/no-import-node-test -- Frozen baseline checks run in Node.
|
||||
import test from 'node:test'
|
||||
import { audioFunctionHash, verifyAudioContract } from './audio-contract.mjs'
|
||||
|
||||
test('Audio Track 1.1.0 archive and historical contract remain immutable', verifyAudioContract)
|
||||
|
||||
test('audio factory comparison ignores formatting but detects changed behavior', async () => {
|
||||
const original = 'export default function artplayerPluginAudioTrack(option) { return option.offset + 1 }'
|
||||
const formatted = 'function artplayerPluginAudioTrack(option) {\n return option.offset + 1;\n }'
|
||||
assert.equal(await audioFunctionHash(original), await audioFunctionHash(formatted))
|
||||
assert.notEqual(await audioFunctionHash(original), await audioFunctionHash(original.replace('+ 1', '+ 2')))
|
||||
await assert.rejects(audioFunctionHash('function unrelated() {}'), /exactly one audio factory/)
|
||||
})
|
||||
+6
-2
@@ -1468,11 +1468,15 @@
|
||||
"dependsOn": [
|
||||
"BASE-05"
|
||||
],
|
||||
"status": "todo",
|
||||
"status": "done",
|
||||
"risk": "H",
|
||||
"deliverable": "url/offset/sync、audio 实例暴露、update 与音量语义",
|
||||
"acceptance": "源码/声明/README/demo/发布包差异已登记;公开形状和版本范围冻结",
|
||||
"evidence": []
|
||||
"evidence": [
|
||||
"changes/2026-09-12-PKG-AUDIO-01-contract.md",
|
||||
"baselines/audio-track-contract.md",
|
||||
"baselines/audio-track-release.json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "PKG-AUDIO-02",
|
||||
|
||||
Reference in new issue
Block a user