Captura de Webcam en C# Usando el SDK DirectShow .NET¶
Introducción¶
Esta guía demuestra cómo crear una aplicación de captura de webcam en C# usando el Video Capture SDK .Net con tecnología Microsoft DirectShow. DirectShow es un poderoso framework multimedia de Windows que permite a las aplicaciones controlar y procesar datos de audio y video desde varias fuentes, incluyendo webcams y cámaras USB.
El código fuente completo de la aplicación de ejemplo está disponible en el repositorio de GitHub.
Prerrequisitos¶
- Visual Studio 2019 o posterior
- Sistema operativo Windows 10 u 11
- Webcam u otro dispositivo de captura de video (cámara USB)
- Comprensión básica de programación en C#
Instalación¶
Consulta la guía de instalación principal para pasos detallados sobre cómo instalar el SDK DirectShow .NET en tu aplicación.
Componentes Clave¶
Clases Principales¶
VideoCaptureCore- Clase principal para capturar video desde un dispositivo fuenteVideoCaptureSource- Representa un dispositivo fuente de video (webcam, cámara)AudioCaptureSource- Representa un dispositivo de captura de audio (micrófono)
Guía de Implementación¶
1. Inicializar el Motor de Captura¶
El primer paso en cualquier aplicación DirectShow es crear el objeto principal de captura:
// Crear una nueva instancia con una vista de video
var captureCore = await VideoCaptureCore.CreateAsync(videoView as IVideoView);
// Registrar manejador de errores para desarrollo de aplicaciones robusto
captureCore.OnError += (sender, args) => {
Console.WriteLine($"Error: {args.Message}");
};
2. Enumeración y Selección de Dispositivos¶
Enumerar Dispositivos Disponibles¶
Para acceder a webcams y micrófonos, necesitas enumerar los dispositivos disponibles:
// Obtener fuentes de video
foreach (var item in captureCore.Video_CaptureDevices())
{
Console.WriteLine($"Dispositivo de video: {item.Name}");
// Listar formatos disponibles para este dispositivo
foreach (var format in item.VideoFormats)
{
Console.WriteLine($" Formato: {format}");
}
}
// Obtener fuentes de audio
foreach (var item in captureCore.Audio_CaptureDevices())
{
Console.WriteLine($"Dispositivo de audio: {item.Name}");
foreach (var format in item.Formats)
{
Console.WriteLine($" Formato: {format}");
}
}
Configurar Fuentes de Captura de Video y Audio¶
Este código de ejemplo muestra cómo filtrar y seleccionar formatos específicos de video y audio requeridos por tu aplicación:
// Encontrar y configurar fuente de video con formato específico
var videoDevices = captureCore.Video_CaptureDevices();
VideoCaptureSource selectedVideoDevice = null;
string targetVideoFormat = null;
// Encontrar un dispositivo con soporte 1280x720 MJPG
foreach (var item in videoDevices)
{
Console.WriteLine($"Verificando dispositivo de video: {item.Name}");
foreach (var format in item.VideoFormats)
{
Console.WriteLine($" Formato: {format}");
// Buscar formato 1280x720 MJPG
if (format.Contains("1280x720") && format.Contains("MJPG"))
{
selectedVideoDevice = item;
targetVideoFormat = format;
Console.WriteLine($" SELECCIONADO: {format}");
break;
}
}
if (selectedVideoDevice != null)
break;
}
// Encontrar y configurar fuente de audio con formato específico
var audioDevices = captureCore.Audio_CaptureDevices();
AudioCaptureSource selectedAudioDevice = null;
string targetAudioFormat = null;
// Encontrar un dispositivo con soporte 44100 Hz, 16 bit, 2 canales
foreach (var item in audioDevices)
{
Console.WriteLine($"Verificando dispositivo de audio: {item.Name}");
foreach (var format in item.Formats)
{
Console.WriteLine($" Formato: {format}");
// Buscar formato 44100 Hz, 16 bit, 2 canales
if (format.Contains("44100 Hz") && format.Contains("16 Bit") && format.Contains("2 Channel"))
{
selectedAudioDevice = item;
targetAudioFormat = format;
Console.WriteLine($" SELECCIONADO: {format}");
break;
}
}
if (selectedAudioDevice != null)
break;
}
// Configurar captura de video con el dispositivo y formato seleccionados
if (selectedVideoDevice != null)
{
captureCore.Video_CaptureDevice = new VideoCaptureSource(selectedVideoDevice.Name);
if (targetVideoFormat != null)
{
captureCore.Video_CaptureDevice.Format = targetVideoFormat;
captureCore.Video_CaptureDevice.Format_UseBest = false; // Usando formato específico
}
else
{
captureCore.Video_CaptureDevice.Format_UseBest = true; // Usar el mejor formato disponible
}
// Configurar tasa de fotogramas de video si es necesario
captureCore.Video_CaptureDevice.FrameRate = new VideoFrameRate(30.0);
}
else
{
Console.WriteLine("No se encontró dispositivo de video con 1280x720 MJPG.");
// Alternativa al primer dispositivo disponible con mejor formato
if (videoDevices.Count() > 0)
{
captureCore.Video_CaptureDevice = new VideoCaptureSource(videoDevices[0].Name);
captureCore.Video_CaptureDevice.Format_UseBest = true;
}
}
// Seleccionar dispositivo de captura de audio. Especificar el nombre del dispositivo y formato
if (selectedAudioDevice != null)
{
captureCore.Audio_CaptureDevice = new AudioCaptureSource(selectedAudioDevice.Name);
if (targetAudioFormat != null)
{
captureCore.Audio_CaptureDevice.Format = targetAudioFormat;
captureCore.Audio_CaptureDevice.Format_UseBest = false; // Usando formato específico
}
else
{
captureCore.Audio_CaptureDevice.Format_UseBest = true; // Establecer true para detectar el mejor formato automáticamente
}
}
else
{
Console.WriteLine("No se encontró dispositivo de audio con 44100 Hz, 16 bit, 2 canales.");
// Alternativa al primer dispositivo disponible
if (audioDevices.Count() > 0)
{
captureCore.Audio_CaptureDevice = new AudioCaptureSource(audioDevices[0].Name);
captureCore.Audio_CaptureDevice.Format_UseBest = true;
}
}
// Abrir diálogos de configuración del dispositivo si es necesario
// captureCore.Video_CaptureDevice_SettingsDialog_Show(IntPtr.Zero, captureCore.Video_CaptureDevice.Name);
// captureCore.Audio_CaptureDevice_SettingsDialog_Show(IntPtr.Zero, captureCore.Audio_CaptureDevice.Name);
3. Configurando Ajustes de Audio¶
Controla la grabación y reproducción de audio con estos ajustes:
// Habilitar grabación de audio
captureCore.Audio_RecordAudio = true;
// Habilitar reproducción de audio durante la captura
captureCore.Audio_PlayAudio = true;
// Configurar dispositivo de salida de audio
captureCore.Audio_OutputDevice = "Default DirectSound Device";
// Establecer volumen de audio (0-100)
captureCore.Audio_OutputDevice_Volume_Set(75);
// Establecer balance de audio (-100 a 100)
captureCore.Audio_OutputDevice_Balance_Set(0);
4. Configuración de Salida¶
Salida de Video MP4¶
Para guardar el video capturado en un archivo MP4, usa el siguiente código:
// Establecer modo de captura
captureCore.Mode = VideoCaptureMode.VideoCapture;
captureCore.Output_Filename = "salida.mp4";
// Configurar salida MP4 (CPU/QuickSync)
var mp4Output = new MP4Output
{
MP4Mode = MP4Mode.CPU_QSV,
AudioFormat = MP4AudioEncoder.AAC
};
// Configurar ajustes de audio AAC
mp4Output.Audio_AAC = new M4AOutput
{
Bitrate = 128,
Object = AACObject.Low,
Output = AACOutput.RAW,
Version = AACVersion.MPEG4
};
// O usar MP3 para audio (vía codificador LAME)
var mp3Output = new MP3Output();
mp4Output.Audio_LAME = mp3Output;
mp4Output.AudioFormat = MP4AudioEncoder.MP3_LAME;
// Configurar ajustes de video H.264
mp4Output.Video = new MP4OutputH264Settings
{
// Ajustes básicos
Bitrate = 3500,
MaxBitrate = 6000,
MinBitrate = 1500,
BitrateAuto = false,
// Perfil y nivel
Profile = H264Profile.ProfileMain,
Level = H264Level.Level41,
// Estructura de fotogramas
IDR_Period = 15, // Intervalo de I-frame en fotogramas
P_Period = 3, // Distancia entre fotogramas clave I o P (si es 1, sin B-frames)
// Ajustes de codificación
RateControl = H264RateControl.VBR,
MBEncoding = H264MBEncoding.CAVLC, // o CABAC para mejor compresión
TargetUsage = H264TargetUsage.Balanced,
Preset = H264Peset.Balanced,
// Otras opciones
Deblocking = true,
GOP = true,
PictureType = H264PictureType.Auto
};
// Asignar formato de salida
captureCore.Output_Format = mp4Output;
Codificación Acelerada por Hardware¶
Para aceleración por hardware usando GPU NVIDIA:
// Usar aceleración por hardware con NVENC
var mp4HWOutput = new MP4HWOutput
{
// Ajustes H264
Video = new MFVideoEncoderSettings
{
Codec = MFVideoEncoder.NVENC_H264, // o MS_H264, QSV_H264, AMD_H264
AvgBitrate = 3500,
MaxBitrate = 6000,
Profile = MFH264Profile.Main,
Level = MFH264Level.Level41,
RateControl = MFCommonRateControlMode.CBR,
CABAC = true,
QualityVsSpeed = 85,
MaxKeyFrameSpacing = 125
},
// Ajustes AAC
Audio = new M4AOutput
{
Bitrate = 128,
Object = AACObject.Low
}
};
captureCore.Output_Format = mp4HWOutput;
Formatos de Salida Personalizados¶
Para configuraciones de salida más avanzadas:
- Consulta la guía de Formatos de salida personalizados para más información.
5. Procesamiento de Video y Efectos¶
DirectShow permite el procesamiento de video a través de filtros. Aquí está cómo añadir varios efectos:
// Habilitar efectos de video
captureCore.Video_Effects_Enabled = true;
captureCore.Video_Effects_MergeImageLogos = true;
captureCore.Video_Effects_MergeTextLogos = true;
// Añadir efecto de escala de grises
var grayscale = new VideoEffectGrayscale(true);
captureCore.Video_Effects_Add(grayscale);
// Añadir efecto de contraste (0-200)
var contrast = new VideoEffectContrast(true, 50);
captureCore.Video_Effects_Add(contrast);
// Añadir efecto de brillo (0-200)
var lightness = new VideoEffectLightness(true, 50);
captureCore.Video_Effects_Add(lightness);
// Añadir efecto de saturación (0-255)
var saturation = new VideoEffectSaturation(120);
captureCore.Video_Effects_Add(saturation);
// Añadir efecto de oscuridad (0-200)
var darkness = new VideoEffectDarkness(true, 20);
captureCore.Video_Effects_Add(darkness);
// Añadir efecto de inversión de colores
var invert = new VideoEffectInvert(true);
captureCore.Video_Effects_Add(invert);
// Añadir efectos de volteo
var flipHorizontal = new VideoEffectFlipHorizontal(true);
captureCore.Video_Effects_Add(flipHorizontal);
var flipVertical = new VideoEffectFlipVertical(true);
captureCore.Video_Effects_Add(flipVertical);
Añadiendo Superposiciones¶
// Añadir logo de imagen
var imageLogo = new VideoEffectImageLogo(true, "MiLogo");
imageLogo.Filename = "logo.png"; // Ruta a tu imagen de logo
// Configurar propiedades del logo aquí
captureCore.Video_Effects_Add(imageLogo);
// Añadir logo de texto
var textLogo = new VideoEffectTextLogo(true, "MiLogoDeTexto");
textLogo.Text = "Mi Logo de Texto";
// Configurar propiedades del texto aquí
captureCore.Video_Effects_Add(textLogo);
// Añadir texto con desplazamiento
var scrollingText = new VideoEffectScrollingTextLogo(true);
// Configurar propiedades del texto aquí
captureCore.Video_Effects_Add(scrollingText);
Filtros DirectShow Personalizados¶
El poder de DirectShow viene de su arquitectura basada en filtros. Aquí está cómo añadir un filtro para procesamiento de video:
// Listar todos los filtros DirectShow disponibles
var filters = captureCore.DirectShow_Filters();
// Usar un filtro específico
var filter = filters.FirstOrDefault(f => f.Name == "MiFiltro");
captureCore.Video_Filters_Add(new CustomProcessingFilter(filter));
6. Control de Captura¶
Controla el flujo de medios con estos métodos simples:
// Establecer opciones de depuración si es necesario
captureCore.Debug_Mode = true;
captureCore.Debug_Dir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "VisioForge");
// Iniciar captura
await captureCore.StartAsync();
// Pausar captura
await captureCore.PauseAsync();
// Reanudar captura
await captureCore.ResumeAsync();
// Detener captura
await captureCore.StopAsync();
// Liberar cuando termine
captureCore.Dispose();
7. Tomando Capturas de Pantalla¶
Captura imágenes fijas de tu flujo de video:
// Tomar una captura y guardar como JPEG con calidad 85
await captureCore.Frame_SaveAsync("captura.jpg", ImageFormat.Jpeg, 85);
// Otros formatos soportados
await captureCore.Frame_SaveAsync("captura.png", ImageFormat.Png, 0);
await captureCore.Frame_SaveAsync("captura.bmp", ImageFormat.Bmp, 0);
await captureCore.Frame_SaveAsync("captura.gif", ImageFormat.Gif, 0);
await captureCore.Frame_SaveAsync("captura.tiff", ImageFormat.Tiff, 0);
Temas Avanzados¶
Para funcionalidad más avanzada del SDK DirectShow .NET, explora:
- Publicación de flujos en red
- Grabación multi-fuente
- Gráficos de filtros personalizados
- Manejo de eventos y notificaciones
- Edición de línea de tiempo
Solución de Problemas¶
Problemas comunes cuando trabajas con DirectShow en C#:
- Dispositivo ocupado o inaccesible: Asegúrate de que ninguna otra aplicación esté usando la webcam
- Compatibilidad de formato: No todos los formatos funcionan con todos los filtros y configuraciones de salida
- Fugas de memoria: Siempre libera los objetos DirectShow correctamente
- Problemas de controladores: Asegúrate de que los controladores de webcam/cámara estén actualizados
Conclusión¶
Este tutorial demuestra la funcionalidad principal necesaria para crear una aplicación de captura de video en C# usando el SDK DirectShow .NET. Con este framework, puedes construir aplicaciones que capturen, procesen y guarden video y audio desde varias fuentes como webcams y cámaras USB. La arquitectura DirectShow proporciona acceso a una amplia gama de capacidades de procesamiento multimedia a través de su diseño basado en filtros, haciéndolo una opción poderosa para aplicaciones multimedia de Windows.