Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In dieser Schnellstartanleitung erfahren Sie, wie Sie eine grundlegende WinUI 3-Kamera-App erstellen, die die Kameravorschau anzeigt. In einer WinUI 3-App verwenden Sie das MediaPlayerElement-Steuerelement im Microsoft.UI.Xaml.Controls-Namespace , um die Kameravorschau zu rendern, und die WinRT-Klasse MediaCapture , um auf den Kameravorschaustream des Geräts zuzugreifen. MediaCapture bietet APIs zum Ausführen einer Vielzahl von kamerabezogenen Aufgaben, z. B. zum Aufnehmen von Fotos und Videos und zum Konfigurieren des Gerätetreibers der Kamera. Weitere Informationen zu anderen MediaCapture-Funktionen finden Sie in den anderen Artikeln in diesem Abschnitt.
Der Code in dieser exemplarischen Vorgehensweise wurde aus dem MediaCapture WinUI 3-Beispiel auf github angepasst.
Tipp
Die UWP-Version dieses Artikels finden Sie unter Anzeigen der Kameravorschau in der UWP-Dokumentation.
Voraussetzungen
- Ihr Gerät muss den Entwicklermodus aktiviert haben. Weitere Informationen finden Sie unter "Einstellungen für Entwickler".
- Visual Studio 2022 oder höher mit der Workload WinUI-Anwendungsentwicklung .
Erstellen einer neuen WinUI 3-App
Erstellen Sie in Visual Studio ein neues Projekt. Legen Sie im Dialogfeld Neues Projekt erstellen den Sprachfilter auf "C#" und den Plattformfilter auf "Windows" fest, und wählen Sie dann die Projektvorlage "Leere App, verpackt (WinUI 3 auf dem Desktop)" aus.
Erstellen der Benutzeroberfläche
Die einfache Benutzeroberfläche für dieses Beispiel enthält ein MediaPlayerElement-Steuerelement zum Anzeigen der Kameravorschau, ein ComboBox , mit dem Sie aus den Kameras des Geräts auswählen können, und Schaltflächen zum Initialisieren der MediaCapture-Klasse , zum Starten und Beenden der Kameravorschau und zum Zurücksetzen des Beispiels. Wir fügen auch einen TextBlock für die Anzeige von Statusmeldungen hinzu.
Ersetzen Sie in der MainWindow.xml Datei Ihres Projekts das standardmäßige StackPanel-Steuerelement durch den folgenden XAML-Code.
<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>
Aktualisieren der MainWindow-Klassendefinition
Der Rest des Codes in diesem Artikel wird der MainWindow-Klassendefinition in der MainWindow.xaml.cs Datei Ihres Projekts hinzugefügt. Fügen Sie zunächst einige Klassenvariablen hinzu, die während der gesamten Lebensdauer des Fensters bestehen bleiben. Zu diesen Variablen gehören:
- Eine DeviceInformationCollection , die ein DeviceInformation-Objekt für jede verfügbare Kamera speichert. Das DeviceInformation-Objekt übermittelt Informationen wie den eindeutigen Bezeichner und den Anzeigenamen für die Kamera.
- Ein MediaCapture-Objekt , das Interaktionen mit dem ausgewählten Kameratreiber verarbeitet und Ihnen das Abrufen des Videostreams der Kamera ermöglicht.
- Ein MediaFrameSource-Objekt , das eine Quelle von Medienframes darstellt, z. B. einen Videostream.
- Ein boolescher Wert, der verfolgt werden soll, wenn die Kameravorschau ausgeführt wird. Einige Kameraeinstellungen können nicht geändert werden, während die Vorschau ausgeführt wird, daher empfiehlt es sich, den Status der Kameravorschau zu verfolgen.
private DeviceInformationCollection m_deviceList;
private MediaCapture m_mediaCapture;
private MediaFrameSource m_frameSource;
private MediaPlayer m_mediaPlayer;
private bool m_isPreviewing;
Füllen Sie die Liste der verfügbaren Kameras aus
Als Nächstes erstellen wir eine Hilfsmethode, um die Kameras zu erkennen, die auf dem aktuellen Gerät vorhanden sind, und füllen das ComboBox in der Benutzeroberfläche mit den Kameranamen auf, sodass der Benutzer eine Kamera für die Vorschau auswählen kann. Mit DeviceInformation.FindAllAsync können Sie viele verschiedene Arten von Geräten abfragen. Wir verwenden MediaDevice.GetVideoCaptureSelector , um den Bezeichner abzurufen, der angibt, dass wir nur Videoaufnahmegeräte abrufen möchten.
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;
}
}
Fügen Sie dem MainWindow-Klassenkonstruktor einen Aufruf dieser Hilfsmethode hinzu, damit das ComboBox beim Laden des Fensters aufgefüllt wird.
public MainWindow()
{
this.InitializeComponent();
PopulateCameraList();
}
MediaCapture-Objekt initialisieren
Initialisieren Sie das MediaCapture-Objekt , indem Sie InitializeAsync aufrufen und ein MediaCaptureInitializationSettings-Objekt übergeben, das die angeforderten Initialisierungsparameter enthält. Es gibt eine Vielzahl optionaler Initialisierungsparameter, die verschiedene Szenarien ermöglichen. Eine vollständige Liste finden Sie auf der API-Referenzseite. In diesem einfachen Beispiel geben wir einige grundlegende Einstellungen an, darunter:
- Die VideoDeviceId-Eigenschaft gibt den eindeutigen Bezeichner der Kamera an, an die MediaCapture angefügt wird. Wir rufen die Geräte-ID aus der DeviceInformationCollection ab, indem wir den ausgewählten Index der ComboBox verwenden.
- Die SharingMode-Eigenschaft gibt an, ob die App freigegebenen, schreibgeschützten Zugriff auf die Kamera anfordert, mit der Sie den Videostream anzeigen und aufnehmen können, oder die exklusive Steuerung der Kamera, mit der Sie die Kamerakonfiguration ändern können. Mehrere Apps können gleichzeitig von einer Kamera lesen, aber nur eine App gleichzeitig kann die exklusive Steuerung haben.
- Die StreamingCaptureMode-Eigenschaft gibt an, ob Video, Audio oder Audio und Video erfasst werden sollen.
- Die MediaCaptureMemoryPreference ermöglicht es uns, die spezifische Verwendung von CPU-Speicher für Videoframes anzufordern. Mit dem Wert Auto kann das System GPU-Speicher verwenden, wenn dieser verfügbar ist.
Vor dem Initialisieren des MediaCapture-Objekts rufen wir die AppCapability.CheckAccess-Methode auf, um zu ermitteln, ob der Benutzer unserer App in den Windows-Einstellungen den Zugriff auf die Kamera verweigert hat.
Hinweis
Windows ermöglicht Benutzern, unter "Datenschutz und Sicherheit –> Kamera" den Zugriff auf die Kamera des Geräts in den Windows-Einstellungen zu gewähren oder zu verweigern. Bei der Initialisierung des Aufnahmegeräts sollten Anwendungen prüfen, ob sie Zugriff auf die Kamera haben, und den Fall behandeln, dass der Zugriff vom Benutzer verweigert wird. Weitere Informationen finden Sie unter Behandeln der Datenschutzeinstellung der Windows-Kamera.
Der InitializeAsync-Aufruf erfolgt innerhalb eines try-Blocks , sodass eine Wiederherstellung möglich ist, wenn die Initialisierung fehlschlägt. Apps sollten Initialisierungsfehler ordnungsgemäß behandeln. In diesem einfachen Beispiel zeigen wir nur eine Fehlermeldung an, wenn ein Fehler auftritt.
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;
}
}
Initialisieren der Kameravorschau
Wenn der Benutzer auf die Schaltfläche Vorschau starten klickt, versuchen wir, eine MediaFrameSource für einen Videostream von dem Kameragerät zu erstellen, mit dem das MediaCapture-Objekt initialisiert wurde. Die verfügbaren Framequellen werden von der MediaCapture.FrameSources-Eigenschaft verfügbar gemacht.
Um eine Frame-Quelle zu finden, bei der es sich um Farbvideodaten handelt, im Gegensatz zu einer Tiefenkamera, suchen wir nach einer Frame-Quelle mit SourceKind of Color. Einige Kameratreiber bieten einen dedizierten Vorschau-Stream, der vom Datensatz-Stream getrennt ist. Um den Vorschauvideostream abzurufen, versuchen wir, eine Framequelle auszuwählen, die den MediaStreamTypeVideoPreview aufweist. Wenn keine Vorschaustreams gefunden werden, können wir den aufgezeichneten Videostream abrufen, indem wir einen MediaStreamType von VideoRecord auswählen. Wenn keine dieser Bildquellen verfügbar ist, kann dieses Aufnahmegerät nicht für die Videovorschau verwendet werden.
Nachdem wir eine Framequelle ausgewählt haben, erstellen wir ein neues MediaPlayer-Objekt , das vom MediaPlayerElement in der Benutzeroberfläche gerendert wird. Wir legen die Source-Eigenschaft des MediaPlayer auf ein neues MediaSource-Objekt fest, das wir aus der ausgewählten MediaFrameSource erstellen.
Rufen Sie die Wiedergabe für das MediaPlayer-Objekt auf, um mit dem Rendern des Videostreams zu beginnen.
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;
}
Implementieren Sie einen Handler für das MediaFailed-Ereignis , damit Sie Fehler beim Rendern der Vorschau behandeln können.
private void MediaPlayer_MediaFailed(MediaPlayer sender, MediaPlayerFailedEventArgs args)
{
tbStatus.Text = "MediaPlayer error: " + args.ErrorMessage;
}
Stoppen Sie die Kameravorschau
Um die Kameravorschau zu beenden, rufen Sie Pause für das MediaPlayer-Objekt auf.
private void bStopPreview_Click(object sender, RoutedEventArgs e)
{
// Stop preview
m_mediaPlayer.Pause();
m_isPreviewing = false;
bStartPreview.IsEnabled = true;
bStopPreview.IsEnabled = false;
}
Setzen Sie die App zurück
Um das Testen der Beispiel-App zu vereinfachen, fügen Sie eine Methode zum Zurücksetzen des Zustands der App hinzu. Kamera-Apps sollten die Kamera und die zugehörigen Ressourcen immer entsorgen, wenn die Kamera nicht mehr benötigt wird.
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