Unite Video Players: Compose Multiplatform para iOS, Android y Desktop | de Kashif Mehmood | julio 2023
Descubra la alegría multiplataforma: ¡Presentamos los reproductores de video multiplataforma de Compose para iOS, Android y escritorio! Muchos de ustedes que han trabajado con XML y los viejos días de ExoPlayer saben lo difícil que era integrar un reproductor de video en una aplicación. Afortunadamente, las cosas han mejorado significativamente con Jetpack Compose. Pero incluso mejor que Compose en sí mismo es Compose Multiplatform, que permite a los desarrolladores de Android convertirse en desarrolladores de «iOS Lite». Sin embargo, faltan algunas piezas en este rompecabezas y, como dice el Doctor Strange: «En el gran cómputo del multiverso, algunas vistas deberían permanecer nativas, de lo contrario no habrá natividad». Tiene que ser específico de la plataforma o la aplicación carecerá de la sensación nativa de cada plataforma. Nadie quiere usar un iPhone y obtener un reproductor de video al estilo de Android. Entonces empecemos.
Contenidos
Espere el mecanismo real:
Si ya está familiarizado con KMM, es posible que esté familiarizado con el mecanismo Expect/Actual. Podemos usarlo para crear una función VideoPlayer como una función esperada, y cada plataforma proporcionará su implementación real @Composableexpect fun VideoPlayer(Modifier: Modifier, URL: String) Con este enfoque, pasar el modificador como primer parámetro a cada función componible se considera una buena práctica. Esto le permite personalizar el componente sin cambiar su cadena interna de modificadores. Cada plataforma (Android, iOS, etc.) luego implementa la función VideoPlayer real con código específico de la plataforma mientras mantiene la misma firma de función esperada. Agrega la función actual a todas las plataformas. @Composableactual fun VideoPlayer(modifier: Modifier, url: String) { // Implementación específica de la plataforma aquí }
Implementación de Android:
Como desarrollador de Android, es posible que esté familiarizado con ExoPlayer, una biblioteca de reproductores multimedia para Android.
Paso 1:
Agregue las dependencias de ExoPlayer a Android Main en su archivo build.gradle del módulo compartido val androidMain llamando a {dependencies {implementation(«androidx.media3:media3-exoplayer:1.1.0»)implementation(«androidx.media3:media3-exoplayer-dash:1.1.0»)implementation(«androidx.media3:media3-ui:1.1.0»)}} . Ahora necesita agregar la implementación real de su reproductor de video. Para hacer esto, debe ir al menú principal de Android donde creó la función real y agregar este código. )}En Para la implementación real del reproductor de video para Android, usamos el AndroidView componible para integrar la funcionalidad ExoPlayer en una vista de Android. VideoPlayer para Android usa ExoPlayer internamente a través de VideoView incrustado en AndroidView componible, lo que nos permite reproducir videos en múltiples plataformas. ¿Bastante fácil?
Implementación del IOS:
En nuestra implementación de iOS, podemos integrar las vistas de AVPlayer y UIKit mediante la interoperabilidad C de Kotlin. Primero creamos la instancia de AVPlayer con la URL proporcionada y usamos AVPlayerLayer y AVPlayerViewController. AVPlayerViewController maneja el control de reproducción y proporciona una sensación nativa. AVPlayer es similar a ExoPlayer en Android. val player = recordar { AVPlayer(uRL = NSURL.URLWithString(url)!!) }val playerLayer = recordar { AVPlayerLayer() }val avPlayerViewController = recordar { AVPlayerViewController() }avPlayerViewController.player = playeravPlayerViewController.showsPlaybackControls = trueplayerLayer.player = playerEl UIKitView Composable se usa para integrar AVPlayerViewController en UIKit existente vistas Se crea la vista de contenedor del reproductor y se agrega la vista de AVPlayerViewController como vista secundaria. La devolución de llamada onResize garantiza que el marco del reproductor cambie de tamaño correctamente. Cuando la vista se actualiza, el reproductor comienza a jugar. Aquí puede ver que el modificador que pasamos se puede usar directamente en UIKitView. // Use un UIKitView para integrarlo con sus vistas de UIKit existentes. UIKitView(factory = {// Cree una UIView para almacenar AVPlayerLayerval > ->CATransaction.begin()CATransaction.setValue(true, kCATransactionDisableActions)view.layer.setFrame(rect)playerLayer.setFrame(rect)avPlayerViewController.view.layer.frame = rectCATransaction.commit()},update = { view ->player.play()avPlayerViewController.player !!.play()},modifier = modificador)Nuestra última función debería tener este aspecto: @Composableactual fun VideoPlayer(modifier: Modifier , url: String) {val player = recordar { AVPlayer(uRL = NSURL.URLWithString(url)!!) }val playerLayer = recordar { AVPlayerLayer() }val avPlayerViewController = recordar { AVPlayerViewController() }avPlayerViewController.player = playeravPlayer ViewController.showsPlaybackControls = trueplayer Layer.player = player// Use un UIKitView para integrarlo con sus vistas de UIKit existentesUIKitView(factory = {// Cree un UIView para contener el AVPlayerLayerval playerContainer = UIView()playerContainer.addSubview(avPlayerViewController.view)// Devuelve el playerContainer como UIViewplayerContainer raíz},onResize = { view: UIView, rect: CV valor
Implementación de escritorio:
Integrar la reproducción de video en Compose Desktop es un poco complicado, pero factible. Usamos SwingPanel y agregamos la dependencia de VLC a Desktop Main. SwingPanel(factory = Factory,background = Color.Transparent,modifier = modifier,update = {}) val desktopMain by get {dependencies {implementation(«uk.co.caprica:vlcj:4.7.0»)}}Aquí hay una implementación simple de VideoPlayer usando VLCJ. Inicializa el reproductor multimedia, reproduce la URL del video y maneja los componentes del reproductor específicos de macOS. ¡Ahora puede disfrutar de la reproducción de video en Compose Desktop! 🎉❤️@Composablefun VideoPlayerImpl(url: String,modifier: Modifier,) {val mediaPlayerComponent = Recordar { initializeMediaPlayerComponent() }val mediaPlayer = Recordar { mediaPlayerComponent.mediaPlayer() }val Factory = Recordar { { mediaPlayerComponent } }LaunchedEffect(url) { mediaPlayer.media().play/*OR .start*/(url) }DisposableEffect(Uni t) { onDis pose(mediaPlayer::release) }SwingPanel(factory = Factory,background = Color.Transparent,modifier = modifier,update = {})}private fun initializeMediaPlayerComponent(): Component {NativeDiscovery().discover()return if (isMacOS()) {CallbackMediaPlayerComponent()} else {EmbeddedMediaPlayerComponent()}}private fun Component.mediaPlayer() = when (this) {is CallbackMediaPlay erComponent -> mediaPlayer() is EmbeddedMediaPlayer Component -> mediaPlayer()else -> error(«mediaPlayer() solo se puede llamar en los componentes del reproductor vlcj»)} diversión privada isMacOS(): Boolean {val os = System.getProperty(«os.name», «generic»).lowercase(Locale.ENGLISH)return «mac» in os || «darwin» en OS} y listo ❤. El reproductor de video multiplataforma Compose para escritorio es experimental y se puede encontrar aquí.
Resultado:
se puede ver en un video de arriba. Enlace de repositorio: https://github.com/Kashif-E/Compose-Multiplatform-Video-PlayerGracias por leer ❤ Aplaude si aprendiste algo. Avancemos Gorjeo y LinkedIn y discutir otras ideas.