Partager via


Effets de la capture vidéo

Cette rubrique vous montre comment appliquer des effets à l’aperçu de la caméra et à enregistrer des flux vidéo et vous montre comment utiliser l’effet de stabilisation vidéo.

Remarque

Cet article repose sur les concepts et le code décrits dans Capture photo, vidéo et audio de base à l’aide de MediaCapture, qui décrit comment implémenter la capture photo et vidéo de base. Nous vous recommandons de vous familiariser avec le modèle de capture simple de contenu multimédia de cet article avant d’adopter des scénarios de capture plus avancés. Le code de cet article suppose que votre application a déjà une instance de MediaCapture qui a été correctement initialisée.

Ajout et suppression d’effets du flux vidéo de la caméra

Pour capturer ou afficher un aperçu vidéo à partir de l’appareil photo de l’appareil, vous utilisez l’objet MediaCapture, comme décrit dans La capture photo, vidéo et audio de base avec MediaCapture. Après avoir initialisé l’objet MediaCapture, vous pouvez ajouter un ou plusieurs effets vidéo à la préversion ou au flux de capture en appelant AddVideoEffectAsync, en passant un objet IVideoEffectDefinition représentant l’effet à ajouter et un membre de l’énumération MediaStreamType indiquant si l’effet doit être ajouté au flux d’aperçu de la caméra ou au flux d’enregistrement.

Remarque

Sur certains appareils, le flux d’aperçu et le flux de capture sont identiques, ce qui signifie que si vous spécifiez MediaStreamType.VideoPreview ou MediaStreamType.VideoRecord lorsque vous appelez AddVideoEffectAsync, l’effet est appliqué aux flux d’aperçu et d’enregistrement. Vous pouvez déterminer si les flux d’aperçu et d’enregistrement sont identiques sur l’appareil actuel en vérifiant la propriété VideoDeviceCharacteristic de l’objet MediaCaptureSettings pour l’objet MediaCapture. Si la valeur de cette propriété est VideoDeviceCharacteristic.AllStreamsIdentical ou VideoDeviceCharacteristic.PreviewRecordStreamsIdentical, les flux sont identiques et tous les effets que vous appliquez affectent l’autre.

L’exemple suivant ajoute un effet à la fois aux flux d’aperçu et d’enregistrement de l’appareil photo. Cet exemple illustre la vérification pour voir si les flux d’enregistrement et d’aperçu sont identiques.

if (mediaCapture.MediaCaptureSettings.VideoDeviceCharacteristic == VideoDeviceCharacteristic.AllStreamsIdentical ||
    mediaCapture.MediaCaptureSettings.VideoDeviceCharacteristic == VideoDeviceCharacteristic.PreviewRecordStreamsIdentical)
{
    // This effect will modify both the preview and the record streams, because they are the same stream.
    myRecordEffect = await mediaCapture.AddVideoEffectAsync(myEffectDefinition, MediaStreamType.VideoRecord);
}
else
{
    myRecordEffect = await mediaCapture.AddVideoEffectAsync(myEffectDefinition, MediaStreamType.VideoRecord);
    myPreviewEffect = await mediaCapture.AddVideoEffectAsync(myEffectDefinition, MediaStreamType.VideoPreview);
}

Notez que AddVideoEffectAsync retourne un objet qui implémente IMediaExtension qui représente l’effet vidéo ajouté. Certains effets vous permettent de modifier les paramètres d’effet en passant un PropertySet à la méthode SetProperties.

À compter de Windows 10 version 1607, vous pouvez également utiliser l’objet retourné par AddVideoEffectAsync pour supprimer l’effet du pipeline vidéo en le transmettant à RemoveEffectAsync. RemoveEffectAsync détermine automatiquement si le paramètre d’objet d’effet a été ajouté au flux d’aperçu ou d’enregistrement. Vous n’avez donc pas besoin de spécifier le type de flux lors de l’appel.

if (myRecordEffect != null)
{
    await mediaCapture.RemoveEffectAsync(myRecordEffect);
}
if(myPreviewEffect != null)
{
    await mediaCapture.RemoveEffectAsync(myPreviewEffect);
}

Vous pouvez également supprimer tous les effets du flux d’aperçu ou de capture en appelant ClearEffectsAsync et en spécifiant le flux pour lequel tous les effets doivent être supprimés.

await mediaCapture.ClearEffectsAsync(MediaStreamType.VideoPreview);
await mediaCapture.ClearEffectsAsync(MediaStreamType.VideoRecord);

Effet de stabilisation vidéo

L’effet de stabilisation vidéo manipule les images d’un flux vidéo afin de minimiser les tremblements causés par le maintien de l’appareil de capture dans votre main. Étant donné que cette technique entraîne le décalage des pixels vers la droite, la gauche, le haut et le bas, et parce que l’effet ne peut pas connaître le contenu juste en dehors de l’image vidéo, la vidéo stabilisée est rognée légèrement à partir de la vidéo d’origine. Une fonction utilitaire est fournie pour vous permettre d’ajuster vos paramètres d’encodage vidéo pour gérer de manière optimale le rognage effectué par l’effet.

Sur les appareils qui le prennent en charge, la stabilisation optique d’image (OIS) stabilise la vidéo en manipulant mécaniquement l’appareil de capture et, par conséquent, n’a pas besoin de rogner les bords des images vidéo. Pour plus d’informations, consultez Capture des contrôles d’appareil pour la capture vidéo.

Configurer votre application pour utiliser la stabilisation vidéo

Outre les espaces de noms requis pour la capture multimédia de base, l’utilisation de l’effet de stabilisation vidéo nécessite l’espace de noms suivant.

using Windows.Media.Core;
using Windows.Media.MediaProperties;
using Windows.Media.Effects;
using Windows.Media;

Déclarez une variable membre pour stocker l’objet VideoStabilizationEffect . Dans le cadre de l’implémentation de l’effet, vous allez modifier les propriétés d’encodage que vous utilisez pour encoder la vidéo capturée. Déclarez deux variables pour stocker une copie de sauvegarde des propriétés d’encodage d’entrée et de sortie initiales afin de pouvoir les restaurer ultérieurement lorsque l’effet est désactivé. Enfin, déclarez une variable membre de type MediaEncodingProfile , car cet objet est accessible à partir de plusieurs emplacements au sein de votre code.

private VideoStabilizationEffect _videoStabilizationEffect;
private VideoEncodingProperties _inputPropertiesBackup;
private VideoEncodingProperties _outputPropertiesBackup;
private MediaEncodingProfile _encodingProfile;

Pour ce scénario, vous devez affecter l’objet de profil d’encodage multimédia à une variable membre afin de pouvoir y accéder ultérieurement.

_encodingProfile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto);

Initialiser l’effet de stabilisation vidéo

Une fois que votre objet MediaCapture a été initialisé, créez une instance de l’objet VideoStabilizationEffectDefinition. Appelez MediaCapture.AddVideoEffectAsync pour ajouter l’effet au pipeline vidéo et récupérer une instance de la classe VideoStabilizationEffect. Spécifiez MediaStreamType.VideoRecord pour indiquer que l’effet doit être appliqué au flux d’enregistrement vidéo.

Inscrivez un gestionnaire d’événements pour l’événement EnabledChanged et appelez la méthode d’assistance SetUpVideoStabilizationRecommendationAsync, qui sont présentées plus loin dans cet article. Enfin, définissez la propriété Enabled de l’effet sur true pour activer l’effet.

// Create the effect definition
VideoStabilizationEffectDefinition stabilizerDefinition = new VideoStabilizationEffectDefinition();

// Add the video stabilization effect to media capture
_videoStabilizationEffect =
    (VideoStabilizationEffect)await mediaCapture.AddVideoEffectAsync(stabilizerDefinition, MediaStreamType.VideoRecord);

_videoStabilizationEffect.EnabledChanged += VideoStabilizationEffect_EnabledChanged;

await SetUpVideoStabilizationRecommendationAsync();

_videoStabilizationEffect.Enabled = true;

Comme indiqué précédemment dans cet article, la technique utilisée par l’effet de stabilisation vidéo entraîne nécessairement la rognage légèrement de la vidéo stabilisée à partir de la vidéo source. Définissez la fonction d’assistance suivante dans votre code pour ajuster les propriétés d’encodage vidéo afin de gérer de façon optimale cette limitation de l’effet. Cette étape n’est pas nécessaire pour utiliser l’effet de stabilisation vidéo, mais si vous n’effectuez pas cette étape, la vidéo résultante est légèrement mise à l’échelle et a donc une fidélité visuelle légèrement inférieure.

Appelez GetRecommendedStreamConfiguration sur votre instance d’effet de stabilisation vidéo, en passant l’objet VideoDeviceController, qui informe l’effet sur vos propriétés d’encodage de flux d’entrée actuelles et votre MediaEncodingProfile qui permet à l’effet de connaître vos propriétés d’encodage de sortie actuelles. Cette méthode retourne un objet VideoStreamConfiguration contenant de nouvelles propriétés d’encodage de flux d’entrée et de sortie recommandées.

Les propriétés d’encodage d’entrée recommandées sont, si elles sont prises en charge par l’appareil, une résolution plus élevée que les paramètres initiaux que vous avez fournis afin qu’il y ait une perte minimale de résolution après l’application du rognage de l’effet.

Appelez VideoDeviceController.SetMediaStreamPropertiesAsync pour définir les nouvelles propriétés d’encodage. Avant de définir les nouvelles propriétés, utilisez la variable membre pour stocker les propriétés d’encodage initiales afin de pouvoir modifier les paramètres lorsque vous désactivez l’effet.

Si l’effet de stabilisation vidéo doit rogner la vidéo de sortie, les propriétés d’encodage de sortie recommandées sont la taille de la vidéo rognée. Cela signifie que la résolution de sortie correspondra à la taille de vidéo rognée. Si vous n’utilisez pas les propriétés de sortie recommandées, la vidéo est mise à l’échelle pour correspondre à la taille de sortie initiale, ce qui entraîne une perte de fidélité visuelle.

Définissez la propriété Video de l’objet MediaEncodingProfile. Avant de définir les nouvelles propriétés, utilisez la variable membre pour stocker les propriétés d’encodage initiales afin de pouvoir modifier les paramètres lorsque vous désactivez l’effet.

private async Task SetUpVideoStabilizationRecommendationAsync()
{

    // Get the recommendation from the effect based on our current input and output configuration
    var recommendation = _videoStabilizationEffect.GetRecommendedStreamConfiguration(mediaCapture.VideoDeviceController, _encodingProfile.Video);

    // Handle the recommendation for the input into the effect, which can contain a larger resolution than currently configured, so cropping is minimized
    if (recommendation.InputProperties != null)
    {
        // Back up the current input properties from before VS was activated
        _inputPropertiesBackup = mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoRecord) as VideoEncodingProperties;

        // Set the recommendation from the effect (a resolution higher than the current one to allow for cropping) on the input
        await mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.VideoRecord, recommendation.InputProperties);
        await mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.VideoPreview, recommendation.InputProperties);
    }

    // Handle the recommendations for the output from the effect
    if (recommendation.OutputProperties != null)
    {
        // Back up the current output properties from before VS was activated
        _outputPropertiesBackup = _encodingProfile.Video;

        // Apply the recommended encoding profile for the output
        _encodingProfile.Video = recommendation.OutputProperties;
    }
}

Gérer l’effet de stabilisation vidéo désactivé

Le système peut désactiver automatiquement l’effet de stabilisation vidéo si le débit de pixels est trop élevé pour que l’effet soit géré ou s’il détecte que l’effet s’exécute lentement. Si cela se produit, l’événement EnabledChanged est déclenché. L’instance VideoStabilizationEffect dans le paramètre expéditeur indique le nouvel état de l’effet, activé ou désactivé. VideoStabilizationEffectEnabledChangedEventArgs a une valeur VideoStabilizationEffectEnabledChangedReason indiquant pourquoi l’effet a été activé ou désactivé. Notez que cet événement est également déclenché si vous activez ou désactivez l’effet par programmation, auquel cas la raison sera Programmatique.

En règle générale, vous utilisez cet événement pour ajuster l’interface utilisateur de votre application pour indiquer l’état actuel de la stabilisation vidéo.

private async void VideoStabilizationEffect_EnabledChanged(VideoStabilizationEffect sender, VideoStabilizationEffectEnabledChangedEventArgs args)
{
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        // Update your UI to reflect the change in status
        ShowMessageToUser("video stabilization status: " + sender.Enabled + ". Reason: " + args.Reason);
    });
}

Nettoyer l’effet de stabilisation vidéo

Pour nettoyer l’effet de stabilisation vidéo, appelez RemoveEffectAsync pour supprimer l’effet du pipeline vidéo. Si les variables membres contenant les propriétés d’encodage initiales ne sont pas null, utilisez-les pour restaurer les propriétés d’encodage. Enfin, supprimez le gestionnaire d’événements EnabledChanged et définissez l’effet sur Null.

// Clear all effects in the pipeline
await mediaCapture.RemoveEffectAsync(_videoStabilizationEffect);

// If backed up settings (stream properties and encoding profile) exist, restore them and clear the backups
if (_inputPropertiesBackup != null)
{
    await mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.VideoRecord, _inputPropertiesBackup);
    _inputPropertiesBackup = null;
}

if (_outputPropertiesBackup != null)
{
    _encodingProfile.Video = _outputPropertiesBackup;
    _outputPropertiesBackup = null;
}

_videoStabilizationEffect.EnabledChanged -= VideoStabilizationEffect_EnabledChanged;

_videoStabilizationEffect = null;