[Windows Phone 7.5] Acceso a la Cámara (II)

Hola a todos!

En el anterior artículo vimos que Windows Phone 7.5 soporta dos apis distintas para trabajar con la cámara del dispositivo. Vimos a fondo como usar el api nativa de Windows Phone para sacar fotos con gran resolución, manejar el flash o el auto enfoque e incluso como usar los botones físicos de disparo del teléfono para sacar nuestra foto.

Pero no solo de imágenes estáticas se vive, también es interesante poder grabar videos (que incluyan audio) con nuestra aplicación. En Windows Phone esto lo conseguimos usando el api de webcam de Silverlight 4. Esto significa que si alguna vez has usado este api en la versión de escritorio de Silverlight, ya sabes usarla en Windows Phone y además el código te servirá sin ningún problema.

Grabando video y audio

En primer lugar vamos a crear una página con un layout básico que nos permita mostrar el video de la cámara, grabar, parar y reproducir:

<Grid>
    <Grid.Background>
        <VideoBrush x:Name="video"></VideoBrush>
    </Grid.Background>
        
    <StackPanel Orientation="Horizontal" Height="100" 
                HorizontalAlignment="Center"
                VerticalAlignment="Bottom"
                Margin="10" Background="#55CCCCCC">
        <Button Name="btnRec" Content="Rec" Width="150">
        </Button>
        <Button Name="btnStop" Content="Stop" Width="150">
        </Button>
        <Button Name="btnPlay" Content="Play" Width="150">
        </Button>
    </StackPanel>
</Grid>

Como podemos ver, vuelve a hacer acto de presencia el VideoBrush, que nos permitirá mostrar como background de la Grid el vídeo que capturemos de la cámara. En cuanto a diseño hemos terminado con nuestra aplicación. Vamos a ver el código que necesitamos ahora para aportarle la funcionalidad deseada.

Para comenzar vamos a crear una instancia del objeto CaptureSource, localizado en el namespace System.Windows.Media, que será el encargado de ofrecernos las fuentes de audio / video a utilizar y del objeto FileSink, del mismo namespace, encargado de ir guardando el video que grabemos en un archivo:

public partial class MainPage : PhoneApplicationPage
{
    CaptureSource source = new CaptureSource();
    FileSink file = new FileSink();
    // Constructor
    public MainPage()
    {
        InitializeComponent();
    }
}

A continuación tenemos que inicializar los dispositivos de audio y video que deseamos utilizar y establecer la fuente de video de nuestra VideoBrush:

void InitializeVideo()
{
    file = new FileSink();
    source = new CaptureSource();

    source.VideoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
    source.AudioCaptureDevice = CaptureDeviceConfiguration.GetDefaultAudioCaptureDevice();

    video.Stretch = Stretch.Uniform;
    video.SetSource(source);
}

Lo más importante de este método es la clase CaptureDeviceConfiguration. Nos ofrece dos métodos para audio y video: GetDefaultAudioCaptureDevice / GetDefaultVideoCaptureDevice, que usamos en este ejemplo para obtener los dispositivos de audio y video por defecto y GetAvailableAudioCaptureDevices y GetAvailableVideoCaptureDevices, que nos ofrecen todos los dispositivos de grabación que tenemos en el sistema para que podamos ofrecerlos al usuario. Esto es muy importante en el caso del video, pues ya empiezan a aparecer los primeros terminales Windows Phone con cámara frontal, por lo que podríamos ofrecer al usuario el uso de la cámara frontal o la cámara trasera y que el decida cual quiere asignar a la captura de video.

Ya solo nos queda llamar al método InitializeVideo desde el constructor de nuestra página, o desde el método OnNavigatedTo (Ten en cuenta que el constructor no se ejecuta cuando vuelves a una página desde el Tombstoning o el FAS, el OnNavigatedTo si lo hace), llamar al método Start() de nuestra instancia de CaptureSource e iniciar la aplicación en un terminal para obtener el primer resultado de nuestra nueva grabadora de video:

Screen Capture (12)

Ya tenemos gran parte del trabajo hecho. Un detalle que observaremos es que la fluidez del video que vemos en pantalla es mucho mayor que la obtenida con el método del primer artículo. Esto se debe principalmente a la calidad exigida a la cámara, que en este caso es mucho menor y nos ofrece entre 24 y 30 frames por segundo, dependiendo del modelo de teléfono que tengamos.

Ahora vamos a empezar a grabar cuando el usuario presione el botón “Rec”:

private void btnRec_Click(object sender, RoutedEventArgs e)
{
    source.Stop();
    file = new FileSink();
    file.CaptureSource = source;
    file.IsolatedStorageFileName = "video.mp4";
    source.Start();
}

En primer lugar paramos nuestra fuente de video usando el método Stop() del CaptureSource. Esto nos permite cambiar los parámetros de la instancia de FileSkink, al cual debemos asignar el CaptureSource a usar y el nombre de archivo para nuestro video (Es obligatorio usar la extensión MP4, de lo contrario obtendremos una preciosa InvalidOperationException al intentar asignar el nombre de archivo). Por último solo tenemos que volver a iniciar nuestra instancia de CaptureSource.

Para detener la grabación, simplemente llamamos al método InitializeVideo, que resetea el FileSink a una instancia nueva y por lo tanto deja de grabar:

private void btnStop_Click(object sender, RoutedEventArgs e)
{
    source.Stop();
    InitializeVideo();
    source.Start();
}

Algo que siempre hacemos es llamar al método Stop() del CaptureSource antes de cambiar propiedades, de lo contrario tendríamos problemas (de nuevo nuestra amiga InvalidOperationException) al intentar modificar el FileSkink, pues solo se permite su modificación cuando el CaptureSource está detenido.

Y ahora que hemos grabado un vídeo, podemos reproducirlo llamando al MediaPlayerLauncher:

private void btnPlay_Click(object sender, RoutedEventArgs e)
{
    MediaPlayerLauncher mplayer = new MediaPlayerLauncher();
    mplayer.Location = MediaLocationType.Data;
    mplayer.Media = new Uri("video.mp4", UriKind.Relative);
    mplayer.Show();
}

Y el resultado es que podremos ver nuestros videos directamente en el teléfono:

Screen Capture

 

Ya tenemos nuestra grabadora de vídeo terminada, no haremos la competencia a Red, pero ¿Y lo bien que nos lo hemos pasado?.

Algo que sería muy útil, pero que desgraciadamente no está soportado, es poder guardar estos vídeos en la librería multimedia o la galería del teléfono. Lamentablemente solo podemos guardar/obtener imágenes de ella así que la única opción para poder enviar estos vídeos fuera de nuestra aplicación pasa por subirlos a Skydrive u otro servicio de almacenamiento o crear un servicio web en el pc que sea capaz de recibir los vídeos. Tirón de orejas a los chicos de Windows Phone! Esperemos que en próximas versiones podamos guardar nuestros fantásticos vídeos caseros!

Conclusión

Y con esto terminamos nuestra mini serie de dos artículos. Como siempre, aquí tienes el código del ejemplo usado en el artículo. Espero que disfrutéis tanto leyéndolo como yo escribiéndolo y….

Happy Coding!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *