A lightweight, atomic live-streaming player SDK — fast start, seamless switching, easy to extend.
English | 简体中文 | 日本語 · ⬅ Back to overview
AtomicPlayer targets low-latency live streaming (LEB / RTMP) and CDN pull-stream scenarios. It does one thing well: play a live stream fast and stable.
- 🚀 Fast start — first frame under 600ms
- 🎞️ Premium visual quality — opt-in AI super-resolution and HDR
- 🔄 Seamless switch — quality switch is smooth
- 🌐 Consistent across platforms — all platforms share the same unified flow
| Capability | API |
|---|---|
| Playback control | startPlay / stopPlay / pause / resume |
| Seamless switch | switchStream |
| Render control | setRenderView / setRenderRotation / setRenderFillMode |
| Snapshot | snapshot |
| Volume | setVolume |
| SEI messages | enableReceiveSeiMessage |
| Event callbacks | AtomicPlayerObserver |
| Advanced features | enableAdvancedFeature (AI super-resolution / HDR) |
- Android minSdk 21+ (Android 5.0)
- ABIs:
armeabi-v7a/arm64-v8a/x86_64
In your project-level settings.gradle (or build.gradle), add the Maven repository:
dependencyResolutionManagement {
repositories {
maven { url "" } // TODO: fill in AtomicPlayer Maven repository URL
}
}In your module-level build.gradle, add the dependency:
dependencies {
implementation "" // TODO: fill in AtomicPlayer Maven coordinate, e.g. "io.trtc:atomic-player:x.y.z"
}<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><io.trtc.tuikit.atomicxcore.api.view.AtomicView
android:id="@+id/atomic_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />val player = AtomicPlayerImpl()
player.setRenderView(findViewById(R.id.atomic_view))
player.startPlay("https://your-cdn.com/live/stream.m3u8")class PlayerActivity : AppCompatActivity() {
private lateinit var player: AtomicPlayer
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_player)
player = AtomicPlayerImpl()
player.setRenderView(findViewById(R.id.atomic_view))
player.setObserver(object : AtomicPlayerObserver() {
override fun didRenderFirstVideoFrame(player: AtomicPlayer, elapsedMs: Int) {
Log.i("AtomicPlayer", "First frame: ${elapsedMs}ms")
}
override fun didFailWithCode(
player: AtomicPlayer,
code: AtomicPlayerCode,
message: String
) {
Log.e("AtomicPlayer", "Failed: $code, $message")
}
})
player.startPlay("https://your-cdn.com/live/stream.m3u8")
}
override fun onDestroy() {
super.onDestroy()
player.stopPlay()
player.setObserver(null)
}
}Supported protocols: FLV / HLS (http(s)://…) · LEB (webrtc://) · RTMP (rtmp://)
▶ Seamless quality switch (no black frame)
// ✅ Recommended: seamless, no black frame
player.switchStream("webrtc://.../stream_1080p")
// ❌ Not recommended: visible black frame + re-first-frame
player.stopPlay()
player.startPlay("webrtc://.../stream_1080p")The result is delivered asynchronously via didSwitchStream(player, url, code).
▶ Render fill mode
import com.tencent.cloud.tuikit.engine.common.TUICommonDefine.VideoRenderParams.FillMode
player.setRenderFillMode(FillMode.Fill) // fill container, crop overflow (default)
player.setRenderFillMode(FillMode.Fit) // aspect-fit, may have letterbox
player.setRenderFillMode(FillMode.ScaleFill) // stretch to fill, may distort▶ Snapshot
player.snapshot()
override fun didTakeSnapshot(player: AtomicPlayer, image: Bitmap) {
// save / share / display
}▶ Receive SEI messages (danmaku sync, co-hosting signals, timestamp alignment)
player.enableReceiveSeiMessage(enable = true, payloadType = 243)
override fun didReceiveSEI(player: AtomicPlayer, data: ByteArray) {
Log.i(TAG, "SEI: ${String(data, Charsets.UTF_8)}")
}Supported payloadType: 5 / 100 / 242 / 243.
▶ HEVC fallback to H.264
override fun didFailWithCode(
player: AtomicPlayer,
code: AtomicPlayerCode,
message: String
) {
if (code == AtomicPlayerCode.ERROR_NO_AVAILABLE_HEVC_DECODERS) {
player.stopPlay()
player.startPlay(h264FallbackUrl)
}
}▶ Advanced features (AI super-resolution / HDR)
player.enableAdvancedFeature("setVideoSuperResolutionEnableMode", 1) // AI super-resolution
player.enableAdvancedFeature("enableHdrEnhancement", "{\"enable\": 1}") // HDRAll methods on AtomicPlayerObserver have a default no-op implementation — override only what you care about:
| Category | Callback | Description |
|---|---|---|
| Playback | didRenderFirstVideoFrame(player, elapsedMs) |
First frame rendered; elapsed since startPlay |
didStartBuffering(player) / didEndBuffering(player, elapsedMs) |
Buffering start / end | |
didChangeVideoSize(player, width, height) |
Resolution changed | |
| Connection | didConnect(player) / didDisconnect(player) |
Connected / disconnected |
didFailWithCode(player, code, message) |
Playback failed | |
| Data | didUpdateStatistics(player, stats) |
Stats every 2s (resolution / bitrate / fps) |
didSwitchStream(player, url, code) |
Stream switch finished | |
didTakeSnapshot(player, image) |
Snapshot ready | |
didReceiveSEI(player, data) |
SEI received |
⚠️ All callbacks are dispatched on the main thread. Update UI directly; move heavy work to a background thread yourself.
| Enum | Value | Description |
|---|---|---|
OK |
0 | Success |
ERROR_FAILED |
-1 | Uncategorized failure |
ERROR_INVALID_PARAMETER |
-1001 | Invalid parameter |
ERROR_INSTANCE_NOT_EXIST |
-1002 | Instance disposed |
ERROR_NO_AVAILABLE_HEVC_DECODERS |
-2304 | No HEVC decoder available on the device |