Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
In dit artikel wordt beschreven hoe u snel de preview-stream van de camera kunt weergeven op een XAML-pagina in een UWP-app (Universal Windows Platform). Als u een app maakt waarmee foto's en video's worden vastgelegd met de camera, moet u taken uitvoeren, zoals het afhandelen van de apparaat- en camerastand of het instellen van coderingsopties voor het vastgelegde bestand. Voor sommige app-scenario's wilt u misschien gewoon de preview-stream van de camera weergeven zonder dat u zich zorgen hoeft te maken over deze andere overwegingen. In dit artikel wordt beschreven hoe u dit doet met een minimum aan code. Houd er rekening mee dat u de preview-stream altijd correct moet afsluiten wanneer u hiermee klaar bent door de onderstaande stappen te volgen.
Zie voor informatie over het schrijven van een camera-app die foto's of video's vastlegt Basic-foto, video en audioopname met MediaCapture.
Mogelijkheidsdeclaraties toevoegen aan het app-manifest
Als u wilt dat uw app toegang krijgt tot de camera van een apparaat, moet u declareren dat uw app gebruikmaakt van de webcam en microfoon apparaatmogelijkheden.
Mogelijkheden toevoegen aan het app-manifest
- Open in Microsoft Visual Studio, in Solution Explorer, de ontwerpfunctie voor het toepassingsmanifest door te dubbelklikken op het item package.appxmanifest.
- Selecteer het tabblad Capaciteiten.
- Schakel het selectievakje in voor Webcam en het selectievakje voor Microfoon.
Een CaptureElement toevoegen aan uw pagina
Gebruik een CaptureElement om de preview-stream weer te geven op uw XAML-pagina.
<CaptureElement Name="PreviewControl" Stretch="Uniform"/>
MediaCapture gebruiken om de preview-stream te starten
Het object MediaCapture is de interface van uw app met de camera van het apparaat. Deze klasse is lid van de windows.Media.Capture-naamruimte. Het voorbeeld in dit artikel maakt ook gebruik van API's uit de Windows.ApplicationModel en System.Threading.Tasks naamruimten, naast de api's die zijn opgenomen in de standaardprojectsjabloon.
Voeg gebruiksrichtlijnen toe om de volgende naamruimten op te nemen in het .cs-bestand van uw pagina.
//MainPage.xaml.cs
using Windows.UI.Core;
using Windows.UI.Xaml.Navigation;
using Windows.Media.Capture;
using Windows.ApplicationModel;
using System.Threading.Tasks;
using Windows.System.Display;
using Windows.Graphics.Display;
Declareer een klasselidvariabele voor het MediaCapture--object en een booleaanse waarde om bij te houden of de camera momenteel een preview-versie heeft.
MediaCapture mediaCapture;
bool isPreviewing;
Declareer een variabele van het type DisplayRequest die worden gebruikt om ervoor te zorgen dat de weergave niet wordt uitgeschakeld terwijl het voorbeeld wordt uitgevoerd.
DisplayRequest displayRequest = new DisplayRequest();
Maak een helpermethode voor het starten van het cameravoorbeeld, genaamd StartPreviewAsync in dit voorbeeld. Afhankelijk van het scenario van uw app kunt u dit aanroepen vanuit de OnNavigatedTo gebeurtenis-handler die wordt aangeroepen wanneer de pagina wordt geladen, of wachten en de preview starten als reactie op UI-gebeurtenissen.
Maak een nieuw exemplaar van de MediaCapture-klasse en roep InitializeAsync- aan om het opnameapparaat te initialiseren. Deze methode kan mislukken op apparaten die bijvoorbeeld geen camera hebben, dus zou u deze vanuit een try-blok moeten aanroepen. Er wordt een UnauthorizedAccessException- gegenereerd wanneer u probeert de camera te initialiseren als de gebruiker cameratoegang heeft uitgeschakeld in de privacyinstellingen van het apparaat. U ziet deze uitzondering ook tijdens de ontwikkeling als u de juiste mogelijkheden niet hebt toegevoegd aan uw app-manifest.
Belangrijke Op sommige apparaatfamilies wordt een gebruikerstoestemmingsprompt weergegeven aan de gebruiker voordat uw app toegang krijgt tot de camera van het apparaat. Daarom moet u alleen MediaCapture.InitializeAsync aanroepen vanuit de hoofd-UI-thread. Het initialiseren van de camera vanuit een andere thread kan leiden tot een initialisatiefout.
Opmerking
Met Windows kunnen gebruikers toegang verlenen of weigeren tot de camera van het apparaat in Windows-instellingen, onder Privacy en beveiliging -> Camera. Bij het initialiseren van het opnameapparaat moeten apps controleren of ze toegang hebben tot de camera en het geval afhandelen waarbij de toegang wordt geweigerd door de gebruiker. Zie De privacy-instelling van de Windows-camera afhandelen voor meer informatie.
Verbind de MediaCapture- met de CaptureElement- door de eigenschap Source in te stellen. Start het voorbeeld door StartPreviewAsyncaan te roepen. Deze methode genereert een FileLoadException- als een andere app exclusief beheer heeft over het opnameapparaat. Zie de volgende paragraaf voor informatie over het monitoren van wijzigingen in exclusieve controle.
Roep RequestActive- aan om ervoor te zorgen dat het apparaat niet in de slaapstand gaat terwijl de preview wordt uitgevoerd. Stel ten slotte de eigenschap DisplayInformation.AutoRotationPreferences in op Liggend om te voorkomen dat de gebruikersinterface en de CaptureElement- draaien wanneer de gebruiker de apparaatstand wijzigt. Voor meer informatie over het afhandelen van apparaatstandwijzigingen, zie Apparaatstand afhandelen met MediaCapture.
private async Task StartPreviewAsync()
{
try
{
mediaCapture = new MediaCapture();
await mediaCapture.InitializeAsync();
displayRequest.RequestActive();
DisplayInformation.AutoRotationPreferences = DisplayOrientations.Landscape;
}
catch (UnauthorizedAccessException)
{
// This will be thrown if the user denied access to the camera in privacy settings
ShowMessageToUser("The app was denied access to the camera");
return;
}
try
{
PreviewControl.Source = mediaCapture;
await mediaCapture.StartPreviewAsync();
isPreviewing = true;
}
catch (System.IO.FileLoadException)
{
mediaCapture.CaptureDeviceExclusiveControlStatusChanged += _mediaCapture_CaptureDeviceExclusiveControlStatusChanged;
}
}
Omgaan met wijzigingen in exclusief beheer
Zoals aangegeven in de vorige sectie, genereert StartPreviewAsync- een FileLoadException- als een andere app exclusief beheer heeft over het opnameapparaat. Vanaf Windows 10 versie 1703 kunt u een handler registreren voor de gebeurtenis MediaCapture.CaptureDeviceExclusiveControlStatusChanged, die wordt gegenereerd wanneer de exclusieve controlestatus van het apparaat verandert. Controleer in de handler voor deze gebeurtenis de eigenschap MediaCaptureDeviceExclusiveControlStatusChangedEventArgs.Status om te zien wat de huidige status is. Als de nieuwe status is SharedReadOnlyAvailable, weet u dat u de preview momenteel niet kunt starten en mogelijk wilt u de gebruikersinterface bijwerken om de gebruiker te waarschuwen. Als de nieuwe status ExclusiveControlAvailableis, kunt u proberen het cameravoorbeeld opnieuw te starten.
private async void _mediaCapture_CaptureDeviceExclusiveControlStatusChanged(MediaCapture sender, MediaCaptureDeviceExclusiveControlStatusChangedEventArgs args)
{
if (args.Status == MediaCaptureDeviceExclusiveControlStatus.SharedReadOnlyAvailable)
{
ShowMessageToUser("The camera preview can't be displayed because another app has exclusive access");
}
else if (args.Status == MediaCaptureDeviceExclusiveControlStatus.ExclusiveControlAvailable && !isPreviewing)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
await StartPreviewAsync();
});
}
}
De preview-stream afsluiten
Wanneer u klaar bent met het gebruik van de preview-stream, moet u de stream altijd afsluiten en de bijbehorende resources correct verwijderen om ervoor te zorgen dat de camera beschikbaar is voor andere apps op het apparaat. De vereiste stappen voor het afsluiten van de preview-stream zijn:
- Als de camera momenteel een voorbeeld weergeeft, roept u StopPreviewAsync aan om de voorbeeldstream te stoppen. Er wordt een uitzondering gegenereerd als u StopPreviewAsync aanroept terwijl het voorbeeld niet wordt uitgevoerd.
- Stel de eigenschap Source van de CaptureElement- in op null. Gebruik CoreDispatcher.RunAsync om ervoor te zorgen dat deze aanroep wordt uitgevoerd op de UI-thread.
- Roep de methode MediaCapture object Dispose aan om het object vrij te geven. Gebruik opnieuw CoreDispatcher.RunAsync- om ervoor te zorgen dat deze aanroep wordt uitgevoerd op de UI-thread.
- Stel de MediaCapture-lidvariabele in op null.
- Roep RequestRelease- aan om toe te staan dat het scherm wordt uitgeschakeld wanneer het inactief is.
private async Task CleanupCameraAsync()
{
if (mediaCapture != null)
{
if (isPreviewing)
{
await mediaCapture.StopPreviewAsync();
}
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
PreviewControl.Source = null;
if (displayRequest != null)
{
displayRequest.RequestRelease();
}
mediaCapture.Dispose();
mediaCapture = null;
});
}
}
Sluit de preview-stream af wanneer de gebruiker van uw pagina weg navigeert door de methode OnNavigatedFrom te overschrijven.
protected async override void OnNavigatedFrom(NavigationEventArgs e)
{
await CleanupCameraAsync();
}
U moet ook de preview-stream correct afsluiten wanneer uw app wordt opgeschort. Hiervoor registreert u een handler voor de Application.Suspending gebeurtenis in de constructor van uw pagina.
public MainPage()
{
this.InitializeComponent();
Application.Current.Suspending += Application_Suspending;
}
Controleer eerst in de Suspenderen gebeurtenis-handler of de pagina wordt weergegeven binnen het Frame van de applicatie door het type van de pagina te vergelijken met de eigenschap CurrentSourcePageType. Als de pagina momenteel niet wordt weergegeven, zou de gebeurtenis OnNavigatedFrom al moeten zijn gegenereerd en zou de voorbeeldstream moeten zijn afgesloten. Als de pagina momenteel wordt weergegeven, moet u een SuspendingDeferral-object halen uit de gebeurtenisargumenten die aan de handler worden doorgegeven, om ervoor te zorgen dat het systeem uw app niet opschort totdat de preview-stream is afgesloten. Nadat u de stream hebt afgesloten, roept u de Complete-methode van de uitsteloproep aan om het systeem uw app te laten onderbreken.
private async void Application_Suspending(object sender, SuspendingEventArgs e)
{
// Handle global application events only if this page is active
if (Frame.CurrentSourcePageType == typeof(MainPage))
{
var deferral = e.SuspendingOperation.GetDeferral();
await CleanupCameraAsync();
deferral.Complete();
}
}