https://kotlinlang.org logo
#compose
Title
# compose
p

Philip Dukhov

12/27/2020, 3:26 AM
Hello! I’m trying to use webrtc with compose. I’ve created the following wrapper:
Copy code
data class SurfaceViewContext(
    val eglBase: EglBase,
    val videoTrack: VideoTrack,
)

@Composable
fun SurfaceView(
    surfaceViewContext: SurfaceViewContext,
    modifier: Modifier,
) {
    val context = AmbientContext.current
    val customView = remember {
        SurfaceViewRenderer(context).apply {
            init(surfaceViewContext.eglBase.eglBaseContext, null)
            setEnableHardwareScaler(true)
            setMirror(true)
        }
    }

    AndroidView(
        { customView },
        modifier = modifier
    ) {
        surfaceViewContext.videoTrack.addSink(it)
    }
    onDispose {
        surfaceViewContext.videoTrack.removeSink(customView)
    }
}
And using it like this:
Copy code
@Composable
fun TestView(context: SurfaceViewContext?) =
        Column(
                modifier = Modifier
                        .fillMaxWidth()
        ) {
            context?.let {
                SurfaceView(
                        it,
                        modifier = Modifier
                                .weight(1F)
                )
            }
            Box(
                    modifier = Modifier
                            .size(40.dp)
                            .background(Color.Red)
            )
            Text("hello",
                    color = Color.White,
                    modifier = Modifier
            )
            Box(
                    modifier = Modifier
                            .background(Color.Red)
                            .aspectRatio(1080F/1920)
                            .align(Alignment.End)
                            .padding(10.dp)
                            .weight(1F)
            ) {
                context?.let {
                    if (counter % 2 == 0) {
                        SurfaceView(
                                it,
                                modifier = Modifier
                                        .fillMaxSize()
                        )
                    }
                }
            }
            Text(
                    "hello again",
                    color = Color.White,
                    modifier = Modifier
                            .align(Alignment.End)
            )
        }
But there’s a bug. All views above SurfaceView, except an other SurfaceView, becomes invisible. I’ve added a counter and update the view once a second to add/remove a second SurfaceView. When it’s presented, the container containing it disappears, as well as other Box and Text. Text below is visible all the time. If I use Box instead of a Column as a main container, problem is the same. sample project: https://github.com/PhilipDukhov/ComposeWebRTCTest
🙌 1
r

rharter

12/27/2020, 3:31 AM
That's how SurfaceView works, it cuts a hole in the window buffer to show it's content. You can sue TextureView instead if you want to interleave the view with others, but surface view can't really do that.
👍 3
p

Philip Dukhov

12/27/2020, 3:50 AM
Oh I didn’t know that! Looks like
SurfaceViewRenderer.setZOrderOnTop(true)
fixed that, thanks a lot!
r

rharter

12/27/2020, 4:27 PM
That can work, but you have to be careful with it if you need to interact with things like dialogs, or if you need to do animation, etc.
👍 2
91 Views