26 - Control CameraCaptureUI para tomar videos


La clase CameraCaptureUI también es la encargada de la captura de videos desde una aplicación universal de Windows.

Como vimos anteriormente esta componente se la invoca y nos provee la interfaz visual para la captura de videos.

Problema

Implementar una aplicación que permita tomar una video con la cámara del dispositivo móvil o web cam y posteriormente la muestre en un control MediaElement.

Como primer paso creamos un nuevo proyecto llamado "Proyecto34" seleccionando desde el menú de opciones del Visual Studio: Archivo -> Nuevo -> Proyecto

La interfaz visual queda definida por el archivo MainPage.xaml que contiene un botón para mostrar la interfaz visual que crea el CameraCaptureUI y un objeto de la clase MediaElement para reproducir posteriormente el video:

<Page
    x:Class="Proyecto34.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Proyecto34"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Button Content="Tomar video" 
                Click="Button_Click"  
                HorizontalAlignment="Center"
                Grid.Row="0" />
        <MediaElement Grid.Row="1" 
                      x:Name="mediaElement1" 
                      AreTransportControlsEnabled="True"
                      Stretch="Fill"/>
    </Grid>
    
</Page>

Por otro lado tenemos el código C# para lanzar el CameraCaptureUI y tomar el video:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Media.Capture;
using Windows.Media.Core;
using Windows.Media.Editing;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// La plantilla de elemento Página en blanco está documentada en http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409

namespace Proyecto34
{
    /// 
    /// Página vacía que se puede usar de forma independiente o a la que se puede navegar dentro de un objeto Frame.
    /// 
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            CameraCaptureUI camara1 = new CameraCaptureUI();
            camara1.VideoSettings.Format = CameraCaptureUIVideoFormat.Mp4;

            StorageFile archivoVideo1 = await camara1.CaptureFileAsync(CameraCaptureUIMode.Video);

            if (archivoVideo1 != null)
            {
                MediaComposition mediaComposition1 = new MediaComposition();
                MediaClip mediaClip1 = await MediaClip.CreateFromFileAsync(archivoVideo1);

                mediaComposition1.Clips.Add(mediaClip1);
                MediaStreamSource mediaStreamSource1 = mediaComposition1.GeneratePreviewMediaStreamSource(
                    (int)mediaElement1.ActualWidth,
                    (int)mediaElement1.ActualHeight);

                mediaElement1.SetMediaStreamSource(mediaStreamSource1);
            }
        }
    }

}

Los espacios de nombres siguientes son necesarios para capturar un video y luego procesarlo y visualizarlo en un control MediaElement:

using Windows.Media.Capture;
using Windows.Media.Core;
using Windows.Media.Editing;
using Windows.Storage;

El método de presión del botón debe ser asíncrono (async):

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
          ...
        }

Definimos un objeto llamado camara1 de la clase CameraCaptureUI:

            CameraCaptureUI camara1 = new CameraCaptureUI();

Definimos el formato de archivo a generar (En este ejemplo Mp4):

            camara1.VideoSettings.Format = CameraCaptureUIVideoFormat.Mp4;

Llamamos al método CaptureFileAsync y le pasamos en el parámetro que muestre la interfaz para la captura de video:

            StorageFile archivoVideo1 = await camara1.CaptureFileAsync(CameraCaptureUIMode.Video);

En este momento se visualiza la interfaz CameraCaptureUI para tomar el video:

CameraCaptureUI videos

Luego de haber capturado el video si se presiona el botón de aceptar el if siguiente se verifica verdadero:

            if (archivoVideo1 != null)
            {

Definimos un objeto de la clase MediaComposition:

                MediaComposition mediaComposition1 = new MediaComposition();

También creamos un objeto de la clase MediaClip pasando como parámetro el objeto de la clase StorageFile que contiene el video propiamente dicho:

                MediaClip mediaClip1 = await MediaClip.CreateFromFileAsync(archivoVideo1);

Añadimos el objeto de la clase MediaClip al objeto MediaComposition:

                mediaComposition1.Clips.Add(mediaClip1);

Definimos el ancho y alto del video:

                MediaStreamSource mediaStreamSource1 = mediaComposition1.GeneratePreviewMediaStreamSource(
                    (int)mediaElement1.ActualWidth,
                    (int)mediaElement1.ActualHeight);

Enlazamos el video definitivo con el control visual MediaElement que tiene por objeto mostrar el video en pantalla:

                mediaElement1.SetMediaStreamSource(mediaStreamSource1);

Este proyecto lo puede descargar en un zip desde este enlace :Proyecto34.zip

Retornar