Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu hızlı başlangıçta, kamera önizlemesini görüntüleyen temel bir WinUI 3 kamera uygulaması oluşturmayı öğreneceksiniz. WinUI 3 uygulamasında, kamera önizlemesini işlemek için Microsoft.UI.Xaml.Controls ad alanında MediaPlayerElement denetimini ve cihazın kamera önizleme akışına erişmek için MediaCapture WinRT sınıfını kullanırsınız. MediaCapture , fotoğraf ve video yakalama ve kameranın cihaz sürücüsünü yapılandırma gibi kamerayla ilgili çok çeşitli görevleri gerçekleştirmek için API'ler sağlar. Diğer MediaCapture özellikleri hakkında ayrıntılı bilgi için bu bölümdeki diğer makalelere bakın.
Bu kılavuzdaki kod, github'daki MediaCapture WinUI 3 örneğinden uyarlanmıştır.
Tavsiye
Bu makalenin UWP sürümü için bkz. UWP belgelerinde kamera önizlemesini görüntüleme .
Önkoşullar
- Cihazınızda geliştirici modu etkinleştirilmiş olmalıdır. Daha fazla bilgi için bkz. Geliştiriciler için ayarlar.
- WinUI uygulama geliştirme iş yüküyle Visual Studio 2022 veya üzeri.
Yeni bir WinUI 3 uygulaması oluşturma
Visual Studio'da yeni bir proje oluşturun. Yeni proje oluştur iletişim kutusunda dil filtresini "C#" ve platform filtresini "Windows" olarak ayarlayın, ardından "Boş Uygulama, Paketlenmiş (masaüstünde WinUI 3)" proje şablonunu seçin.
Kullanıcı arabirimini oluşturma
Bu örneğin basit kullanıcı arabirimi kamera önizlemesini görüntülemek için bir MediaPlayerElement denetimi, cihazın kameralarından seçim yapmanızı sağlayan bir ComboBox ve MediaCapture sınıfını başlatma, kamera önizlemesini başlatma ve durdurma ve örneği sıfırlama düğmeleri içerir. Durum iletilerini görüntülemek için textblock da ekleriz.
Projenizin MainWindow.xml dosyasında, varsayılan StackPanel denetimini aşağıdaki XAML ile değiştirin.
<Grid ColumnDefinitions="4*,*" ColumnSpacing="4">
<MediaPlayerElement x:Name="mpePreview" Grid.Row="0" Grid.Column="0" AreTransportControlsEnabled="False" ManipulationMode="None"/>
<StackPanel Orientation="Vertical" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Top">
<TextBlock Text="Status:" Margin="0,0,10,0"/>
<TextBlock x:Name="tbStatus" Text=""/>
<TextBlock Text="Preview Source:" Margin="0,0,10,0"/>
<ComboBox x:Name="cbDeviceList" HorizontalAlignment="Stretch" SelectionChanged="cbDeviceList_SelectionChanged"></ComboBox>
<Button x:Name="bStartMediaCapture" Content="Initialize MediaCapture" IsEnabled="False" Click="bStartMediaCapture_Click"/>
<Button x:Name="bStartPreview" Content="Start preview" IsEnabled="False" Click="bStartPreview_Click"/>
<Button x:Name="bStopPreview" Content="Stop preview" IsEnabled="False" Click="bStopPreview_Click"/>
<Button x:Name="bReset" Content="Reset" Click="bReset_Click" />
</StackPanel>
</Grid>
MainWindow sınıf tanımını güncelleştirme
Bu makaledeki kodun geri kalanı projenizin MainWindow.xaml.cs dosyasındaki MainWindow sınıf tanımına eklenecektir. İlk olarak, pencerenin ömrü boyunca kalıcı olacak birkaç sınıf değişkeni ekleyin. Bu değişkenler şunlardır:
- Kullanılabilir her kamera için bir DeviceInformation nesnesi depolayacak olan DeviceInformationCollection. DeviceInformation nesnesi, benzersiz tanımlayıcı ve kameranın kolay adı gibi bilgileri iletir.
- Seçilen kameranın sürücüsüyle etkileşimleri işleyen ve kameranın video akışını almanıza olanak tanıyan bir MediaCapture nesnesi.
- Video akışı gibi bir medya çerçevesi kaynağını temsil eden bir MediaFrameSource nesnesi.
- Kamera önizlemesinin çalışıp çalışmadığını takip etmek için bir boolean değer. Önizleme çalışırken bazı kamera ayarları değiştirilemez, bu nedenle kamera önizlemesinin durumunu izlemek iyi bir uygulamadır.
private DeviceInformationCollection m_deviceList;
private MediaCapture m_mediaCapture;
private MediaFrameSource m_frameSource;
private MediaPlayer m_mediaPlayer;
private bool m_isPreviewing;
Kullanılabilir kameraların listesini doldurma
Ardından, geçerli cihazda bulunan kameraları algılamak ve kullanıcı arabirimindeki ComboBox'ı kamera adlarıyla doldurarak kullanıcının önizlemesi için bir kamera seçmesini sağlayan bir yardımcı yöntem oluşturacağız. DeviceInformation.FindAllAsync , birçok farklı cihaz türünü sorgulamanıza olanak tanır. MediaDevice.GetVideoCaptureSelector'ı yalnızca video yakalama cihazlarını almak istediğimizi belirten tanımlayıcıyı almak için kullanırız.
private async void PopulateCameraList()
{
cbDeviceList.Items.Clear();
m_deviceList = await DeviceInformation.FindAllAsync(MediaDevice.GetVideoCaptureSelector());
if(m_deviceList.Count == 0)
{
tbStatus.Text = "No video capture devices found.";
return;
}
foreach (var device in m_deviceList)
{
cbDeviceList.Items.Add(device.Name);
bStartMediaCapture.IsEnabled = true;
}
}
Pencere yüklendiğinde ComboBox'ın doldurulması için MainWindow sınıf oluşturucusunun bu yardımcı yöntemine bir çağrı ekleyin.
public MainWindow()
{
this.InitializeComponent();
PopulateCameraList();
}
MediaCapture nesnesini başlatma
İstenen başlatma parametrelerini içeren bir MediaCaptureInitializationSettings nesnesi geçirerek InitializeAsync'i çağırarak MediaCapture nesnesini başlatın. Farklı senaryoları etkinleştiren çok sayıda isteğe bağlı başlatma parametresi vardır. Tam liste için API başvuru sayfasına bakın. Bu basit örnekte aşağıdakiler dahil olmak üzere birkaç temel ayar belirteceğiz:
- VideoDeviceId özelliği, MediaCapture'ın iliştireceği kameranın benzersiz tanımlayıcısını belirtir. Cihaz kimliğini, ComboBox'ın seçili dizinini kullanarak DeviceInformationCollection'dan alacağız.
- SharingMode özelliği, uygulamanın kameraya paylaşılan, salt okunur erişim isteyip istemediğinizi belirtir. Bu, video akışını görüntülemenize ve yakalamanıza veya kamera yapılandırmasını değiştirmenize olanak tanıyan özel kamera denetimine olanak tanır. Birden çok uygulama aynı anda bir kameradan okuyabilir, ancak aynı anda yalnızca bir uygulama özel denetime sahip olabilir.
- StreamingCaptureMode özelliği, video, ses veya ses ve video yakalamak isteyip istemediğinizi belirtir.
- MediaCaptureMemoryPreference, video kareleri için özel olarak CPU belleği kullanma isteğinde bulunmamızı sağlar. Otomatik değeri, kullanılabilir durumdaysa sistemin GPU belleği kullanmasına izin verir.
MediaCapture nesnesini başlatmadan önce, kullanıcının Windows Ayarları'nda kameraya uygulama erişimimizi reddedip reddetmediğini belirlemek için AppCapability.CheckAccess yöntemini çağırırız.
Uyarı
Windows, kullanıcıların Gizlilik ve Güvenlik -> Kamera altındaki Windows Ayarları'nda cihazın kamerasına erişim izni vermesine veya erişimi reddetmesine izin verir. Yakalama cihazını başlatırken, uygulamaların kameraya erişimi olup olmadığını denetlemesi ve kullanıcı tarafından erişimin reddedildiği durumu işlemesi gerekir. Daha fazla bilgi için bkz . Windows kamera gizlilik ayarını işleme.
InitializeAsync çağrısı, başlatma başarısız olursa kurtarabilmemiz için bir deneme bloğunun içinden yapılır. Uygulamalar başlatma hatasını düzgün bir şekilde işlemelidir. Bu basit örnekte, hata durumunda yalnızca bir hata iletisi görüntüleyeceğiz.
private async void bStartMediaCapture_Click(object sender, RoutedEventArgs e)
{
if (m_mediaCapture != null)
{
tbStatus.Text = "MediaCapture already initialized.";
return;
}
// Supported in Windows Build 18362 and later
if(AppCapability.Create("Webcam").CheckAccess() != AppCapabilityAccessStatus.Allowed)
{
tbStatus.Text = "Camera access denied. Launching settings.";
bool result = await Windows.System.Launcher.LaunchUriAsync(new Uri("ms-settings:privacy-webcam"));
if (AppCapability.Create("Webcam").CheckAccess() != AppCapabilityAccessStatus.Allowed)
{
tbStatus.Text = "Camera access denied in privacy settings.";
return;
}
}
try
{
m_mediaCapture = new MediaCapture();
var mediaCaptureInitializationSettings = new MediaCaptureInitializationSettings()
{
VideoDeviceId = m_deviceList[cbDeviceList.SelectedIndex].Id,
SharingMode = MediaCaptureSharingMode.ExclusiveControl,
StreamingCaptureMode = StreamingCaptureMode.Video,
MemoryPreference = MediaCaptureMemoryPreference.Auto
};
await m_mediaCapture.InitializeAsync(mediaCaptureInitializationSettings);
tbStatus.Text = "MediaCapture initialized successfully.";
bStartPreview.IsEnabled = true;
}
catch (Exception ex)
{
tbStatus.Text = "Initialize media capture failed: " + ex.Message;
}
}
Kamera önizlemesini başlatma
Kullanıcı önizlemeyi başlat düğmesine tıkladığında, MediaCapture nesnesinin başlatıldığı kamera cihazından bir video akışı için MediaFrameSource oluşturmayı deneyeceğiz. Kullanılabilir çerçeve kaynakları MediaCapture.FrameSources özelliği tarafından kullanıma sunulur.
Örneğin derinlik kamerası yerine renkli video verileri olan bir çerçeve kaynağı bulmak için SourceKind of Color içeren bir çerçeve kaynağı arıyoruz. Bazı kamera sürücüleri, kayıt akışından ayrı bir ayrılmış önizleme akışı sağlar. Önizleme video akışını almak için MediaStreamType of VideoPreview içeren bir çerçeve kaynağı seçmeye çalışıyoruz. Önizleme akışları bulunamazsa, VideoRecord tipi bir MediaStreamType seçerek kayıt video akışını elde edebiliriz. Bu çerçeve kaynaklarından hiçbiri kullanılamıyorsa, bu yakalama cihazı video önizlemesi için kullanılamaz.
Bir çerçeve kaynağı seçtikten sonra, kullanıcı arabirimimizde MediaPlayerElement tarafından işlenecek yeni bir MediaPlayer nesnesi oluştururuz. MediaPlayer'ınSource özelliğini, seçtiğimiz MediaFrameSource'tan oluşturduğumuz yeni bir MediaSource nesnesine ayarladık.
Video akışını işlemeye başlamak için MediaPlayer nesnesinde Play'i çağırın.
private void bStartPreview_Click(object sender, RoutedEventArgs e)
{
m_frameSource = null;
// Find preview source.
// The preferred preview stream from a camera is defined by MediaStreamType.VideoPreview on the RGB camera (SourceKind == color).
var previewSource = m_mediaCapture.FrameSources.FirstOrDefault(source => source.Value.Info.MediaStreamType == MediaStreamType.VideoPreview
&& source.Value.Info.SourceKind == MediaFrameSourceKind.Color).Value;
if (previewSource != null)
{
m_frameSource = previewSource;
}
else
{
var recordSource = m_mediaCapture.FrameSources.FirstOrDefault(source => source.Value.Info.MediaStreamType == MediaStreamType.VideoRecord
&& source.Value.Info.SourceKind == MediaFrameSourceKind.Color).Value;
if (recordSource != null)
{
m_frameSource = recordSource;
}
}
if (m_frameSource == null)
{
tbStatus.Text = "No video preview or record stream found.";
return;
}
// Create MediaPlayer with the preview source
m_mediaPlayer = new MediaPlayer();
m_mediaPlayer.RealTimePlayback = true;
m_mediaPlayer.AutoPlay = false;
m_mediaPlayer.Source = MediaSource.CreateFromMediaFrameSource(m_frameSource);
m_mediaPlayer.MediaFailed += MediaPlayer_MediaFailed; ;
// Set the mediaPlayer on the MediaPlayerElement
mpePreview.SetMediaPlayer(m_mediaPlayer);
// Start preview
m_mediaPlayer.Play();
tbStatus.Text = "Start preview succeeded!";
m_isPreviewing = true;
bStartPreview.IsEnabled = false;
bStopPreview.IsEnabled = true;
}
Önizlemeyi işleme hatalarını işleyebilmeniz için MediaFailed olayı için bir işleyici uygulayın.
private void MediaPlayer_MediaFailed(MediaPlayer sender, MediaPlayerFailedEventArgs args)
{
tbStatus.Text = "MediaPlayer error: " + args.ErrorMessage;
}
Kamera önizlemesini durdurma
Kamera önizlemesini durdurmak için MediaPlayer nesnesinde Duraklat'ı çağırın.
private void bStopPreview_Click(object sender, RoutedEventArgs e)
{
// Stop preview
m_mediaPlayer.Pause();
m_isPreviewing = false;
bStartPreview.IsEnabled = true;
bStopPreview.IsEnabled = false;
}
Uygulamayı sıfırlama
Örnek uygulamanın testini kolaylaştırmak için uygulamanın durumunu sıfırlamak için bir yöntem ekleyin. Kamera artık gerekli olmadığında kamera uygulamaları her zaman kamerayı ve ilişkili kaynakları atmalıdır.
private void bReset_Click(object sender, RoutedEventArgs e)
{
if (m_mediaCapture != null)
{
m_mediaCapture.Dispose();
m_mediaCapture = null;
}
if(m_mediaPlayer != null)
{
m_mediaPlayer.Dispose();
m_mediaPlayer = null;
}
m_frameSource = null;
bStartMediaCapture.IsEnabled = false;
bStartPreview.IsEnabled = false;
bStopPreview.IsEnabled = false;
PopulateCameraList();
}
Windows developer