Using with BB Native Player SDK
By default, the channel plays video in the WebView using the standard web player. For better performance and platform integration, you can use the BB Native Player SDK (ExoPlayer-based) for native playback.
Setup
- Add the BB Native Player SDK to your
build.gradle.kts:implementation("com.bluebillywig:nativeplayer:<version>") - Enable native player mode in the channel options:
val options = BBChannelOptions(nativePlayerMode = true)
When nativePlayerMode is enabled, the channel will not create a web player. Instead, it fires onMediaPlay events that your app handles by creating a native player.
Handling Media Play
import com.bluebillywig.channel.compose.BBChannelView
import com.bluebillywig.channel.compose.BBChannelViewModel
import com.bluebillywig.channel.compose.BBChannelCallbacks
import com.bluebillywig.channel.compose.BBChannelOptions
import com.bluebillywig.nativeplayer.BBNativePlayer
@Composable
fun ChannelScreen() {
val viewModel = BBChannelViewModel()
var activePlayer by remember { mutableStateOf<BBNativePlayer?>(null) }
Box(modifier = Modifier.fillMaxSize()) {
BBChannelView(
channelUrl = "https://demo.bbvms.com/ch/1152.json",
options = BBChannelOptions(nativePlayerMode = true),
viewModel = viewModel,
callbacks = BBChannelCallbacks(
onMediaPlay = { media ->
handleMediaPlay(media) { activePlayer = it }
},
onMediaEnd = {
activePlayer = null
}
)
)
activePlayer?.let { player ->
NativePlayerView(player = player)
}
}
}
private fun handleMediaPlay(
media: BBMediaInfo,
setPlayer: (BBNativePlayer) -> Unit
) {
val jsonUrl = media.jsonUrl ?: return
val player = BBNativePlayer()
player.load(jsonUrl)
if (media.isInlinePlayer) {
// Inline player — position over the WebView player area
player.play()
} else {
// Modal/fullscreen player
player.enterFullscreen()
player.play()
}
setPlayer(player)
}
Auto-Advance with Context
When nativePlayerMode is enabled and the channel is configured with playlists, the onMediaPlay event includes playlist context for auto-advance:
onMediaPlay = { media ->
media.clipListId?.let { clipListId ->
media.index?.let { index ->
println("Playing clip $index of playlist $clipListId")
// Use context to load the next clip when playback ends
}
}
}
The context map contains the playlist data needed to advance to the next clip. Pass it to your native player's playlist handler for seamless auto-advance behavior.
Architecture
The native player integration uses the same WebView bridge as all other SDK features. When nativePlayerMode is true:
- Channel JS detects native mode and skips iframe player creation
- A
mediaPlayevent is posted to the WebView bridge - The SDK deserializes it into a
BBMediaInfoand firesonMediaPlay - Your app creates a native ExoPlayer overlay
See Architecture for the full bridge design.