DEV Community

Hector Moreno
Hector Moreno

Posted on

MVVM Background Video

Hey hola este es mi primer post y quiero compartirles como generar una vista con video en MVVM en SwiftUI

  1. Crearemos nuestro proyecto en SwiftUI.
  2. Dentro de la carpeta de nuestro proyecto, crearemos otra carpeta para guardar los videos que utilizaremos en este caso usaremos el nombre de Resources

  3. Copiamos nuestros archivos en formatos (.MOV, .MP4, .M4V, .HLS / .M3U8) a nuestra carpeta Resources.

  4. Para tener ordenado nuestro código generaremos dos carpetas la primera sera View y la segunda carpeta sera nuestro ViewModel, dentro de nuestro ViewModel generaremos un EmptyFile y lo llamaremos VideoLooper.

  5. Dentro del archivo VideoLooper haremos un import de SwiftUI y AVFoundation
    esta libreria de AVFoundation contiene las herramientas para trabajar con Audio y Video permite la crear, editarm procesar archivos multimedia etc), nosotros la usaremos para insertar un video y reproducirlo infinitamente.

una vez importadas las librerias usaremos la macro @observable esta reemplazara el antiguo protocolo ObservableObject y ya no requiere de la macro @Published.

dentro de la clase generaremos dos variables la primera sera un private(set) que sera de tipo AVQueuePlayer y quizá te preguntes por que private(set) es por que permite que la vista pueda leer el valor al momento de realizar el cambio de estado, la segunda variable a generar será nuestra variable privada looper de tipo AVPlayerLooper esta variable nos permitirá generar el loop sin interrupciones manteniendo una reproducción fluida y es ideal para videos cortos o para usarla en fondos animados, terminando de declarar nuestras variables generaremos una función que llamaremos setUpVideo y al cual le pasaremos el nombre del video que guardamos en el paso 3.

En nuestra función obtendremos la url de nuestros videos al ser un recurso local usaremos un guard let Bundle.main.url(forResource: String, withExtension: String)
este bundle nos permitira buscar en nuestra carpeta de resources el nombre del video con la extensión del mismo de una manera segura sin generar algun crash dentro de la aplicación.

debajo de nuestro guard generaremos un item con AVPlayerItem(url: URL) al cual le pasaremos la url de nuestro archivo, el AVPlayerItem nos permite saber si el archivo multimedia esta listo para reproducirse, también nos proporciona información sobre la duración y progreso del video.

declararemos un queuePlayer que sera de tipo AVQueuePlayer, al queuePlauyer le pasaremos el item generado con el AVPlayerItem(url: URL) , el queuePlayer lo usaremos para mutear el video ya que sera un video de fondo lo cual quedaria como queuePlayer.isMuted = true, posteriormente a nuestra variable looper le asignaremos el queuePlayer y el item de nuestro video de la siguiente manera

self.looper = AVPlayerLooper(player: queuePlayer, templateItem: item)

y a nuestra variable player le pasaremos el queuePlayer.

Dentro de la clase VideoLooper terminaremos de poner los controles de nuestro video con la función play y pausa.

Generaremos ahora nuestra vista, debido a que SwiftUI no incluye una vista nativa avanzada para manejar de manera directa todas las capas del video envolveremos nuestra vista en UIKit usando el UIViewRepresentable.

Primero generaremos el contenedor de nuestra vista la llamaremmos PlayerContainerView de tipo UIView para asegurarnos que se maneje de forma correcta crearemos una subclase de UIView que sobre escribe el layer para que devuelva un AVPlayerLayer.

Luego generaremos el puente a SwiftUI el cual será un struc de tipo UIViewRepresentable.
Crearemos la vista con una funcion que llamaremos makeUIView la cual contendra el contexto de nuestra app y devolvera un UIView dentro de makeUIView sobre escribiremos el layer donde ira nuestro video y realizaremos la configuración que requeriremos para la vista en este caso usaremos el videoGravity .resizeAspectFill para que el video se pueda mostrar de manera correcta en toda nuestra pantalla y posterior a esto tendremos el updateUIView el cual nos ayudara a actualizar nuestra vista cada que detecte un cambio esto nos ayudara a evitar crashes en caso de que no contenga ningún video.

al finalizar nuestro file VideoView quedaria de la siguiente manera.

esto se puede separar en archivos diferentes pero al ser pequeños y pertenecer a la creación de la vista decidi que se quedaran en el mismo.

al finalizar en nuestro ContentView usaremos un @State looper para manejar nuestro video, dentro del body use un ZStack para poder usar componentes sobre componentes en nuestro caso usare un botón que permita controlar el cambio del video.

generamos una función que detecte que cuando cambia se presione el botón cambie el booleano y ponga un video u otro al final nuestro código queda de la siguiente manera:

y al final agrege un VStack y un spacer para poner el bóton hasta abajo del video el resultado final es:

Top comments (0)