Поделиться через


Обнаружение и выбор возможностей камеры с помощью профилей камеры

В этой статье описывается, как использовать профили камер для обнаружения возможностей различных устройств захвата видео и управления ими. К ним относятся такие задачи, как выбор профилей, поддерживающих определенные разрешения или частоты кадров, профили, поддерживающие одновременный доступ к нескольким камерам и профилям, поддерживающим HDR.

Примечание.

В этой статье рассматриваются основные понятия и код, описанные в разделе "Базовый" фото, видео и аудиозапись с помощью MediaCapture, в котором описаны шаги по реализации базового фото и видеозахвата. Рекомендуется ознакомиться с основным шаблоном захвата мультимедиа в этой статье, прежде чем перейти к более сложным сценариям захвата. В коде этой статьи предполагается, что приложение уже имеет экземпляр MediaCapture, который был правильно инициализирован.

 

Сведения о профилях камеры

Камеры на разных устройствах поддерживают различные возможности, включая набор поддерживаемых разрешений захвата, частоту кадров для видеозахватов, а также поддерживаются ли записи hdR или переменной частоты кадров. Платформа отслеживания мультимедиа универсальная платформа Windows (UWP) сохраняет этот набор возможностей в MediaCaptureVideoProfileMediaDescription. Профиль камеры, представленный объектом MediaCaptureVideoProfile , содержит три коллекции описаний мультимедиа; один для захвата фотографий, один для захвата видео и другой для предварительного просмотра видео.

Перед инициализацией объекта MediaCapture можно запросить устройства записи на текущем устройстве, чтобы узнать, какие профили поддерживаются. При выборе поддерживаемого профиля известно, что устройство записи поддерживает все возможности в описаниях мультимедиа профиля. Это устраняет необходимость в пробном и ошибочном подходе к определению сочетаний возможностей, поддерживаемых на определенном устройстве.

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

Примеры кода в этой статье заменяют эту минимальную инициализацию на обнаружение профилей камер, поддерживающих различные возможности, которые затем используются для инициализации устройства захвата мультимедиа.

Поиск видеоустройства, поддерживающего профили камеры

Перед поиском поддерживаемых профилей камеры следует найти устройство захвата, которое поддерживает использование профилей камеры. Вспомогательный метод GetVideoProfileSupportedDeviceIdAsync, определенный в примере ниже, использует метод DeviceInformation.FindAllAsync для получения списка всех доступных устройств захвата видео. Он выполняет цикл по всем устройствам в списке, вызывая статический метод IsVideoProfileSupported, чтобы узнать, поддерживает ли он профили видео. Кроме того, свойство EnclosureLocation.Panel для каждого устройства позволяет указать, требуется ли камера на передней или задней части устройства.

Если устройство, поддерживающее профили камеры, найдено на указанной панели, возвращается значение идентификатора , содержащее строку идентификатора устройства.

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;
}

Если идентификатор устройства, возвращенный из вспомогательного метода GetVideoProfileSupportedDeviceIdAsync , имеет значение NULL или пустую строку, на указанной панели устройства, поддерживающей профили камеры. В этом случае необходимо инициализировать устройство захвата мультимедиа без использования профилей.

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

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

Выбор профиля на основе поддерживаемого разрешения и частоты кадров

Чтобы выбрать профиль с определенными возможностями, например с возможностью достижения определенного разрешения и частоты кадров, необходимо сначала вызвать вспомогательный метод, определенный выше, чтобы получить идентификатор устройства захвата, поддерживающего использование профилей камеры.

Создайте новый объект MediaCaptureInitializationSettings , передавая выбранный идентификатор устройства. Затем вызовите статический метод MediaCapture.FindAllVideoProfiles , чтобы получить список всех профилей камер, поддерживаемых устройством.

В этом примере используется метод запроса Linq, включенный в пространство имен System.Linq, для выбора профиля, содержащего объект SupportedRecordMediaDescription, где свойства Width, Height и FrameRate соответствуют запрошенным значениям. Если совпадение найдено, VideoProfile и RecordMediaDescription объекта MediaCaptureInitializationSettings задаются значения из анонимного типа, возвращаемого из запроса Linq. Если совпадение не найдено, используется профиль по умолчанию.


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];
}

После заполнения MediaCaptureInitializationSettings нужным профилем камеры просто вызовите InitializeAsync в объекте захвата мультимедиа, чтобы настроить его в нужном профиле.

await _mediaCapture.InitializeAsync(mediaInitSettings);

Получение профилей с помощью групп источников кадра мультимедиа

Начиная с Windows 10 версии 1803, можно использовать класс MediaFrameSourceGroup для получения профилей камер с определенными возможностями перед инициализацией объекта MediaCapture. Группы источников кадров позволяют производителям устройств представлять группы датчиков или возможностей захвата в виде одного виртуального устройства. Это позволяет вычислительным сценариям фотографии, таким как использование камер глубины и цвета вместе, но также можно использовать для выбора профилей камер для простых сценариев захвата. Дополнительные сведения об использовании MediaFrameSourceGroup см. в разделе "Обработка кадров мультимедиа" с помощью MediaFrameReader.

В приведенном ниже примере показано, как использовать объекты MediaFrameSourceGroup для поиска профиля камеры, поддерживающего известный профиль видео, например тот, который поддерживает последовательность фотографий HDR или переменной. Во-первых, вызовите MediaFrameSourceGroup.FindAllAsync , чтобы получить список всех групп источников кадров мультимедиа, доступных на текущем устройстве. Выполните цикл по каждой исходной группе и вызовите MediaCapture.FindKnownVideoProfiles , чтобы получить список всех профилей видео для текущей исходной группы, поддерживающей указанный профиль, в данном случае HDR с фотографией WCG. Если найден профиль, соответствующий критериям, создайте новый объект MediaCaptureInitializationSettings и задайте для объекта VideoProfile профиль выбора и VideoDeviceId свойству Id текущей исходной группы кадров мультимедиа. Например, можно передать значение KnownVideoProfile.HdrWithWcgVideo в этот метод, чтобы получить параметры захвата мультимедиа, поддерживающие видео HDR. Передайте knownVideoProfile.VariablePhotoSequence , чтобы получить параметры, поддерживающие последовательность фотографий переменных.

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;

    
}

Использование известных профилей для поиска профиля, поддерживающего видео HDR (устаревший метод)

Примечание.

API, описанные в этом разделе, устарели, начиная с Windows 10 версии 1803. См. предыдущий раздел: использование групп источников кадров мультимедиа для получения профилей.

Выбор профиля, поддерживающего HDR, начинается так же, как и в других сценариях. Создайте MediaCaptureInitializationSettings и строку для хранения идентификатора устройства записи. Добавьте логическую переменную, которая будет отслеживать, поддерживается ли видео HDR.

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

Используйте вспомогательный метод GetVideoProfileSupportedDeviceIdAsync , определенный выше, чтобы получить идентификатор устройства для устройства захвата, поддерживающего профили камеры.

// 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;
}

Статический метод MediaCapture.FindKnownVideoProfiles возвращает профили камер, поддерживаемые указанным устройством, классифицированным указанным значением KnownVideoProfile. Для этого сценария указано значение VideoRecording, чтобы ограничить возвращаемые профили камеры до тех, которые поддерживают запись видео.

Прокрутить возвращенный список профилей камеры. Для каждого профиля камеры выполните цикл по каждому параметру VideoProfileMediaDescription в проверке профиля, чтобы узнать, имеет ли значение свойство IsHdrVideoSupported. После обнаружения подходящего описания носителя разорвать цикл и назначить объекты профиля и описания объекту 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;
    }
}

Определение того, поддерживает ли устройство одновременную съемку фотографий и видео

Многие устройства поддерживают одновременное запись фотографий и видео. Чтобы определить, поддерживает ли устройство захвата это, вызовите MediaCapture.FindAllVideoProfiles , чтобы получить все профили камеры, поддерживаемые устройством. Используйте запрос ссылки, чтобы найти профиль, имеющий по крайней мере одну запись для supportedPhotoMediaDescription и SupportedRecordMediaDescription, что означает, что профиль поддерживает одновременный захват.

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;
}

Этот запрос можно уточнить, чтобы искать профили, поддерживающие определенные разрешения или другие возможности, помимо одновременной записи видео. Вы также можете использовать MediaCapture.FindKnownVideoProfiles и указать значение BalancedVideoAndPhoto для получения профилей, поддерживающих одновременную запись, но запросы всех профилей будут предоставлять более полные результаты.