> ## 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.

# Tencent Cloud Player

> Hand a Tencent Cloud Player SDK player (TXVodPlayer) to the SDK with so.kontext:video-txplayer.

The SDK follows your content player: where the viewer is in the episode, and whether the content plays. An overlay shows over playing content only and ends when the viewer pauses; a pause ad ends when the content plays again. With the Tencent Cloud Player SDK (`TXVodPlayer`, LiteAV), one call and one line in your play listener give the SDK all of that.

## Add the adapter

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

* **Player SDK 11.0 or later** (`TXVodPlayer`, any LiteAV edition that has it).
* **The Player SDK is not included.** The adapter uses your app's own Player SDK, with your license; it adds no LiteAV artifact to your build.
* **R8:** the adapter needs no rules from you. Keep the Player SDK's own rule from its integration guide (`-keep class com.tencent.** { *; }`): a minified app without it aborts when it creates a player.

## Track the player

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

ads.track(player, currentItem = { episode.id })
```

Call it once the player has the episode's source (`startVodPlay`), when the episode starts. The SDK holds the player weakly and lets go at `ads.destroy()` or the next `track`.

`currentItem` is optional: your episode on this player (its id), for a player that plays several episodes one after another. Without it the player is the episode. Either way, playing the video to its end, or a loop's next round, counts as another play.

## Hand on the play events

A `TXVodPlayer` has one listener, yours (`setVodListener`), so the SDK does not take it. Hand each play event on from your `onPlayEvent`, as given:

```kotlin theme={null}
import so.kontext.video.txplayer.KontextTXVodPlayer

player.setVodListener(object : ITXVodPlayListener {
    override fun onPlayEvent(player: TXVodPlayer, event: Int, param: Bundle?) {
        KontextTXVodPlayer.onPlayEvent(player, event)
        // … your own handling
    }

    override fun onNetStatus(player: TXVodPlayer, status: Bundle?) {}
})
```

With them the SDK hears the end of the video, a loop's next round and a seek at once. Without them it still follows the player, reading its position and `isPlaying()`, and infers seeks from the position. An event for a player no `VideoAds` tracks is ignored, so forward every event of every player.

## In a feed

Short-drama feeds usually give each page its own `TXVodPlayer`. Give each page its own `VideoAds`, and track the page's player once it has its source:

```kotlin theme={null}
override fun onPageSelected(page: Int) {
    val item = pages[page]
    item.ads.track(item.player, currentItem = { item.episodeId })
}
```

Show an overlay or pause ad on the current page only. A page swiped away with its ad on screen ends that ad within about a second (`INTERRUPTED`), so the next page's ad can show. A neighbour page prepared ahead and paused is not playing, so no overlay shows over it.

## Pause and buffering

The Player SDK sends no event for a pause. The SDK reads `isPlaying()` four times a second while an overlay or pause ad is on screen, and at every `show`, so an overlay ends within a quarter of a second of `pause()`. `isPlaying()` stays true while the player stalls to load, so buffering counts as playing and an overlay stays.

## The playback speed

The Player SDK has no getter for the speed. When the viewer changes it (`setRate`), tell the SDK, so an overlay's duration counts video seconds correctly:

```kotlin theme={null}
ads.track(player, playbackSpeed = { currentRate })     // read when the SDK needs it
```

Without it, the SDK accepts playback up to about 4× and takes a bigger jump for a seek.

## What the SDK reads

| The SDK needs | Read from the Player SDK |
| - | - |
| Where the content is | `getCurrentPlaybackTime()`, in seconds |
| Whether it plays | `isPlaying()`. Paused, ended or stopped is not playing; buffering is. |
| Another episode | another `currentItem` from your closure, or the end of the video (`PLAY_EVT_PLAY_END`) or a loop's next round (`VOD_PLAY_EVT_LOOP_ONCE_COMPLETE`): a replay is another play |
| A seek | `VOD_PLAY_EVT_SEEK_COMPLETE`, or inferred from the position without the events |

An overlay or pause ad of a `VideoAds` then throws `Invalidated(ContentChanged)` at `show` once its player plays another episode or plays this one again.


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