Skip to content

Commit f48f52f

Browse files
committed
Add the platform video player composable
1 parent 923c0f0 commit f48f52f

3 files changed

Lines changed: 66 additions & 0 deletions

File tree

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.pureswift.swiftui
2+
3+
import androidx.compose.foundation.layout.fillMaxWidth
4+
import androidx.compose.foundation.layout.height
5+
import androidx.compose.runtime.Composable
6+
import androidx.compose.runtime.DisposableEffect
7+
import androidx.compose.runtime.remember
8+
import androidx.compose.ui.platform.LocalContext
9+
import androidx.compose.ui.viewinterop.AndroidView
10+
import androidx.compose.ui.unit.dp
11+
import androidx.media3.common.MediaItem
12+
import androidx.media3.exoplayer.ExoPlayer
13+
import androidx.media3.ui.PlayerView
14+
15+
/// Hosts a Media3 player with its standard controls. The player prepares
16+
/// paused on the first frame; the user starts playback from the controls.
17+
@Composable
18+
internal actual fun RenderVideoPlayer(node: ViewNode) {
19+
val url = node.string("url") ?: return
20+
val context = LocalContext.current
21+
val player = remember(node.id, url) {
22+
ExoPlayer.Builder(context).build().apply {
23+
setMediaItem(MediaItem.fromUri(url))
24+
playWhenReady = false
25+
prepare()
26+
}
27+
}
28+
DisposableEffect(node.id, url) {
29+
onDispose { player.release() }
30+
}
31+
AndroidView(
32+
factory = { PlayerView(it).apply { this.player = player } },
33+
modifier = node.composeModifiers().fillMaxWidth().height(220.dp),
34+
)
35+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.pureswift.swiftui
2+
3+
import androidx.compose.runtime.Composable
4+
5+
/// A video player for the node's `url`. Platform-specific: Android hosts a
6+
/// system player view with playback controls; the desktop rig shows a
7+
/// placeholder.
8+
@Composable
9+
internal expect fun RenderVideoPlayer(node: ViewNode)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.pureswift.swiftui
2+
3+
import androidx.compose.foundation.background
4+
import androidx.compose.foundation.layout.Box
5+
import androidx.compose.foundation.layout.fillMaxWidth
6+
import androidx.compose.foundation.layout.height
7+
import androidx.compose.runtime.Composable
8+
import androidx.compose.ui.Alignment
9+
import androidx.compose.ui.graphics.Color
10+
import androidx.compose.material3.Text
11+
import androidx.compose.ui.unit.dp
12+
13+
/// The desktop rig has no media stack; show a labeled placeholder.
14+
@Composable
15+
internal actual fun RenderVideoPlayer(node: ViewNode) {
16+
Box(
17+
contentAlignment = Alignment.Center,
18+
modifier = node.composeModifiers().fillMaxWidth().height(220.dp).background(Color.Black),
19+
) {
20+
Text("${node.string("url") ?: ""}", color = Color.White)
21+
}
22+
}

0 commit comments

Comments
 (0)