使用相機設定檔探索並選取相機功能
本文討論如何使用相機設定檔來探索及管理不同視訊擷取裝置的功能。 這包括各種工作,例如選取支援特定解析度或畫面播放速率的設定檔、支援同時存取多個相機的設定檔,以及支援 HDR 的設定檔。
注意
本文以使用 MediaCapture 進行基本相片、視訊和音訊的擷取中所討論的概念和程式碼為基礎,說明實作基本相片和視訊擷取的步驟。 建議您先熟悉該文章中的基本媒體擷取模式後,再繼續進行更進階的擷取案例。 本文中的程式碼假設您的應用程式已經有已正確初始化的 MediaCapture 執行個體。
關於相機設定檔
不同裝置上的相機支援不同的功能,包括一組支援的擷取解析度、視訊擷取的畫面播放速率,以及是否支援 HDR 或可變畫面播放速率擷取。 通用 Windows 平台 (UWP) 媒體擷取架構會將這組功能儲存在 MediaCaptureVideoProfileMediaDescription 中。 相機設定檔 (由 MediaCaptureVideoProfile 表示) 有三個媒體描述集合:一個用於相片擷取、一個用於視訊擷取,另一個則用於影片預覽。
在初始化 MediaCapture 物件之前,您可以查詢目前裝置上的擷取裝置,以查看支援的設定檔。 當您選取支援的設定檔時,您知道擷取裝置支援設定檔媒體描述中的所有功能。 這樣就不需要試用和錯誤方法來判斷特定裝置上支援哪些功能組合。
var mediaInitSettings = new MediaCaptureInitializationSettings { VideoDeviceId = cameraDevice.Id };
本文中的程式碼範例會以探索支援各種功能的相機設定檔來取代這個最小初始化,然後用來將媒體擷取裝置初始化。
尋找支援相機設定檔的視訊裝置
搜尋支援的相機設定檔之前,您應該會找到支援使用相機設定檔的擷取裝置。 下列範例中定義的 GetVideoProfileSupportedDeviceIdAsync 協助程式方法會使用 DeviceInformation.FindAllAsync 方法來擷取所有可用視訊擷取裝置的清單。 其會在清單中的所有裝置之間執行迴圈,呼叫靜態方法 (IsVideoProfileSupported) 讓每個裝置查看其是否支援視訊設定檔。 此外,每個裝置的 EnclosureLocation.Panel 屬性可讓您指定您想要相機在裝置正面還是背面。
如果在指定的面板中找到支援相機設定檔的裝置,則會傳回包含裝置識別碼字串 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 協助程式方法傳回的裝置識別碼為 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,以取得裝置支援的所有相機配置檔案清單。
此範例使用包含在使用 System.Linq 命名空間的 Linq 查詢方法中,以選取包含 SupportedRecordMediaDescription 物件的設定檔,其中 Width、Height 和 FrameRate 屬性符合要求的值。 如果找到相符項目,MediaCaptureInitializationSettings 的 VideoProfile 和 RecordMediaDescription 會設定為 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,以取得支援指定設定檔目前來源群組的所有視訊設定檔案清單,在此案例中為具有 WCG 相片的 HDR。 如果找到符合準則的設定檔,請建立新的 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 屬性是否為 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,以取得裝置支援的所有相機設定檔。 使用連結查詢來尋找至少有一個 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 值來擷取支援同時擷取的設定檔,但查詢所有設定檔將會提供更完整的結果。
相關主題