Partager via


Capture photo, vidéo et audio de base avec MediaCapture dans une application WinUI 3

Cet article montre la façon la plus simple de capturer des photos et des vidéos à l’aide de la classe MediaCapture . La classe MediaCapture expose un ensemble robuste d’API qui fournissent un contrôle de bas niveau sur le pipeline de capture et activent des scénarios de capture avancés, mais cet article est destiné à vous aider à ajouter une capture multimédia de base à votre application rapidement et facilement. Pour en savoir plus sur les fonctionnalités fournies par MediaCapture , consultez Caméra.

Initialiser l’objet MediaCapture

Toutes les méthodes de capture décrites dans cet article nécessitent la première étape d’initialisation de l’objet MediaCapture . Cela inclut l’instanciation de l’objet, la sélection d’un appareil de capture, la définition des paramètres d’initialisation, puis l’appel d’InitializeAsync. En règle générale, les applications de caméra affichent l’aperçu de l’appareil photo lors de la capture de photos ou de vidéos dans leur interface utilisateur à l’aide de MediaPlayerElement. Pour obtenir une procédure pas à pas d’initialisation de MediaCapture et d’affichage de l’aperçu dans une interface utilisateur XAML, consultez Afficher l’aperçu de l’appareil photo dans une application WinUI. Les exemples de code de cet article supposent qu’une instance initialisée de MediaCapture a déjà été créée.

Capturer une photo dans un SoftwareBitmap

La classe SoftwareBitmap fournit une représentation commune des images sur plusieurs fonctionnalités. Si vous souhaitez capturer une photo, puis utiliser immédiatement l’image capturée dans votre application, par exemple l’afficher en XAML, au lieu de la capturer dans un fichier, vous devez effectuer une capture dans un SoftwareBitmap. Vous avez toujours la possibilité d’enregistrer l’image sur le disque ultérieurement.

Capturez une photo dans un SoftwareBitmap à l’aide de la classe LowLagPhotoCapture . Obtenez une instance de cette classe en appelant PrepareLowLagPhotoCaptureAsync, en passant un objet ImageEncodingProperties spécifiant le format d’image souhaité. CreateUncompressed crée un encodage non compressé avec le format de pixel spécifié. Lancez la capture de photos en appelant CaptureAsync, qui retourne un objet CapturedPhoto . Obtenez un SoftwareBitmap en accédant à la propriété Frame , puis à la propriété SoftwareBitmap .

Vous pouvez capturer plusieurs photos en appelant à plusieurs reprises CaptureAsync. Lorsque vous avez terminé la capture, appelez FinishAsync pour arrêter la session LowLagPhotoCapture et libérer les ressources associées. Après avoir appelé FinishAsync, pour commencer à capturer à nouveau des photos, vous devez appeler PrepareLowLagPhotoCaptureAsync pour réinitialiser la session de capture avant d’appeler CaptureAsync.

// 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();

Capturer une photo dans un flux de mémoire

Vous pouvez utiliser MediaCapture pour capturer une photo dans un flux en mémoire, que vous pouvez ensuite utiliser pour transcoder la photo du flux vers un fichier sur disque.

Créez un InMemoryRandomAccessStream puis appelez CapturePhotoToStreamAsync pour capturer une photo dans le flux, en passant le flux et un objet ImageEncodingProperties qui spécifie le format d'image à utiliser. Vous pouvez créer des propriétés d’encodage personnalisées en initialisant l’objet vous-même, mais la classe fournit des méthodes statiques, telles que ImageEncodingProperties.CreateJpeg pour les formats d’encodage courants.

Créez un BitmapDecoder pour décoder l’image à partir du flux de mémoire. Créez un BitmapEncoder pour encoder l’image dans un fichier en appelant CreateForTranscodingAsync.

Vous pouvez éventuellement créer un objet BitmapPropertySet , puis appeler SetPropertiesAsync sur l’encodeur d’image pour inclure des métadonnées sur la photo dans le fichier image. Pour plus d’informations sur les propriétés d’encodage, consultez métadonnées d’image.

Enfin, appelez FlushAsync sur l’objet encodeur pour transcoder la photo du flux en mémoire vers le fichier.

// 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();

Capture d’une vidéo

Ajoutez rapidement la capture vidéo à votre application à l’aide de la classe LowLagMediaRecording .

Tout d’abord, LowLagMediaRecording doit persister pendant que la vidéo est capturée, déclarez donc une variable de classe pour l’objet.

LowLagMediaRecording m_mediaRecording;

Appelez PrepareLowLagRecordToStorageFileAsync pour initialiser l’enregistrement multimédia, en passant le fichier de stockage et un objet MediaEncodingProfile spécifiant l’encodage de la vidéo. La classe fournit des méthodes statiques, comme CreateMp4, pour créer des profils d’encodage vidéo courants. Appelez StartAsync pour commencer à capturer la vidéo.

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();

Pour arrêter l’enregistrement de la vidéo, appelez StopAsync.

await m_mediaRecording.StopAsync();

Vous pouvez continuer à appeler StartAsync et StopAsync pour capturer des vidéos supplémentaires. Lorsque vous avez terminé la capture de vidéos, appelez FinishAsync pour supprimer la session de capture et nettoyer les ressources associées. Après cet appel, vous devez appeler à nouveau PrepareLowLagRecordToStorageFileAsync pour réinitialiser la session de capture avant d’appeler StartAsync.

await m_mediaRecording.FinishAsync();

Lors de la capture vidéo, vous devez inscrire un gestionnaire pour l’événement RecordLimitationExceeded de l’objet MediaCapture , qui sera déclenché par le système d’exploitation si vous dépassez la limite d’un enregistrement unique, actuellement trois heures. Dans le gestionnaire de l’événement, vous devez finaliser votre enregistrement en appelant StopAsync.

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

Vous pouvez suspendre un enregistrement vidéo, puis reprendre l’enregistrement sans créer de fichier de sortie distinct en appelant PauseAsync , puis en appelant ResumeAsync.

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

L’appel de PauseWithResultAsync renvoie un objet MediaCapturePauseResult . La propriété LastFrame est un objet VideoFrame représentant le dernier frame. Pour afficher le cadre en XAML, obtenez la représentation SoftwareBitmap de l’image vidéo. Actuellement, seules les images au format BGRA8 avec un canal alpha prémultiplié ou vide sont prises en charge. Appelez Convertir si nécessaire pour obtenir le format correct. PauseWithResultAsync retourne également la durée de la vidéo enregistrée dans le segment précédent au cas où vous devez suivre la durée totale enregistrée.

Vous pouvez également obtenir une image de résultat lorsque vous arrêtez la vidéo en appelant StopWithResultAsync.

Lire et modifier des fichiers vidéo capturés

Une fois que vous avez capturé une vidéo dans un fichier, vous pouvez charger le fichier et le lire dans l’interface utilisateur de votre application. Vous pouvez le faire à l’aide du contrôle XAML MediaPlayerElement et d’un MediaPlayer associé. Pour plus d’informations sur la lecture d’un média dans une page XAML, consultez Lire l’audio et la vidéo avec MediaPlayer.

Vous pouvez également créer un objet MediaClip à partir d’un fichier vidéo en appelant CreateFromFileAsync. Un MediaComposition fournit des fonctionnalités d’édition vidéo de base, telles que l’organisation de la séquence d’objets MediaClip , la suppression de la longueur vidéo, la création de couches, l’ajout de musique d’arrière-plan et l’application d’effets vidéo. Pour plus d’informations sur l’utilisation des compositions multimédias, consultez Compositions multimédias et édition.

Capturer l’audio

Vous pouvez rapidement ajouter une capture audio à votre application à l’aide de la même technique que celle indiquée ci-dessus pour capturer la vidéo. Appelez PrepareLowLagRecordToStorageFileAsync pour initialiser la session de capture, en passant le fichier et un MediaEncodingProfile généré dans cet exemple par la méthode statique CreateMp3 . Pour commencer l’enregistrement, appelez StartAsync.

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();

Appelez StopAsync pour arrêter l’enregistrement audio.

await m_mediaRecording.StopAsync();

Vous pouvez appeler StartAsync et StopAsync plusieurs fois pour enregistrer plusieurs fichiers audio. Lorsque vous avez terminé la capture audio, appelez FinishAsync pour supprimer la session de capture et nettoyer les ressources associées. Après cet appel, vous devez appeler à nouveau PrepareLowLagRecordToStorageFileAsync pour réinitialiser la session de capture avant d’appeler StartAsync.

Pour plus d’informations sur la détection lorsque le système modifie le niveau audio du flux de capture audio, consultez Détecter et répondre aux modifications au niveau audio par le système.