Descubrir y seleccionar las funcionalidades de cámara con los perfiles de cámara

En este artículo se describe cómo usar perfiles de cámara para detectar y administrar las funcionalidades de diferentes dispositivos de captura de vídeo. Esto incluye tareas como la selección de perfiles que admiten resoluciones específicas o velocidades de fotogramas, perfiles que admiten el acceso simultáneo con varias cámaras y perfiles que admiten HDR.

Nota:

Este artículo se basa en los conceptos y el código analizados en Captura básica de fotos, audio y vídeo con MediaCapture, donde se describen los pasos para implementar la captura básica de fotos y vídeo. Se recomienda que te familiarices con el patrón de captura de multimedia básico de ese artículo antes de pasar a escenarios más avanzados de captura. El código que encontrarás en este artículo se ha agregado suponiendo que la aplicación ya tiene una instancia de MediaCapture inicializada correctamente.

 

Acerca de los perfiles de cámara

Las cámaras en diferentes dispositivos admiten diferentes funcionalidades, como el conjunto de resoluciones de captura admitidas, la velocidad de fotogramas para las capturas de vídeo y la compatibilidad con las capturas con velocidad de fotogramas HDR o variable. El marco de captura multimedia de la Plataforma universal de Windows (UWP) almacena este conjunto de funcionalidades en un MediaCaptureVideoProfileMediaDescription. Un perfil de cámara, representado por un objeto MediaCaptureVideoProfile, tiene tres colecciones de descripciones multimedia; una para la captura de fotos, otra para la captura de vídeos y otra para la vista previa de vídeos.

Antes de inicializar el objeto MediaCapture, puede consultar los dispositivos de captura en el dispositivo actual para ver qué perfiles se admiten. Al seleccionar un perfil compatible, sabe que el dispositivo de captura admite todas las funcionalidades de las descripciones multimedia del perfil. Esto elimina la necesidad de un enfoque de ensayo y error para determinar qué combinaciones de funcionalidades se admiten en un dispositivo determinado.

var mediaInitSettings = new MediaCaptureInitializationSettings { VideoDeviceId = cameraDevice.Id };

Los ejemplos de código de este artículo reemplazan esta inicialización mínima por la detección de perfiles de cámara que admiten diversas funcionalidades, que posteriormente se usan para inicializar el dispositivo de captura multimedia.

Buscar un dispositivo de vídeo que admita perfiles de cámara

Antes de buscar perfiles de cámara compatibles, debe encontrar un dispositivo de captura que admita el uso de perfiles de cámara. El método auxiliar GetVideoProfileSupportedDeviceIdAsync definido en el ejemplo siguiente usa el método DeviceInformation.FindAllAsync para recuperar una lista de todos los dispositivos de captura de vídeo disponibles. Recorre en bucle todos los dispositivos de la lista, llamando al método estático, IsVideoProfileSupported, para cada dispositivo para ver si admite los perfiles de vídeo. Además, la propiedad EnclosureLocation.Panel para cada dispositivo le permite especificar si desea una cámara en la parte frontal o posterior del dispositivo.

Si se encuentra un dispositivo que admite perfiles de cámara en el panel especificado, se devuelve el valor de id., que contiene la cadena de identificador del dispositivo.

public async Task<string> GetVideoProfileSupportedDeviceIdAsync(Windows.Devices.Enumeration.Panel panel)
{
    string deviceId = string.Empty;

    // Finds all video capture devices
    DeviceInformationCollection devices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
    
    foreach (var device in devices)
    {
        // Check if the device on the requested panel supports Video Profile
        if (MediaCapture.IsVideoProfileSupported(device.Id) && device.EnclosureLocation.Panel == panel)
        {
            // We've located a device that supports Video Profiles on expected panel
            deviceId = device.Id;
            break;
        }
    }

    return deviceId;
}

Si el identificador de dispositivo devuelto desde el método auxiliar GetVideoProfileSupportedDeviceIdAsync es null o una cadena vacía, no hay ningún dispositivo en el panel especificado que admita perfiles de cámara. En este caso, debe inicializar el dispositivo de captura multimedia sin usar perfiles.

string videoDeviceId = await GetVideoProfileSupportedDeviceIdAsync(Windows.Devices.Enumeration.Panel.Back);

if (string.IsNullOrEmpty(videoDeviceId))
{
    // No devices on the specified panel support video profiles. .
    return;
}

Selección de un perfil basado en la resolución y la velocidad de fotogramas admitidas

Para seleccionar un perfil con funcionalidades concretas, como con la capacidad de lograr una resolución y una velocidad de fotogramas determinadas, primero debe llamar al método auxiliar definido anteriormente para obtener el identificador de un dispositivo de captura que admita el uso de perfiles de cámara.

Cree un nuevo objeto MediaCaptureInitializationSettings y pase el identificador de dispositivo seleccionado. A continuación, llame al método estático MediaCapture.FindAllVideoProfiles para obtener una lista de todos los perfiles de cámara compatibles con el dispositivo.

En este ejemplo se usa un método de consulta Linq, incluido en el uso del espacio de nombres System.Linq, para seleccionar un perfil que contenga un objeto SupportedRecordMediaDescription en el que las propiedades Width, Height y FrameRate coincidan con los valores solicitados. Si se encuentra una coincidencia, VideoProfile y RecordMediaDescription de mediaCaptureInitializationSettings se establecen en los valores del tipo anónimo devuelto desde la consulta Linq. Si no se encuentra ninguna coincidencia, se usa el perfil predeterminado.


var mediaInitSettings = new MediaCaptureInitializationSettings { VideoDeviceId = videoDeviceId };

IReadOnlyList<MediaCaptureVideoProfile> profiles = MediaCapture.FindAllVideoProfiles(videoDeviceId);

var match = (from profile in profiles
             from desc in profile.SupportedRecordMediaDescription
             where desc.Width == 640 && desc.Height == 480 && Math.Round(desc.FrameRate) == 30
             select new { profile, desc }).FirstOrDefault();

if (match != null)
{
    mediaInitSettings.VideoProfile = match.profile;
    mediaInitSettings.RecordMediaDescription = match.desc;
}
else
{
    // Could not locate a WVGA 30FPS profile, use default video recording profile
    mediaInitSettings.VideoProfile = profiles[0];
}

Después de rellenar MediaCaptureInitializationSettings con el perfil de cámara deseado, simplemente llame a InitializeAsync en el objeto de captura multimedia para configurarlo con el perfil deseado.

await _mediaCapture.InitializeAsync(mediaInitSettings);

Uso de grupos de origen de fotogramas multimedia para obtener perfiles

A partir de la versión 1803 de Windows 10, puede usar la clase MediaFrameSourceGroup para obtener perfiles de cámara con funcionalidades específicas antes de inicializar el objeto MediaCapture. Los grupos de origen de fotogramas permiten a los fabricantes de dispositivos representar grupos de sensores o funcionalidades de captura como un único dispositivo virtual. Esto permite escenarios de fotografía computacional, como el uso de cámaras de profundidad y color juntas, pero también se puede usar para seleccionar perfiles de cámara para escenarios de captura sencillos. Para obtener más información sobre el uso de MediaFrameSourceGroup, consulte Procesar fotogramas multimedia con MediaFrameReader.

El método de ejemplo siguiente muestra cómo usar objetos MediaFrameSourceGroup para buscar un perfil de cámara que admita un perfil de vídeo conocido, como uno que admita una secuencia de fotos HDR o variable. En primer lugar, llame a MediaFrameSourceGroup.FindAllAsync para obtener una lista de todos los grupos de orígenes de fotogramas multimedia disponibles en el dispositivo actual. Recorra en bucle cada grupo de origen y llame a MediaCapture.FindKnownVideoProfiles para obtener una lista de todos los perfiles de vídeo del grupo de origen actual que admiten el perfil especificado, en este caso HDR con foto WCG. Si se encuentra un perfil que cumpla los criterios, cree un nuevo objeto MediaCaptureInitializationSettings y establezca VideoProfile en el perfil seleccionado y VideoDeviceId en la propiedad de id. del grupo de origen de fotogramas multimedia actual. Así, por ejemplo, podría pasar el valor KnownVideoProfile.HdrWithWcgVideo a este método para obtener la configuración de captura multimedia que admite vídeo HDR. Pase KnownVideoProfile.VariablePhotoSequence para obtener la configuración que admite la secuencia de fotos variable.

private async Task<MediaCaptureInitializationSettings> GetKnownVideoProfile(KnownVideoProfile knownVideoProfile)
{
    IReadOnlyList<MediaFrameSourceGroup> sourceGroups = await MediaFrameSourceGroup.FindAllAsync();
    MediaCaptureInitializationSettings settings = null;

    foreach (MediaFrameSourceGroup sg in sourceGroups)
    {
        // Find a device that support VariablePhotoSequence
        IReadOnlyList<MediaCaptureVideoProfile> profileList = MediaCapture.FindKnownVideoProfiles(
                                      sg.Id,
                                      knownVideoProfile); // e.g. KnownVideoProfile.HdrWithWcgVideo

        if (profileList.Count > 0)
        {
            settings = new MediaCaptureInitializationSettings();
            settings.VideoProfile = profileList[0];
            settings.VideoDeviceId = sg.Id;
            break;
        }
    }
    return settings;

    
}

Uso de perfiles conocidos para encontrar un perfil que admita vídeo HDR (técnica heredada)

Nota:

Las API descritas en esta sección están en desuso a partir de la versión 1803 de Windows 10. Consulte la sección anterior, Uso de grupos de orígenes de fotogramas multimedia para obtener perfiles.

La selección de un perfil que admita HDR comienza como los demás escenarios. Cree un MediaCaptureInitializationSettings y una cadena que contenga el identificador de dispositivo de captura. Agregue una variable booleana que realizará un seguimiento de si se admite el vídeo HDR.

MediaCaptureInitializationSettings mediaInitSettings = new MediaCaptureInitializationSettings();
string videoDeviceId = string.Empty;
bool HdrVideoSupported = false;

Use el método auxiliar GetVideoProfileSupportedDeviceIdAsync definido anteriormente para obtener el identificador de dispositivo para un dispositivo de captura que admita perfiles de cámara.

// Select the first video capture device found on the back of the device
videoDeviceId = await GetVideoProfileSupportedDeviceIdAsync(Windows.Devices.Enumeration.Panel.Back);

if (string.IsNullOrEmpty(videoDeviceId))
{
    // No devices on the specified panel support video profiles. .
    return;
}

El método estático MediaCapture.FindKnownVideoProfiles devuelve los perfiles de cámara admitidos por el dispositivo especificado clasificado por el valor de KnownVideoProfile especificado. En este escenario, se especifica el valor de VideoRecording para limitar los perfiles de cámara devueltos a los que admiten la grabación de vídeo.

Recorra la lista de perfiles de cámara devuelta. Para cada perfil de cámara, recorra cada VideoProfileMediaDescription en la comprobación de perfiles para ver si la propiedad isHdrVideoSupported es true. Una vez que se encuentra una descripción de medios adecuada, divida el bucle y asigne los objetos profile y description al objeto MediaCaptureInitializationSettings.

IReadOnlyList<MediaCaptureVideoProfile> profiles =
    MediaCapture.FindKnownVideoProfiles(videoDeviceId, KnownVideoProfile.VideoRecording);

// Walk through available profiles, look for first profile with HDR supported Video Profile
foreach (MediaCaptureVideoProfile profile in profiles)
{
    IReadOnlyList<MediaCaptureVideoProfileMediaDescription> recordMediaDescription =
        profile.SupportedRecordMediaDescription;
    foreach (MediaCaptureVideoProfileMediaDescription videoProfileMediaDescription in recordMediaDescription)
    {
        if (videoProfileMediaDescription.IsHdrVideoSupported)
        {
            // We've located the profile and description for HDR Video, set profile and flag
            mediaInitSettings.VideoProfile = profile;
            mediaInitSettings.RecordMediaDescription = videoProfileMediaDescription;
            HdrVideoSupported = true;
            break;
        }
    }

    if (HdrVideoSupported)
    {
        // Profile with HDR support found. Stop looking.
        break;
    }
}

Determinar si un dispositivo admite la captura simultánea de fotos y vídeos

Muchos dispositivos admiten la captura simultánea de fotos y vídeos. Para determinar si un dispositivo de captura lo admite, llame a MediaCapture.FindAllVideoProfiles para obtener todos los perfiles de cámara compatibles con el dispositivo. Use una consulta de vínculo para buscar un perfil que tenga al menos una entrada para supportedPhotoMediaDescription y SupportedRecordMediaDescription, lo que significa que el perfil admite la captura simultánea.

var simultaneousPhotoAndVideoSupported = false;

IReadOnlyList<MediaCaptureVideoProfile> profiles = MediaCapture.FindAllVideoProfiles(videoDeviceId);

var match = (from profile in profiles
             where profile.SupportedPhotoMediaDescription.Any() &&
             profile.SupportedRecordMediaDescription.Any()
             select profile).FirstOrDefault();

if (match != null)
{
    // Simultaneous photo and video supported
    simultaneousPhotoAndVideoSupported = true;
}
else
{
    // Simultaneous photo and video not supported
    simultaneousPhotoAndVideoSupported = false;
}

Puede refinar esta consulta para buscar perfiles que admitan resoluciones específicas u otras funcionalidades además de la grabación simultánea de vídeo. También puede usar mediaCapture.FindKnownVideoProfiles y especificar el valor BalancedVideoAndPhoto para recuperar perfiles que admitan la captura simultánea, pero consultar todos los perfiles proporcionará resultados más completos.