Freigeben über


Einfache Foto-, Video- und Audioaufnahme mit "MediaCapture" in einer WinUI-App

In diesem Artikel wird die einfachste Möglichkeit zum Aufnehmen von Fotos und Videos mithilfe der MediaCapture-Klasse gezeigt. Die MediaCapture Klasse macht einen robusten Satz von APIs verfügbar, die die Steuerung der Aufnahmepipeline auf niedriger Ebene ermöglichen und erweiterte Aufnahmeszenarien ermöglichen. Dieser Artikel soll Ihnen jedoch helfen, Ihrer App schnell und einfach einfache Medienaufnahmen hinzuzufügen. Weitere Informationen zu den von MediaCapture bereitgestellten Features finden Sie unter "Kamera".

MediaCapture-Objekt initialisieren

Alle in diesem Artikel beschriebenen Aufnahmemethoden erfordern den ersten Schritt der Initialisierung des MediaCapture-Objekts . Dazu gehört das Instanziieren des Objekts, das Auswählen eines Aufnahmegeräts, das Festlegen von Initialisierungsparametern und das anschließende Aufrufen von InitializeAsync. In der Regel zeigen Kamera-Apps die Kameravorschau beim Aufnehmen von Fotos oder Videos in ihrer Benutzeroberfläche mithilfe des MediaPlayerElement an. Eine exemplarische Vorgehensweise zum Initialisieren von MediaCapture und anzeigen der Vorschau in einer XAML-Benutzeroberfläche finden Sie unter "Anzeigen der Kameravorschau" in einer WinUI-App. In den Codebeispielen in diesem Artikel wird davon ausgegangen, dass bereits eine initialisierte Instanz von MediaCapture erstellt wurde.

Aufnehmen eines Fotos als SoftwareBitmap

Die SoftwareBitmap-Klasse bietet eine gemeinsame Darstellung von Bildern über mehrere Features hinweg. Wenn Sie ein Foto aufnehmen und dann sofort das aufgenommene Bild in Ihrer App verwenden möchten, z. B. das Anzeigen in XAML, anstatt in einer Datei aufzunehmen, sollten Sie es in einer SoftwareBitmap aufnehmen. Sie haben weiterhin die Möglichkeit, das Image später auf dem Datenträger zu speichern.

Erfassen Sie ein Foto in einer SoftwareBitmap mit der LowLagPhotoCapture-Klasse . Rufen Sie eine Instanz dieser Klasse ab, indem Sie PrepareLowLagPhotoCaptureAsync aufrufen und ein ImageEncodingProperties-Objekt übergeben, das das gewünschte Bildformat angibt. CreateUncompressed erstellt eine nicht komprimierte Codierung mit dem angegebenen Pixelformat. Initiieren Sie die Fotoaufnahme durch Aufrufen von CaptureAsync, das ein CapturedPhoto-Objekt zurückgibt. Rufen Sie eine SoftwareBitmap ab, indem Sie auf die Frame-Eigenschaft und dann auf die SoftwareBitmap-Eigenschaft zugreifen.

Sie können mehrere Fotos aufnehmen, indem Sie CaptureAsync wiederholt aufrufen. Wenn Sie die Aufzeichnung abgeschlossen haben, rufen Sie FinishAsync auf, um die LowLagPhotoCapture-Sitzung zu beenden und die zugehörigen Ressourcen freizugeben. Nach dem Aufrufen von FinishAsync müssen Sie zum erneuten Aufnehmen von Fotos erneut PrepareLowLagPhotoCaptureAsync aufrufen, um die Aufnahmesitzung erneut zu initialisieren, bevor Sie CaptureAsync aufrufen.

// Prepare and capture photo
var lowLagCapture = await m_mediaCapture.PrepareLowLagPhotoCaptureAsync(ImageEncodingProperties.CreateUncompressed(MediaPixelFormat.Bgra8));

var capturedPhoto = await lowLagCapture.CaptureAsync();
var softwareBitmap = capturedPhoto.Frame.SoftwareBitmap;

// Capture more photos, if desired.
// Then call FinishAsync to clean up resources
await lowLagCapture.FinishAsync();

Ein Foto in einen Speicherstream aufnehmen.

Sie können MediaCapture verwenden, um ein Foto in einen Speicherdatenstrom aufzunehmen, mit dem Sie das Foto dann vom Datenstrom in eine Datei auf einem Datenträger transcodieren können.

Erstellen Sie einen InMemoryRandomAccessStream , und rufen Sie dann CapturePhotoToStreamAsync auf, um ein Foto an den Datenstrom zu erfassen, und übergeben Sie den Datenstrom und ein ImageEncodingProperties-Objekt , das das zu verwendende Bildformat angibt. Sie können benutzerdefinierte Codierungseigenschaften erstellen, indem Sie das Objekt selbst initialisieren, aber die Klasse stellt statische Methoden bereit, z. B. ImageEncodingProperties.CreateJpeg für gängige Codierungsformate.

Erstellen Sie einen BitmapDecoder , um das Bild aus dem Speicherdatenstrom zu decodieren. Erstellen Sie einen BitmapEncoder , um das Bild in eine Datei zu codieren, indem Sie CreateForTranscodingAsync aufrufen.

Sie können optional ein BitmapPropertySet-Objekt erstellen und dann SetPropertiesAsync für den Bildgeber aufrufen, um Metadaten zum Foto in die Bilddatei einzuschließen. Weitere Informationen zu Codierungseigenschaften finden Sie unter Bildmetadaten.

Rufen Sie schließlich FlushAsync für das Encoderobjekt auf, um das Foto aus dem Speicherdatenstrom in die Datei zu transcodieren.

// Prepare and capture photo
var lowLagCapture = await m_mediaCapture.PrepareLowLagPhotoCaptureAsync(ImageEncodingProperties.CreateUncompressed(MediaPixelFormat.Bgra8));

var capturedPhoto = await lowLagCapture.CaptureAsync();
var softwareBitmap = capturedPhoto.Frame.SoftwareBitmap;

// Capture more photos, if desired.
// Then call FinishAsync to clean up resources
await lowLagCapture.FinishAsync();

Aufnehmen eines Videos

Fügen Sie Ihrer App mithilfe der LowLagMediaRecording-Klasse schnell Videoaufnahmen hinzu.

Zunächst muss das LowLagMediaRecording beibehalten werden, während das Video aufgenommen wird. Deklarieren Sie also eine Klassenvariable für das Objekt.

LowLagMediaRecording m_mediaRecording;

Rufen Sie PrepareLowLagRecordToStorageFileAsync auf, um die Medienaufzeichnung zu initialisieren, und übergeben Sie die Speicherdatei und ein MediaEncodingProfile-Objekt , das die Codierung für das Video angibt. Die Klasse stellt statische Methoden wie CreateMp4 zum Erstellen gängiger Videocodierungsprofile bereit. Rufen Sie StartAsync auf, um mit der Videoaufnahme zu beginnen.

var myVideos = await Windows.Storage.StorageLibrary.GetLibraryAsync(Windows.Storage.KnownLibraryId.Videos);
StorageFile file = await myVideos.SaveFolder.CreateFileAsync("video.mp4", CreationCollisionOption.GenerateUniqueName);
m_mediaRecording = await m_mediaCapture.PrepareLowLagRecordToStorageFileAsync(
        MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto), file);

m_mediaCapture.RecordLimitationExceeded += m_mediaCapture_RecordLimitationExceeded;
await m_mediaRecording.StartAsync();

Rufen Sie "StopAsync" auf, um die Videoaufzeichnung zu beenden.

await m_mediaRecording.StopAsync();

Sie können startAsync und StopAsync weiterhin aufrufen, um zusätzliche Videos aufzunehmen. Wenn Sie mit der Aufnahme von Videos fertig sind, rufen Sie FinishAsync auf, um die Aufnahmesitzung zu löschen und die zugehörigen Ressourcen zu bereinigen. Nach diesem Aufruf müssen Sie PrepareLowLagRecordToStorageFileAsync erneut aufrufen, um die Aufnahmesitzung erneut zu initialisieren, bevor Sie StartAsync aufrufen.

await m_mediaRecording.FinishAsync();

Beim Aufzeichnen von Videos sollten Sie einen Handler für das RecordLimitationExceededed-Ereignis des MediaCapture-Objekts registrieren, das vom Betriebssystem ausgelöst wird, wenn Sie den Grenzwert für eine einzelne Aufzeichnung überschreiten, derzeit drei Stunden. Im Handler für das Ereignis sollten Sie die Aufzeichnung abschließen, indem Sie StopAsync aufrufen.

private async void m_mediaCapture_RecordLimitationExceeded(MediaCapture sender)
{
    await m_mediaRecording.StopAsync();
    DispatcherQueue.TryEnqueue(() =>
    {
        tbStatus.Text = "Record limitation exceeded.";
    });
}

Sie können eine Videoaufzeichnung anhalten und dann die Aufzeichnung fortsetzen, ohne eine separate Ausgabedatei zu erstellen, indem Sie PauseAsync aufrufen und dann ResumeAsync aufrufen.

await m_mediaRecording.PauseAsync(Windows.Media.Devices.MediaCapturePauseBehavior.ReleaseHardwareResources);
await m_mediaRecording.ResumeAsync();

Durch Aufrufen von PauseWithResultAsync wird ein MediaCapturePauseResult -Objekt zurückgegeben. Die LastFrame-Eigenschaft ist ein VideoFrame-Objekt , das den letzten Frame darstellt. Um den Frame in XAML anzuzeigen, rufen Sie die SoftwareBitmap-Darstellung des Videoframes ab. Derzeit werden nur Bilder im BGRA8-Format mit vorgemultipliziertem oder leerem Alphakanal unterstützt, rufen Sie bei Bedarf Convert auf, um das richtige Format zu erhalten. PauseWithResultAsync gibt auch die Dauer des Videos zurück, das im vorherigen Segment aufgezeichnet wurde, falls Sie nachverfolgen müssen, wie viel Gesamtzeit aufgezeichnet wurde.

Sie können auch einen Ergebnisframe abrufen, wenn Sie das Video beenden, indem Sie StopWithResultAsync aufrufen.

Wiedergeben und Bearbeiten aufgenommener Videodateien

Nachdem Sie ein Video in einer Datei aufgenommen haben, können Sie die Datei laden und in der Benutzeroberfläche Ihrer App wiedergeben. Dazu können Sie das MediaPlayerElement-XAML-Steuerelement und einen zugeordneten MediaPlayer verwenden. Informationen zum Wiedergeben von Medien auf einer XAML-Seite finden Sie unter "Wiedergeben von Audio und Video mit MediaPlayer".

[TBD - Wird das MediaComposition-Framework unterstützt/ für WinUI empfohlen?]

Sie können auch ein MediaClip-Objekt aus einer Videodatei erstellen, indem Sie CreateFromFileAsync aufrufen. Eine MediaComposition bietet grundlegende Videobearbeitungsfunktionen wie das Anordnen von MediaClip-Objekten , das Kürzen der Videolänge, das Erstellen von Ebenen, das Hinzufügen von Hintergrundmusik und das Anwenden von Videoeffekten. Weitere Informationen zum Arbeiten mit Medienkompositionen finden Sie unter "Medienkompositionen" und "Bearbeiten".

Audio aufnehmen

Sie können Ihrer App schnell Audioaufnahmen hinzufügen, indem Sie die oben gezeigte Technik zum Aufzeichnen von Videos verwenden. Rufen Sie PrepareLowLagRecordToStorageFileAsync auf, um die Aufnahmesitzung zu initialisieren, und übergeben Sie die Datei und ein MediaEncodingProfile , das in diesem Beispiel von der statischen CreateMp3-Methode generiert wird. Rufen Sie StartAsync auf, um mit der Aufzeichnung zu beginnen.

[TBD : Dieser Code wirft "Die Anforderung ist im aktuellen Zustand nicht gültig".]

m_mediaCapture.RecordLimitationExceeded += m_mediaCapture_RecordLimitationExceeded;

var myVideos = await Windows.Storage.StorageLibrary.GetLibraryAsync(Windows.Storage.KnownLibraryId.Videos);
StorageFile file = await myVideos.SaveFolder.CreateFileAsync("audio.mp3", CreationCollisionOption.GenerateUniqueName);
m_mediaRecording = await m_mediaCapture.PrepareLowLagRecordToStorageFileAsync(
        MediaEncodingProfile.CreateMp3(AudioEncodingQuality.High), file);
await m_mediaRecording.StartAsync();

Rufen Sie StopAsync auf, um die Audioaufzeichnung zu beenden.

await m_mediaRecording.StopAsync();

Sie können StartAsync und StopAsync mehrmals aufrufen, um mehrere Audiodateien aufzuzeichnen. Wenn Sie die Audioaufnahme abgeschlossen haben, rufen Sie FinishAsync auf, um die Aufnahmesitzung zu löschen und die zugehörigen Ressourcen zu bereinigen. Nach diesem Aufruf müssen Sie PrepareLowLagRecordToStorageFileAsync erneut aufrufen, um die Aufnahmesitzung erneut zu initialisieren, bevor Sie StartAsync aufrufen.

Informationen zum Erkennen, wann das System die Audioebene des Audioaufnahmedatenstroms ändert, finden Sie unter Erkennen und Reagieren auf Änderungen der Audioebene durch das System.