Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Artikel ini menunjukkan kepada Anda cara menggunakan antarmuka IMediaEncodingProperties untuk mengatur resolusi dan kecepatan bingkai aliran pratinjau kamera dan foto dan video yang diambil. Ini juga menunjukkan cara memastikan bahwa rasio aspek tampilan pratinjau sesuai dengan media yang ditangkap.
Profil kamera menawarkan mekanisme tingkat yang lebih sederhana dan lebih tinggi untuk menemukan dan mengatur properti streaming kamera, tetapi tidak didukung untuk semua perangkat. Untuk informasi selengkapnya, lihat Profil kamera.
Menentukan apakah pratinjau dan aliran pengambilan independen
Pada beberapa perangkat, pin perangkat keras yang sama digunakan untuk pratinjau dan mengambil aliran. Pada perangkat ini, mengatur properti pengodean seperti format, resolusi, dan kecepatan bingkai pada salah satunya akan memengaruhi keduanya. Pada perangkat yang menggunakan pin perangkat keras yang berbeda untuk pengambilan dan pratinjau, properti dapat diatur untuk setiap aliran secara independen. Gunakan kode berikut untuk menentukan apakah pratinjau dan aliran pengambilan independen. Contoh ini menetapkan variabel global boolean yang dapat digunakan untuk mengalihkan perilaku aplikasi jika aliran dibagikan atau independen.
if (m_mediaCapture.MediaCaptureSettings.VideoDeviceCharacteristic == VideoDeviceCharacteristic.AllStreamsIdentical ||
m_mediaCapture.MediaCaptureSettings.VideoDeviceCharacteristic == VideoDeviceCharacteristic.PreviewRecordStreamsIdentical)
{
m_captureAndPreviewStreamsIdentical = true;
}
Kelas pembantu properti pengodean media
Membuat kelas pembantu sederhana untuk membungkus fungsionalitas antarmuka IMediaEncodingProperties memudahkan untuk memilih serangkaian properti pengodean yang memenuhi kriteria tertentu. Kelas pembantu ini sangat berguna karena perilaku berikut dari fitur properti pengodean:
Nota
Metode VideoDeviceController.GetAvailableMediaStreamProperties mengambil anggota enumerasi MediaStreamType , seperti VideoRecord atau Photo, dan mengembalikan daftar objek ImageEncodingProperties atau VideoEncodingProperties yang menyampaikan pengaturan pengodean streaming, seperti resolusi foto atau video yang diambil. Hasil panggilan GetAvailableMediaStreamProperties dapat mencakup ImageEncodingProperties atau VideoEncodingProperties terlepas dari nilai MediaStreamType yang ditentukan. Untuk alasan ini, Anda harus selalu memeriksa jenis setiap nilai yang dikembalikan dan mentransmisikannya ke jenis yang sesuai sebelum mencoba mengakses salah satu nilai properti.
Kelas pembantu yang ditentukan di bawah ini menangani pemeriksaan jenis dan transmisi untuk ImageEncodingProperties atau VideoEncodingProperties sehingga kode aplikasi Anda tidak perlu membedakan antara kedua jenis. Selain itu, kelas pembantu mengekspos properti untuk rasio aspek, kecepatan bingkai (hanya untuk properti pengodean video), dan nama yang mudah dipahami yang memudahkan penampilan properti pengodean di antarmuka pengguna (UI) Anda.
class StreamPropertiesHelper
{
private IMediaEncodingProperties _properties;
public StreamPropertiesHelper(IMediaEncodingProperties properties)
{
if (properties == null)
{
throw new ArgumentNullException(nameof(properties));
}
// This helper class only uses ImageEncodingProperties or VideoEncodingProperties
if (!(properties is ImageEncodingProperties) && !(properties is VideoEncodingProperties))
{
throw new ArgumentException("Argument is of the wrong type. Required: " + typeof(ImageEncodingProperties).Name
+ " or " + typeof(VideoEncodingProperties).Name + ".", nameof(properties));
}
// Store the actual instance of the IMediaEncodingProperties for setting them later
_properties = properties;
}
public uint Width
{
get
{
if (_properties is ImageEncodingProperties)
{
return (_properties as ImageEncodingProperties).Width;
}
else if (_properties is VideoEncodingProperties)
{
return (_properties as VideoEncodingProperties).Width;
}
return 0;
}
}
public uint Height
{
get
{
if (_properties is ImageEncodingProperties)
{
return (_properties as ImageEncodingProperties).Height;
}
else if (_properties is VideoEncodingProperties)
{
return (_properties as VideoEncodingProperties).Height;
}
return 0;
}
}
public uint FrameRate
{
get
{
if (_properties is VideoEncodingProperties)
{
if ((_properties as VideoEncodingProperties).FrameRate.Denominator != 0)
{
return (_properties as VideoEncodingProperties).FrameRate.Numerator /
(_properties as VideoEncodingProperties).FrameRate.Denominator;
}
}
return 0;
}
}
public double AspectRatio
{
get { return Math.Round((Height != 0) ? (Width / (double)Height) : double.NaN, 2); }
}
public IMediaEncodingProperties EncodingProperties
{
get { return _properties; }
}
public string GetFriendlyName(bool showFrameRate = true)
{
if (_properties is ImageEncodingProperties ||
!showFrameRate)
{
return Width + "x" + Height + " [" + AspectRatio + "] " + _properties.Subtype;
}
else if (_properties is VideoEncodingProperties)
{
return Width + "x" + Height + " [" + AspectRatio + "] " + FrameRate + "FPS " + _properties.Subtype;
}
return String.Empty;
}
}
Dapatkan daftar properti stream yang tersedia
Dapatkan daftar properti streaming yang tersedia untuk perangkat penangkap dengan mendapatkan VideoDeviceController untuk objek MediaCapture aplikasi Anda lalu memanggil GetAvailableMediaStreamProperties dan meneruskan salah satu nilai MediaStreamType , VideoPreview, VideoRecord, atau Foto. Dalam contoh ini, daftar objek StreamPropertiesHelper , yang ditentukan sebelumnya dalam artikel ini, dibuat untuk setiap nilai IMediaEncodingProperties yang dikembalikan dari GetAvailableMediaStreamProperties. Contoh ini mengurutkan properti yang dikembalikan berdasarkan resolusi terlebih dahulu lalu pada kecepatan bingkai.
Jika aplikasi Anda memiliki persyaratan resolusi atau kecepatan bingkai tertentu, Anda dapat memilih sekumpulan properti pengodean media secara terprogram. Aplikasi kamera umum akan mengekspos daftar properti yang tersedia di UI dan memungkinkan pengguna untuk memilih pengaturan yang diinginkan. ComboBoxItem dibuat untuk setiap item dalam daftar objek StreamPropertiesHelper dalam daftar. Konten diatur ke nama ramah yang dikembalikan oleh kelas pembantu dan tag diatur ke kelas pembantu itu sendiri sehingga dapat digunakan nanti untuk mengambil properti pengodean terkait. Setiap ComboBoxItem kemudian ditambahkan ke ComboBox yang ditentukan dalam UI.
private void bGetStreamProperties_Click(object sender, RoutedEventArgs e)
{
// Query all properties of the specified stream type
IEnumerable<StreamPropertiesHelper> allStreamProperties =
m_mediaCapture.VideoDeviceController.GetAvailableMediaStreamProperties(MediaStreamType.VideoRecord).Select(x => new StreamPropertiesHelper(x));
// Order them by resolution then frame rate
allStreamProperties = allStreamProperties.OrderByDescending(x => x.Height * x.Width).ThenByDescending(x => x.FrameRate);
// Populate the combo box with the entries
foreach (var property in allStreamProperties)
{
ComboBoxItem comboBoxItem = new ComboBoxItem();
comboBoxItem.Content = property.GetFriendlyName();
comboBoxItem.Tag = property;
cbStreamProperties.Items.Add(comboBoxItem);
}
}
Mengatur properti aliran yang diinginkan
Beri tahu pengontrol perangkat video untuk menggunakan properti pengodean yang Anda inginkan dengan memanggil SetMediaStreamPropertiesAsync, meneruskan nilai MediaStreamType yang menunjukkan apakah properti foto, video, atau pratinjau harus diatur. Contoh ini menggunakan ComboBox yang diisi dalam contoh dari bagian sebelumnya, tempat properti aliran media diambil dari properti tag dari item yang dipilih.
private async void bSetStreamProperties_Click(object sender, RoutedEventArgs e)
{
if (m_exclusiveCameraAccess)
{
var selectedItem = cbStreamProperties.SelectedItem as ComboBoxItem;
var encodingProperties = (selectedItem.Tag as StreamPropertiesHelper).EncodingProperties;
await m_mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.VideoPreview, encodingProperties);
}
}
Perhatikan bahwa aplikasi Anda harus memiliki kontrol eksklusif terhadap perangkat pengambilan untuk mengubah properti streaming media.
Sesuaikan rasio aspek untuk pratinjau dan aliran perekaman
Aplikasi kamera umum akan menyediakan UI bagi pengguna untuk memilih resolusi pengambilan video atau foto tetapi akan secara terprogram mengatur resolusi pratinjau. Ada beberapa strategi berbeda untuk memilih resolusi streaming pratinjau terbaik untuk aplikasi Anda:
Pilih resolusi pratinjau tertinggi yang tersedia, memungkinkan kerangka kerja UI melakukan penskalaan pratinjau yang diperlukan.
Pilih resolusi pratinjau yang paling dekat dengan resolusi pengambilan sehingga pratinjau menampilkan representasi terdekat dengan media yang ditangkap akhir.
Pilih resolusi pratinjau yang paling dekat dengan ukuran CaptureElement sehingga tidak ada lebih banyak piksel dari yang diperlukan melalui alur aliran pratinjau.
Nota
Dimungkinkan untuk mengatur perbandingan aspek yang berbeda pada beberapa perangkat untuk aliran pratinjau dan aliran tangkap kamera. Pemangkasan bingkai yang disebabkan oleh ketidakcocokan ini dapat mengakibatkan konten yang terdapat dalam media yang ditangkap namun tidak terlihat di pratinjau, menyebabkan pengalaman pengguna yang negatif. Sangat disarankan agar Anda menggunakan rasio aspek yang sama, dalam jendela toleransi kecil, untuk pratinjau dan menangkap aliran. Tidak masalah memiliki resolusi yang benar-benar berbeda yang diaktifkan untuk penangkapan dan pratinjau selama rasio aspek hampir sama.
Untuk memastikan bahwa aliran pengambilan foto atau video cocok dengan rasio aspek aliran pratinjau, contoh ini memanggil VideoDeviceController.GetMediaStreamProperties dan meneruskan nilai enum VideoPreview untuk meminta properti streaming saat ini untuk aliran pratinjau. Selanjutnya, jendela toleransi rasio aspek kecil didefinisikan agar kita dapat menyertakan rasio aspek yang tidak persis sama dengan aliran pratinjau, selama masih mirip. Selanjutnya, objek StreamPropertiesHelper dipilih di mana rasio aspek berada dalam rentang toleransi yang ditentukan dari stream pratinjau.
// Query all properties of the specified stream type
IEnumerable<StreamPropertiesHelper> allVideoProperties =
m_mediaCapture.VideoDeviceController.GetAvailableMediaStreamProperties(MediaStreamType.VideoRecord).Select(x => new StreamPropertiesHelper(x));
// Query the current preview settings
StreamPropertiesHelper previewProperties = new StreamPropertiesHelper(m_mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview));
// Get all formats that have the same-ish aspect ratio as the preview
// Allow for some tolerance in the aspect ratio comparison
const double ASPECT_RATIO_TOLERANCE = 0.015;
var matchingFormats = allVideoProperties.Where(x => Math.Abs(x.AspectRatio - previewProperties.AspectRatio) < ASPECT_RATIO_TOLERANCE);
// Order them by resolution then frame rate
allVideoProperties = matchingFormats.OrderByDescending(x => x.Height * x.Width).ThenByDescending(x => x.FrameRate);
// Clear out old entries and populate the video combo box with new matching entries
cbStreamProperties.Items.Clear();
foreach (var property in allVideoProperties)
{
ComboBoxItem comboBoxItem = new ComboBoxItem();
comboBoxItem.Content = property.GetFriendlyName();
comboBoxItem.Tag = property;
cbStreamProperties.Items.Add(comboBoxItem);
}
SnippetMatchPreviewAspectRatio
Windows developer