Share via


カメラ プロファイルを使用したカメラ機能の検出と選択

この記事では、カメラ プロファイルを使用して、さまざまなビデオ キャプチャ デバイスの機能を検出および管理する方法について説明します。 これには、特定の解像度またはフレーム レートをサポートするプロファイルの選択、複数のカメラへの同時アクセスをサポートするプロファイル、HDR をサポートするプロファイルなどのタスクが含まれます。

注意

この記事では、「MediaCapture を使用した基本的な写真、ビデオ、オーディオのキャプチャ」で説明されている概念とコードに基づいています。ここでは、基本的な写真とビデオのキャプチャを実装する手順について説明します。 より高度なキャプチャ シナリオに進む前に、その記事の基本的なメディア キャプチャ パターンについて理解しておくことをお勧めします。 この記事のコードでは、アプリに、適切に初期化された MediaCapture のインスタンスが既に存在することを前提としています。

 

カメラ プロファイルについて

さまざまなデバイス上のカメラでは、サポートされているキャプチャ解像度のセット、ビデオ キャプチャのフレーム レート、HDR キャプチャと可変フレーム レート キャプチャのどちらをサポートするかなど、さまざまな機能がサポートされています。 ユニバーサル Windows プラットフォーム (UWP) メディア キャプチャ フレームワークは、この一連の機能を MediaCaptureVideoProfileMediaDescription に格納します。 MediaCaptureVideoProfile オブジェクトによって表されるカメラ プロファイルには、3 つのメディア記述のコレクションがあります。1 つは写真キャプチャ用、もう 1 つはビデオ キャプチャ用、もう 1 つはビデオ プレビュー用です。

MediaCapture オブジェクトを初期化する前に、現在のデバイス上のキャプチャ デバイスに対してクエリを実行して、サポートされているプロファイルを確認できます。 サポートされているプロファイルを選択すると、キャプチャ デバイスがプロファイルのメディア説明のすべての機能をサポートしていることがわかります。 これにより、特定のデバイスでサポートされている機能の組み合わせを決定するための、試用版とエラーのアプローチが不要になります。

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

この記事のコードの例では、この最小限の初期化を、さまざまな機能をサポートするカメラ プロファイルの検出に置き換え、メディア キャプチャ デバイスの初期化に使用します。

カメラ プロファイルをサポートするビデオ デバイスを見つける

サポートされているカメラ プロファイルを検索する前に、カメラ プロファイルの使用をサポートするキャプチャ デバイスを見つける必要があります。 次の例で定義されている GetVideoProfileSupportedDeviceIdAsync ヘルパー メソッドでは、DeviceInformation.FindAllAsync メソッドを使って、すべての利用可能なビデオ キャプチャ デバイスの一覧を取得しています。 リスト内のすべてのデバイスをループし、静的メソッド IsVideoProfileSupported を呼び出して、デバイスごとにビデオ プロファイルをサポートしているかどうかを確認します。 各デバイスの EnclosureLocation.Panel プロパティでは、カメラがデバイスの前面と背面のどちらにあるかも指定できます。

指定したパネルでカメラ プロファイルをサポートするデバイスが見つかった場合は、デバイスの ID 文字列を含む Id 値が返されます。

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 ヘルパー メソッドから返されたデバイス ID が null または空の文字列の場合、指定されたパネルにカメラ プロファイルをサポートするデバイスはありません。 この場合は、プロファイルを使用せずにメディア キャプチャ デバイスを初期化する必要があります。

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

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

サポートされている解像度とフレーム レートに基づいてプロファイルを選択する

特定の解像度やフレーム レートを実現する機能など、特定の機能を持つプロファイルを選択するには、まず、上記で定義したヘルパー メソッドを呼び出して、カメラ プロファイルの使用をサポートするキャプチャ デバイスの ID を取得する必要があります。

選択したデバイス ID を渡して、新しい MediaCaptureInitializationSettings オブジェクトを作成します。 次に、MediaCapture.FindAllVideoProfiles 静的メソッドを呼び出して、デバイスでサポートされているすべてのカメラ プロファイルの一覧を取得します。

この例では、System.Linq 名前空間に含まれる Linq クエリ メソッドを使用して、WidthHeight、および FrameRate プロパティが要求された値と一致する SupportedRecordMediaDescription オブジェクトを含むプロファイルを選択します。 一致が見つかった場合は、MediaCaptureInitializationSettingsVideoProfileRecordMediaDescription が、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 オブジェクトを初期化する前に、特定の機能を備えたカメラ プロファイルを取得できます。 フレーム ソース グループを使用すると、デバイスの製造元はセンサーのグループを代表し、機能を 1 つの仮想デバイスとしてキャプチャしたりできます。 これにより、深度カメラとカラー カメラを一緒に使用するなどの計算撮影シナリオが可能になりますが、単純なキャプチャ シナリオではカメラ プロファイルを選択することもできます。 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 を作成し、キャプチャ デバイス ID を保持する文字列を作成します。 HDR ビデオがサポートされているかどうかを追跡するブール変数を追加します。

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

上記で定義した GetVideoProfileSupportedDeviceIdAsync ヘルパー メソッドを使用して、カメラ プロファイルをサポートするキャプチャ デバイスのデバイス ID を取得します。

// 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 プロパティが true かどうかを確認します。 適切なメディア記述が見つかったら、ループから抜け出し、プロファイル オブジェクトと説明オブジェクトを 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 呼び出して、デバイスでサポートされているすべてのカメラ プロファイルを取得します。 リンク クエリを使用して、SupportedPhotoMediaDescriptionSupportedRecordMediaDescription の両方に少なくとも 1 つのエントリがあるプロファイルを検索します。これは、プロファイルが同時キャプチャをサポートしていることを意味します。

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 値を指定して同時キャプチャをサポートするプロファイルを取得することもできますが、すべてのプロファイルに対してクエリを実行すると、より完全な結果が得られます。