Hoy voy a mostrar un ejemplo de como Silverlight 4 permite la integración de Cámaras Web y Micrófonos en las aplicaciones.
El espacio de Nombres que permite la captura de video es System.Windows.Media, y la clase CaptureSource que es la encargada de capturar el video y el audio.
Para empezar podemos crear un control Rectangle, que será el encargado de pintar el contenido del Video, gracias a la clase VisualBrush.
También adicionamos dos ListBox que mostrarán los dispositivos de audio y video instalados, agregamos 3 botones para Iniciar y Detener el Video, y otro para capturar las fotos.
Las fotos serán mostradas en un ScrollViewer.
La aplicación en modo de diseño queda así:
En el código, en cuánto carga la aplicación, buscamos los dispositivos disponibles y los adicionamos a los listBox:
public MainPage() { InitializeComponent(); listAudio.ItemsSource = CaptureDeviceConfiguration.GetAvailableAudioCaptureDevices(); listVideo.ItemsSource = CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices(); }
Si ejecutamos, vemos que no aparece el nombre del dispositivo, para eso se debe modificar el template de los items para mostrar la propiedad friendlyname de los dispositivos, en el XAML, los listbox quedan así:
<ListBox Height="157" HorizontalAlignment="Left" Margin="407,11,0,0" Name="listAudio" VerticalAlignment="Top" Width="245" > <ListBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding FriendlyName}"/> </DataTemplate> </ListBox.ItemTemplate> </ListBox>
Esto se hace para ambos ListBox.
Para mostrar el contenido del video, declaramos un objeto CaptureSource y asignamos un evento en el Botón iniciar que tendrá lo siguiente:
CaptureSource fuente;public MainPage() { InitializeComponent(); listAudio.ItemsSource = CaptureDeviceConfiguration.GetAvailableAudioCaptureDevices(); listVideo.ItemsSource = CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices(); fuente = new CaptureSource(); } private void button1_Click(object sender, RoutedEventArgs e) { if (fuente != null) { fuente.Stop(); fuente.VideoCaptureDevice = (VideoCaptureDevice)listVideo.SelectedItem; fuente.AudioCaptureDevice = (AudioCaptureDevice)listAudio.SelectedItem; VideoBrush videoBrush = new VideoBrush(); videoBrush.SetSource(fuente); rectVideo.Fill = videoBrush; if (CaptureDeviceConfiguration.AllowedDeviceAccess || CaptureDeviceConfiguration.RequestDeviceAccess()) { fuente.Start(); } } }
Primero se declara el objeto CaptureSource, luego cuando presionamos el botón Iniciar, se verifica que el objeto no sea nulo, para evitar excepciones, sí no es nulo entonces detenemos el la captura y asignamos los dispositivos, dependiendo de los items seleccionados en las listas de audio y video.
Declaramos el objeto VisualBrush y le asignamos como fuente el objeto CaptureSource, después llenamos el rectángulo, que en este caso se llama rectVideo.
Si ejecutamos en este momento no va a aparecer aún nada, debemos darle permisos a Silverlight para que pueda capturar el audio y el video, y cuando tengamos permiso, llamamos el método Start, que va a empezar a iniciar la cámara web y el audio:
El evento del botón detener es sencillo, ya que solo debemos verificar que el objeto CaptureSource no sea nulo, y llamar el método Stop:
if (fuente != null) { fuente.Stop(); }
Para tomar capturas del video, se llama el método Asincrónico CaptureImageAsync(), pero para eso se debe antes adicinar el evento CaptureImageCompleted al objeto CaptureSource, este evento retorna un objeto WriteableBitmap.
Para poder mostrar las imagenes en el ScrollViewer, he modificado el template para contener como items unos controles Image, luego asignar una colección de imagenes al ScrollViewer:
ScrollViewer:
<ScrollViewer Height="115" HorizontalAlignment="Left" Margin="21,407,0,0" Name="scrollViewer1" VerticalAlignment="Top" Width="631" VerticalScrollBarVisibility="Hidden" HorizontalScrollBarVisibility="Auto"> <ItemsControl x:Name="capturas" Background="{x:Null}"> <ItemsControl.ItemTemplate> <DataTemplate> <Image Source="{Binding}" Margin="5" Stretch="UniformToFill" Height="100"/> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center"/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ItemsControl> </ScrollViewer>
Código de captura de imagenes:
CaptureSource fuente; ObservableCollection<WriteableBitmap> imagenes = new ObservableCollection<WriteableBitmap>(); public MainPage() { InitializeComponent(); listAudio.ItemsSource = CaptureDeviceConfiguration.GetAvailableAudioCaptureDevices(); listVideo.ItemsSource = CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices(); fuente = new CaptureSource(); fuente.CaptureImageCompleted += new EventHandler<CaptureImageCompletedEventArgs>(fuente_CaptureImageCompleted); capturas.ItemsSource = imagenes; } void fuente_CaptureImageCompleted(object sender, CaptureImageCompletedEventArgs e) { imagenes.Add(e.Result); } private void TomarFoto_Click(object sender, RoutedEventArgs e) { if (fuente != null) { fuente.CaptureImageAsync(); } }
Ahora, cuando se ejecuta la aplicación podemos lo que muestra la cámara de video y tomar unas capturas.
Código Fuente en Microsoft Web Developer Express 2010 Aquí
Enlace: Accessing Web Cam and Microphone
Excelente aporte felicidades
hay alguna forma de hacer esto en una aplicacion de escritorio con wpf?
Hola, para hacerlo desde WPF hay que usar otros controles, por ejemplo en CodeProject esta este control que permite listar los dispositivos de video y audio, además permite grabar: http://www.codeproject.com/KB/WPF/WPF_WebcamControl.aspx
Hola q tal… probe tu codigo en mi lap y funciona bien… se enciende la webcam q tiene la laptop…. pero al conectar una webcam externa y correr el programa me marca error.. me dice: Un Componente Externo Produjo una Excepcion… la webcam q conecte es una Perfect Choice… no se si tendra algo q ver esa webcam.. ???
saludos
tengo una aplicacion en winform esta hecha con VS2008 ahorita la probe… y en esa aplicacion si me funciona la webcam externa y la de la laptop tambien
solo con el proyecto de silverlight ahi no me kiere detectar la webcam externa 😦 igual y yo pensaba q podria ser error de la webcam, pero como te mencione en el otro proyecto en winform si funciona bien… :S
muy bueno el aporte, solo queria preguntar si puedo guardar el video con cualquier tipo de extension en el disco duro
espero su respuesta gracias
Hola, para guardar el video en el disco duro, te recomiendo una ser de post, donde hay diferentes técnicas para guardar el video, una es guardando imagen por imagen, entre otras:
Video Avi con Audio: http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2009/12/30/silverlight-4-webcams-oncemorewithaudio.aspx
http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2009/12/28/silverlight-4-yet-more-on-capturing-video-from-webcams.aspx
http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2009/12/10/silverlight-4-more-on-capturing-video-from-webcams.aspx
http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2009/11/18/silverlight-4-rough-notes-camera-and-microphone-support.aspx
buen aporte pero necesito almacenar el video en cualquier formato alguien sabra como hacerlo¡? necesito ayuda mil gracias
espero su respuesta
Muchas gracias, ahora necesito enviar la foto capturada a un servidor por FTP, podrías darme alguna idea de como hacerlo?, gracias
Hola, pues una forma sería que crearas un web service que suba o baje archivos por FTP, y desde Silverlight invocar el webservice, el webservice puede recibir como parámetro un array de bytes.
Otra opción es la siguiente https://github.com/dittodhole/sharpLightFtp aunque no lo he probado.