> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kontext.so/llms.txt
> Use this file to discover all available pages before exploring further.

# TTSDK 播放器

> 通过 so.kontext:video-ttsdk 把 TTSDK 引擎（TTVideoEngine）交给 SDK。

SDK 会跟随你的内容播放器：观众在剧集中的位置，以及内容是否在播放。叠加广告只在内容播放时展示，观众暂停时结束；暂停广告在内容再次播放时结束。使用 TTSDK 播放器（`TTVideoEngine`，BytePlus / 火山引擎点播播放器 SDK）时，一次调用就能把这些都交给 SDK。

## 添加适配器

```kotlin theme={null}
dependencies {
    implementation("so.kontext:video:0.1.0")
    implementation("so.kontext:video-ttsdk:0.1.0")
}
```

* **TTSDK 1.40 或更高版本。**
* **不包含 TTSDK。** 适配器使用你应用自己的 TTSDK 和你的授权；它不会向你的构建添加任何 TTSDK 构件或仓库。

## 跟随引擎

```kotlin theme={null}
import so.kontext.video.ttsdk.track

ads.track(engine)
```

在引擎拿到该集的播放源（`setStrategySource`、`setVideoID` 等）之后、剧集开始时调用。SDK 弱持有引擎，并在 `ads.destroy()` 或下一次 `track` 时放开。

**你的回调保持不变。** 适配器通过 `addVideoEngineCallback` 监听，与你用 `setVideoEngineCallback` 设置的回调并存，放开时移除它自己的回调。观众一暂停叠加广告就会结束。

## 在信息流中

短剧信息流通常为每一页提供自己的引擎，或者把 TTSDK 预渲染好的引擎交给某一页。为每一页创建自己的 `VideoAds`，并在该页成为当前页时跟随该页的引擎：

```kotlin theme={null}
override fun onPageSelected(page: Int) {
    val item = pages[page]
    item.ads.track(item.engine)        // 这一页的引擎，无论是否预渲染
}
```

只在当前页展示叠加广告或暂停广告。广告在屏幕上时被滑走的页面，其广告会在大约一秒内结束（`INTERRUPTED`），以便下一页的广告可以展示。

## 播放速度

TTSDK 没有读取速度的方法。观众改变速度时告诉 SDK，这样叠加广告的时长才能正确按视频秒数计算：

```kotlin theme={null}
ads.track(engine) { currentSpeed }     // SDK 需要时读取
```

不提供时，SDK 接受最高约 4× 的播放速度，更大的跳变视为拖动进度。

## SDK 读取什么

| SDK 需要 | 从 TTSDK 读取 |
| - | - |
| 内容的位置 | `getCurrentPlaybackTime()`，单位为毫秒 |
| 是否在播放 | `getPlaybackState()` 为播放中。被观众或你的应用暂停或停止不算播放；缓冲算作播放。 |
| 另一集 | 同一引擎上的另一个 `getVideoID()`，或视频播放结束（`onCompletion`）：结束后重新播放算作另一次播放 |
| 拖动进度 | 根据位置推断：TTSDK 不报告拖动 |

此后，一旦引擎播放另一个视频，该 `VideoAds` 的叠加广告或暂停广告会在 `show` 时抛出 `Invalidated(ContentChanged)`。播放没有 vid 的 URL 的引擎仍会被跟随，只是跳过这项检查。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.