# @conetic/prestoplay-analytics 中文文档

规范地址：https://npmcn.com/package/%40conetic/prestoplay-analytics/

版本：0\.2\.1
npm 元数据更新时间：2026-10-02T07:43:42.764Z
中文译文更新时间：2026-11-10T15:12:55.356Z
软件包许可：SEE LICENSE IN LICENSE

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40conetic/prestoplay-analytics
原文对照：https://npmcn.com/package/%40conetic/prestoplay-analytics/?lang=original

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：260 kB，11 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=18
- 运行依赖：0 个
- peer 依赖：@castlabs/prestoplay ^6\.0\.0
- 首次发布：2026-10-02T07:43:42.285Z
- 最新版本发布：2026-10-02T07:43:42.626Z
- 近 30 天下载量：3772（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：1（近 12 个月 1 个）

## 中文简介

PRESToplay 插件, 将 Voyager IFE 分析事件报告到分析端点

## 安装

```sh
npm install @conetic/prestoplay-analytics
```

也可以使用：`pnpm add @conetic/prestoplay-analytics`、`yarn add @conetic/prestoplay-analytics`、`bun add @conetic/prestoplay-analytics`

## README

# @conetic/prestoplay-analysis(英语:

PRESTOPLE 插件, 报告在 变速器分析事件规格(v0.3)——0.2.0有效载荷 所列修正案 [变动情况](https://npmcn.com/package/%40conetic/prestoplay-analytics/CHANGELOG.md) 作为JSON Posts 到一个 分析终点,每个请求或分批一个事件.

插件拥有玩家所能告诉的一切 — 回放状态、 寻求、 跟踪 变化、错误、时间——加 `event_id`, (中文(简体) ), `sequence`, (中文(简体) ), `playback_id`时钟 校正 设备检测 主机应用程序提供航班, 语句和目录背景,玩家无法知道.

* * *

> **第一次融合这个? 开始 [总部](https://npmcn.com/package/%40conetic/prestoplay-analytics/INSTALL.md)。 。 。 .**

## 安装

```bash
npm install @conetic/prestoplay-analytics
```

向公众公布 npm 登记册——没有登记册配置或标志 需要帮助. [总部](https://npmcn.com/package/%40conetic/prestoplay-analytics/INSTALL.md) 有完整的设置.

`@castlabs/prestoplay` 是同级依赖(v6). 插件没有运行时间 其自依缘.

* * *

## 快开始

```ts
import { clpp } from '@castlabs/prestoplay'
import '@castlabs/prestoplay/cl.mse'
import '@castlabs/prestoplay/cl.dash'
import { registerVoyagerAnalytics } from '@conetic/prestoplay-analytics'

// 1. Register BEFORE any player is constructed.
registerVoyagerAnalytics(clpp)

// 2. Static context goes in the player constructor config.
const player = new clpp.Player('#video', {
  license: CLPP_LICENSE,
  voyagerAnalytics: {
    endpoint: 'https://<analytics-host>/api/v1/analytics/events',
    serverTime: bootstrap.serverTime,
    batchSize: 5,                      // optional; 1 (one POST per event) by default
    flight: {
      tail_number: 'N123AZ',
      flight_number: 'XY0189',
      departure_iata: 'GIG',
      arrival_iata: 'OPO',
      takeoff_time: '2026-01-08T16:13:00.000Z',
    },
    session: {
      session_id: bootstrap.sessionId,
      device_id: bootstrap.deviceId,   // onboard router ID, host-supplied
    },
    system: { oem: 'ACME', app_version: '2.4.1' },
  },
})

// 3. Per-playback context goes in the load() config.
await player.load({
  source: { url: asset.manifestUrl, type: clpp.Type.DASH },
  startTime: resumePositionSeconds,
  voyagerAnalytics: {
    gui_path: 'home/categories/kids',
    media_id: '9090929',
    media: {
      media_title: 'Bart Gets Famous',
      media_type: 'SERIES_EPISODE',
      series_title: 'The Simpsons',
      season_number: 5,
      episode_number: 12,
      distributor: 'Warner Bros Discovery',
      category: 'Kids',
      genres: ['Comedy', 'Animation'],
      original_language: 'en',
      release_year: 2023,
      duration_ms: 1420000,
    },
  },
})
```

这就是整体整合。 七事从之.

### 没有捆绑

```html
<script src="node_modules/@castlabs/prestoplay/cl.core.js"></script>
<script src="node_modules/@conetic/prestoplay-analytics/dist/index.global.js"></script>
<script>
  VoyagerAnalytics.registerVoyagerAnalytics(clpp)
</script>
```

* * *

## 三件事会咬人

**1\. 在构建玩家之前登记.** PRESToplay 消耗插件 工厂内部 `Player` 建筑师. `registerVoyagerAnalytics()` 之后 `new clpp.Player(...)` 对那个玩家没有任何影响 却默默失败了.

**2\. 每局键属于 `load()` 配置 绝不是构造器配置 .** SDK 合并 `[constructorConfig, loadConfig, source]` 和嵌入对象合并 而不是替换. `media`, (中文(简体) ), `media_id` 财务报告和审定财务报表 `gui_path` 放置在构造器中 配置会血流成河 静态背景 (单位:千美元)`endpoint`, (中文(简体) ), `flight`, (中文(简体) ), `session`, (中文(简体) ), `system`属于构造器配置; 每个播放上下文属于 `load()`。 。 。 .

**3\. 海关运输不得作为类例.** 同样的合并副本 原始的,功能的, `Date`s和平地物体,以及 **安静地放下任何东西 带有非平面原型**。通过工厂函数或普通对象:

```ts
voyagerAnalytics: { transport: () => new MyTransport() }   // works
voyagerAnalytics: { transport: new MyTransport() }         // silently dropped
```

运输 `send(payload, { events, unloading })` 收到一个请求 一次值 : `payload` 单体,或当批量时,一组 他们,和 `events` 以相同的顺序列出内部的事件.

另请注意: 插件不运行于 `clpp.PlaylistPlayer` 内 单控制器播放列表模式,它完全禁用插件 .

* * *

## 配置

所有密钥都在下面 `voyagerAnalytics` 在玩家配置中.

### 静态- 构造器配置

| 密钥 | 类型 | 默认 | 说明 |
| :-: | --- | --- | --- |
| `endpoint` | `string` | —— 说 | 分析端点 URL. 绝对或同源. |
| `headers` | `Record<string,string>` | `{}` | 额外的请求头,例如:. `{'x-api-key': '…'}`。见下文信标提示. |
| `keepalive` | `boolean` | `true` | 发送每次事件 `fetch(..., {keepalive: true})` 因此,一个在飞行中 撕裂的要求仍然完成。 设定 `false` 只有在终点是同一来源的服务工人时: Firefox 路线在工人周围持续请求。 卸载路径总是使用保存后 `sendBeacon`。 。 。 . |
| `envelope` | `'mms' | 'raw'` | `'mms'` | `mms` 员额 `{type, payload, occurredAt}`· ; `raw` 张贴赤裸事件对象. |
| `batchSize` | `number` | `1` | 每个请求的事件. `1` 每起事件都是自己发的 1以上, 活动队列, 并作为 JSON 阵列一起出去 —— 见 **击打**。 。 。 . |
| `batchFlushMs` | `number` | `0` | 不完全的批次可能要等很久才发出. `0` =无时间限制。 忽略当 `batchSize` 为 1. |
| `disabledEvents` | `EventName[]` | `[]` | 事件名称从未发布. 事发前检查过了 所以 `sequence` 没有洞. |
| `transport` | `'http' | 'mock' | Transport | () => Transport` | `http` 何时 `endpoint` 已经设定, 否则 `mock` | 交付机制. |
| `serverTime` | RFC 3339 字符串 | —— 说 | 服务器在会话开始时的时间, 为时钟校正 。 大力推荐. |
| `flight` | `FlightContext` | —— 说 | 斯谱 4.2. 顺利通过. |
| `session` | `SessionContext` | —— 说 | 标本4.3: `session_id` 财务报告和审定财务报表 `device_id`。 。 。 . |
| `system` | `SystemContext` | —— 说 | 谱 4.5: `oem` 财务报告和审定财务报表 `app_version`。 。 。 . |
| `device` | `Partial<DeviceContext>` | 检测 | 超过检测值 . |
| `onEvent` | `(event, body) => void` | —— 说 | 无论运输方式如何, 对检查人员和调试人员来说——不是交付保证. |
| `enabled` | `boolean` | `true` | `false` 加载插件但禁用所有报告. |
| `trackChangeCoalesceMs` | `number` | `50` | 将同步音频+字幕更改合并到一个事件的窗口 . |
| `trackDiscoveryMs` | `number` | `1500` | 多长时间 `LOADEDMETADATA` 等待轨道列表, 当它看起来还是空的 。 文本音轨在内容负载后注册; 立即报告生成空 `available_subtitle_languages` 有的跑来跑去,有的跑来跑去. `0` 关闭等待。 不影响 `time_to_metadata_ms`。 。 。 . |
| `seekSettleMs` | `number` | `250` | 玩家头在报告搜索前必须安顿多久,所以擦拭器拖曳是一个事件,而不是每个中间位置一个(6.6. |
| `minSeekDeltaMs` | `number` | `1000` | 最小的跳跃报告为乘客寻找. |
| `userGestureWindowMs` | `number` | `2000` | 用户的手势是多久才写到 `video.currentTime` 算作客运动作 见 **请求** 见下文. |
| `debug` | `boolean` | `false` | 日志插件诊断. |

### 反弹.. `load()` 配置

| 密钥 | 类型 | 雷克语 | 说明 |
| :-: | --- | --- | --- |
| `media_id` | `string` | 对 | 目录标识符,在插曲/音轨级别. |
| `media` | `MediaMetadata` | 对 | Spec 4.6目录元数据,以下修改. 发送到 `PLAY` 只有这个. |
| `gui_path` | `string` | 对 | 为到达资产而走的导航路径 . |

`start_position_ms` 从玩家自己读取 `startTime` - 别重复它.

#### 这个 `media` 块

`media_title` 电影 电影 插曲 赛道 章节 没有 `episode_title`。家长进入 `series_title`,其位置在 `episode_number`数字 :

| `media_type` | `media_subtype` | `media_title` | `series_title` | `season_number` | `episode_number` | `author_or_artist` |
| :-: | --- | --- | --- | --- | --- | --- |
| `MOVIE` | —— 说 | 电影 | —— 说 | —— 说 | —— 说 | —— 说 |
| `SERIES_EPISODE` | 譬如说. `SITCOM` | 剧集 | 显示 **(韩语)** | **{\\fn华文楷体\\fs16\\1che0e0e0}雷克.** | **{\\fn华文楷体\\fs16\\1che0e0e0}雷克.** | —— 说 |
| `AUDIO` | `ALBUM` | 音轨 | 相册 **(韩语)** | —— 说 | 音轨编号。 如果知道的话 | 相册艺人 |
| `AUDIO` | `AUDIOBOOK` | 章 次 页 次 | 书本 **(韩语)** | —— 说 | 章次(如果知道) | 作者 |
| `AUDIO` | `PODCAST` | 剧集 | 播客 **(韩语)** | —— 说 | **{\\fn华文楷体\\fs16\\1che0e0e0}雷克.** | 东道主 |
| `TRAILER`, (中文(简体) ), `LIVE` | —— 说 | 标题 | —— 说 | —— 说 | —— 说 | —— 说 |

`distributor` 财务报告和审定财务报表 `duration_ms` 总是需要; `category`, (中文(简体) ), `genres`, (中文(简体) ), `original_language` 财务报告和审定财务报表 `release_year` 到处都是可选的.

插件会先减少给这些字段的任何内容 事件已经构建。 一个流浪汉 `episode_title` 或丢弃不相关的目录密钥 有警告和遗教 `media_type: 'PODCAST'` 被映射为 `AUDIO` 编号 : `PODCAST` 以0.1.x为单位的集成继续报告.

若为 `media_id` 或者说 `media` 缺少 **未报告** (单位:千美元) `clpp.Error(RECOVERABLE, PLUGIN, 7100)` 在玩家上被提升,匹配 SDK自己的插件报告配置不良.

### 请求

乘客可以两相移动游乐头,两相报道:

-   **`player.setPosition()`** 定制的UI洗手机怎么叫的? 总是报.
-   **`video.currentTime = x`** 浏览器的原生 `<video controls>` 洗涤器是的,任何UI都建立在媒体元素上. 游戏的 `USER_SEEKING`编号 :`USER_SEEKED` 永远不要为这些而开火, 只有原始的媒体事件.

玩家也为自己移动玩家头——漏洞跳出,活地修正 - 通过同样的媒体活动,测出启动缺口跳出 1.9 s,因此跳跃的大小不能将它们分开. 意向能力:乘客 求求总是遵循用户的手势,玩家的校正从未如此。 如此寻觅 写给 `currentTime` 仅当手势发生于 `userGestureWindowMs`。通过 `setPosition()` 绕过检查, 因为召集API本身就是意向声明.

**如果你的UI在程序上移动玩家头 并且你想要报告,请打电话 `player.setPosition()` 而不是写作 `currentTime`。 。 。 .**

### 阅读数据时值得了解的两种行为

**`STATE_CHANGED` 锁链.** 每个活动 `previous_state` 是前一个事件的 `current_state`因此,通过命令可以重建回放的时间线 `sequence` 内 `playback_id`这不仅仅是PRESToplay自己的 `previousState`: 玩家没有 `SEEKING` 状态 - 请求是 `BUFFERING` 携带 `reason: SEEKING` 因此,独立绘制出入口图将发出 `PLAYING → SEEKING` 接下来是 `BUFFERING → PLAYING`,不会加入.

**语言标记是可读的** 至BCP 47外壳: `zh-HANT` 变成 `zh-Hant`, (中文(简体) ), `pt-br` 变成 `pt-BR`。表态在这里和 玩家将原始值传递过, 所以没有这个, 同一语言会到达 在几个拼写下 任何组合都分开 只有外壳被改变.. 一个陌生的标记是经过未触及的 `und` 省略.

### 插件自己检测到什么

`device_type`, (中文(简体) ), `os_name`, (中文(简体) ), `browser_name` 财务报告和审定财务报表 `ui_language` 来源于 浏览器. 他们中任何一个都可以被推翻 `config.device`二个值 了解:

-   **`LAPTOP` 从未检测到.** 浏览器无法区分笔记本电脑和 桌面; 插件报告 `DESKTOP`。如果主机知道得更好,就取消它.
-   **`ui_language` 默认为 `navigator.language`。 。 。 .** 光谱将它定义为 _接口_ 语言。 如果应用程序的语言设置是 独立于浏览器, 覆盖它.

`device_id` 从未被检测到——它是船上路由器ID,必须提供 以主妇盟誓.

* * *

## 运行时间 API

```ts
import { getVoyagerAnalytics } from '@conetic/prestoplay-analytics'

const analytics = getVoyagerAnalytics(player)!
```

| 方法 | 目的 |
| :-: | --- |
| `setSessionContext({flight, session, system, device, serverTime})` | 玩家建成后提供或更新上下文. 会话拖曳通常在玩家构造后完成,所以这是正常的路线. 部分更新合并. |
| `setNavigationContext(guiPath)` | 设定 `gui_path` 下一个 `PLAY`,作为替代 `load()` 配置密钥 . |
| `reportError({error_id, error_category, error_location, error_description, is_fatal, media_id?})` | 报告应用程序级别错误 。 玩家无法生成 `ENTITLEMENT` 编号 : `APPLICATION` 类别或类别 `CATALOGUE_FETCH` 编号 : `SESSION_BOOTSTRAP` 编号 : `UI_NAVIGATION` 他们只经过这里. |
| `endPlayback(exitReason)` | 明确关闭当前播放, 例如 . `'USER_STOP'` 当应用程序撕下自己的玩家UI. |
| `flush()` | 发送任何已排队的东西 。 除非分批,否则不准打电话. |
| `getPendingCount()` | 事件已经建立但尚未发送。 除非进行分批,否则零分。 诊断. |
| `getSequence()` | 发布最后序列号. 诊断. |

* * *

## 交付

火灾与遗忘,根据光谱的工作假设(开口问题4):

-   正常事件 : `fetch` 与 `keepalive: true`。 。 。 .
-   卸载路径事件( E)`USER_LEAVING` 与 `TAB_CLOSED`: `navigator.sendBeacon`, (中文(简体) ), 倒计时 `keepalive` 获取。 从 `pagehide` 只有这个 一个页面是 只是隐藏着——屏幕锁、应用开关、前面的另一个标签——确实 **没有** 结束回放,乘客通常会回来,然后关在那里 以后的每一次事件都会下降,直到下一次 `load()`。 。 。 .
-   失败情况记录在案 **丢弃**。没有排队或重试——在 `sequence` 是光谱的丢失信号 静默的重试会隐藏它 与 分批处理时,一个失败的请求会丢失整批,漏洞也表明这一点.

### 击打

`batchSize: 1` (默认)每次事件都发布。 1以上,活动 队列并一起发布——a `STATE_CHANGED` 不再收费 自己来的 事件没有变化: `event_id`, (中文(简体) ), `event_time` 财务报告和审定财务报表 `sequence` 事件发生时盖章,而不是发出时盖章.

满了就发了一批 **早点** 何时持有会冒风险 时间: `USER_LEAVING` (回放结束了),上 `pagehide` (这页结束了, 通过 `sendBeacon`),关于玩家破坏,当传输改变,当应用 电话 `flush()`之后 `batchFlushMs` 如果设置。 之间,一个不完整的 批量等待——乘客在两小时的胶片中暂停一次,产生出两个 随行事件 `USER_LEAVING`。 。 。 .

二事以大小为相. `sendBeacon` 有效载荷预算约为64KB 上下文缓冲事件大约是 1 KB, 所以一批必须幸存下来的卸货应该 呆在这下面 失去请求会失去整个批次:a `batchSize` 5-10分之一的请求量多次超过,但没有造成任何损失 大块.

`onEvent` 每起事件仍会燃烧一次, 由事件本身的躯体 看这批货.

**灯塔提醒.** `sendBeacon` 无法设置请求头 。 若为 `headers` 携带 aPI 键,卸载路径事件将到达没有它。 如果终点需要 认证,要么接受损失 `TAB_CLOSED` 事件或移动 证书进入 URL — 属于 spec 开放问题 3 的决定 .

### 线条格式

与 `envelope: 'mms'` (默认),匹配 `POST /api/v1/analytics/events`数字 :

```json
{
  "type": "PLAY",
  "payload": { "event_id": "…", "event_name": "PLAY", "…": "…" },
  "occurredAt": "2026-01-08T16:23:06.412Z"
}
```

与 `envelope: 'raw'`,有效载荷物体单独张贴.

何时 `batchSize` 捆绑了一些事件, 身体是JSON阵列的以上, 内 `sequence` 顺序 :

```json
[
  { "type": "PLAY", "payload": { "…": "…" }, "occurredAt": "2026-01-08T16:23:06.412Z" },
  { "type": "STATE_CHANGED", "payload": { "…": "…" }, "occurredAt": "2026-01-08T16:23:06.418Z" }
]
```

碰巧举行一个活动的批次被作为单一对象发布,从不 单元素阵列——所以只接受单形式保存的端点 工作时间,只要 `batchSize` 保持为1.

* * *

## 已执行的空格问题

| {\\fn方正粗倩简体\\fs12\\an8\\1cHFFFF00\\b0} | 问题 | 该插件今天做什么 |
| :-: | --- | --- |
| 1个 | 默认 dub/ sub 当 `AUDIO_TRACK_CHANGED` 从不放火 | 如果没有改变,则不会释放任何东西。 当前选择的种子为 `LOADEDMETADATA` 这么说 _第一个_ 真实变化报告正确 `previous_*` 数值。 故意不承认一个合成的默认——它会捏造一个事件. |
| 3个 | 端点规格 | `endpoint`, (中文(简体) ), `headers` 财务报告和审定财务报表 `envelope` 全部可以配置;没有硬码. |
| 页:1 | 重试/ 队列 | 起火而忘相会. A 类 `Transport` 如果修改,接口是扩展点. |
| 页:1 | `device_id` 稳定 | 被视为由东道方提供,在飞行中跨会稳定。 该插件从未发明或坚持它 . |

* * *

## 类型脚本

`clpp.PlayerConfiguration` 是一类别名,没有索引签名,所以不能 通过声明合并扩展,一个自定义密钥是多余的产权错误. 使用导出相交点 :

```ts
import type { WithVoyagerAnalytics } from '@conetic/prestoplay-analytics'

const config: WithVoyagerAnalytics<clpp.PlayerConfiguration> = {
  source: { url },
  voyagerAnalytics: { media_id: '9090929', media },
}
await player.load(config)
```

* * *

## 杰森·斯克马

2020-12年事件有效载荷船舶计划草案:

```
@conetic/prestoplay-analytics/schema
```

插件可以发射的每一个事件都会在测试套件中针对它进行验证.

* * *

## 发展

```bash
npm install
npm run build          # ESM + CJS + IIFE + .d.ts
npm test               # unit suite (vitest, no browser)
npm run test:browser   # browser suite (Playwright, real player, real streams)
npm run typecheck
```

浏览器套房驱动一个真实的PRESToplay播放器对接公共测试流, 装入已建 `dist/`。它涵盖了假玩家无法做到的事: SDK真实地发出,按照它发出的顺序,发出它报告的值—— 寻找、追踪和错误位置的行为 已经建立。 它需要网络访问并使用当地安装的Chrome CI 运行 `npx playwright install chromium` 设置 `PW_CHANNEL=`。 。 。 .

测试套间包括一个读取安装的警卫 `@castlabs/prestoplay/typings.d.ts` 并声称每个PRESToplay常数 插件镜像仍然匹配——所以SDK升级后会重新编号玩家状态 而不是悄悄地腐蚀分析师.

## 常见问题

### @conetic/prestoplay-analytics 是什么？

PRESToplay 插件, 将 Voyager IFE 分析事件报告到分析端点

### 如何安装 @conetic/prestoplay-analytics？

在项目目录运行 npm install @conetic/prestoplay-analytics，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：@castlabs/prestoplay（^6\.0\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @conetic/prestoplay-analytics 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @conetic/prestoplay-analytics 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @conetic/prestoplay-analytics 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=18。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @conetic/prestoplay-analytics 可以商用吗？

@conetic/prestoplay-analytics 使用 SEE LICENSE IN LICENSE 许可。许可条款写在包内的独立文件中，请阅读该文件确认可否商用。以上为概括，不构成法律意见，请以许可原文为准。

### @conetic/prestoplay-analytics 的下载量有多少？

根据 npm 官方下载统计，@conetic/prestoplay-analytics 在 2026/10/11 – 2026/11/09 这 30 天内被下载 3,772 次，日均约 126 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @conetic/prestoplay-analytics 还在维护吗？

最新版本 0\.2\.1 发布于 2026/10/02（1 个月前）；至今共发布 1 个版本，其中过去 12 个月发布了 1 个；首次发布于 2026/10/02。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

