Effetti per l'acquisizione di videoEffects for video capture

In questo argomento viene illustrato come applicare effetti ai flussi di anteprima della fotocamera e di registrazione video e come usare l'effetto di stabilizzazione video.This topic shows you how to apply effects to the camera preview and recording video streams and shows you how to use the video stabilization effect.

Nota

Questo articolo è basato sui concetti e sul codice illustrati in Acquisizione di foto, video e audio di base con MediaCapture, in cui sono descritti i passaggi per l'implementazione delle funzionalità di acquisizione di foto e video di base.This article builds on concepts and code discussed in Basic photo, video, and audio capture with MediaCapture, which describes the steps for implementing basic photo and video capture. È consigliabile acquisire familiarità con il modello di acquisizione multimediale di base presentato in tale articolo prima di passare a scenari di acquisizione più avanzati.We recommend that you familiarize yourself with the basic media capture pattern in that article before moving on to more advanced capture scenarios. Il codice in questo articolo presuppone che l'app abbia già un'istanza di MediaCapture inizializzata correttamente.The code in this article assumes that your app already has an instance of MediaCapture that has been properly initialized.

Aggiunta e rimozione di effetti dal flusso video della fotocameraAdding and removing effects from the camera video stream

Per acquisire o visualizzare in anteprima un video dalla fotocamera del dispositivo, usi l'oggetto MediaCapture, come descritto in Acquisizione di foto, video e audio di base con MediaCapture.To capture or preview video from the device's camera, you use the MediaCapture object as described in Basic photo, video, and audio capture with MediaCapture. Dopo avere inizializzato l'oggetto MediaCapture, puoi aggiungere uno o più effetti video al flusso di anteprima o di acquisizione chiamando AddVideoEffectAsync e passando un oggetto IVideoEffectDefinition che rappresenta l'effetto da aggiungere e un membro dell'enumerazione MediaStreamType che indica se l'effetto deve essere aggiunto al flusso di anteprima o al flusso di record della fotocamera.After you have initialized the MediaCapture object, you can add one or more video effects to the preview or capture stream by calling AddVideoEffectAsync, passing in an IVideoEffectDefinition object representing the effect to be added, and a member of the MediaStreamType enumeration indicating whether the effect should be added to the camera's preview stream or the record stream.

Nota

In alcuni dispositivi il flusso di anteprima e il flusso di acquisizione coincidono, quindi se si specifica MediaStreamType.VideoPreview o MediaStreamType.VideoRecord quando si chiama AddVideoEffectAsync, l'effetto verrà applicato sia al flusso di anteprima che a quello di record.On some devices, the preview stream and the capture stream are the same, which means that if you specify MediaStreamType.VideoPreview or MediaStreamType.VideoRecord when you call AddVideoEffectAsync, the effect will be applied to both preview and record streams. Per determinare se i flussi di anteprima e di record coincidono nel dispositivo corrente, puoi controllare la proprietà VideoDeviceCharacteristic di MediaCaptureSettings per l'oggetto MediaCapture.You can determine whether the preview and record streams are the same on the current device by checking the VideoDeviceCharacteristic property of the MediaCaptureSettings for the MediaCapture object. Se il valore di questa proprietà è VideoDeviceCharacteristic.AllStreamsIdentical o VideoDeviceCharacteristic.PreviewRecordStreamsIdentical, significa che i flussi coincidono e che qualsiasi effetto applicato a uno verrà applicato anche all'altro.If the value of this property is VideoDeviceCharacteristic.AllStreamsIdentical or VideoDeviceCharacteristic.PreviewRecordStreamsIdentical, then the streams are the same and any effect you apply to one will affect the other.

L'esempio seguente aggiunge un effetto sia al flusso di anteprima che a quello di record della fotocamera.The following example adds an effect to both the camera preview and record streams. Questo esempio illustra come controllare se i flussi di anteprima e di record coincidono.This example illustrates checking to see if the record and preview streams are the same.

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

Tieni presente che AddVideoEffectAsync restituisce un oggetto che implementa IMediaExtension che rappresenta l'effetto video aggiunto.Note that AddVideoEffectAsync returns an object that implements IMediaExtension that represents the added video effect. Alcuni effetti ti consentono di modificare le impostazioni passando un PropertySet nel metodo SetProperties.Some effects allow you to change the effect settings by passing a PropertySet into the SetProperties method.

A partire da Windows 10, versione 1607, puoi anche usare l'oggetto restituito da AddVideoEffectAsync per rimuovere l'effetto dalla pipeline video passandolo in RemoveEffectAsync.Starting with Windows 10, version 1607, you can also use the object returned by AddVideoEffectAsync to remove the effect from the video pipeline by passing it into RemoveEffectAsync. Dato che RemoveEffectAsync determina automaticamente se il parametro dell'oggetto effetto è stato aggiunto al flusso di anteprima o di record, non hai bisogno di specificare il tipo di flusso quando esegui la chiamata.RemoveEffectAsync automatically determines whether the effect object parameter was added to the preview or record stream, so you don't need to specify the stream type when making the call.

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

Puoi anche rimuovere tutti gli effetti dal flusso di anteprima o di acquisizione chiamando ClearEffectsAsync e specificando il flusso per cui rimuovere tutti gli effetti.You can also remove all effects from the preview or capture stream by calling ClearEffectsAsync and specifying the stream for which all effects should be removed.

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

Effetto di stabilizzazione videoVideo stabilization effect

L'effetto di stabilizzazione video manipola i fotogrammi di un flusso video in modo da ridurre al minimo i movimenti causati dall'impugnare il dispositivo di acquisizione.The video stabilization effect manipulates the frames of a video stream to minimize shaking caused by holding the capture device in your hand. Poiché questa tecnica determina lo spostamento dei pixel a destra, a sinistra, verso l'alto o verso il basso, e dato che l'effetto non può conoscere gli elementi esterni al fotogramma, il video stabilizzato viene leggermente ritagliato rispetto al video originale.Because this technique causes the pixels to be shifted right, left, up, and down, and because the effect can't know what the content just outside the video frame is, the stabilized video is cropped slightly from the original video. Viene fornita una funzione di utilità che consente di regolare le impostazioni di codifica dei video in modo da gestire in modo ottimale il ritaglio applicato dall'effetto.A utility function is provided to allow you to adjust your video encoding settings to optimally manage the cropping performed by the effect.

Sui dispositivi che la supportano, la funzione di stabilizzazione ottica delle immagini (OIS, Optical Image Stabilization) consente di stabilizzare i video manipolando meccanicamente il dispositivo di acquisizione. In questo caso, non è pertanto necessario ritagliare i bordi dei fotogrammi del video.On devices that support it, Optical Image Stabilization (OIS) stabilizes video by mechanically manipulating the capture device and, therefore, does not need to crop the edges of the video frames. Per altre informazioni, vedi Controlli dei dispositivi di acquisizione per l’acquisizione di video.For more information, see Capture device controls for video capture.

Impostare l'app per l'uso della stabilizzazione videoSet up your app to use video stabilization

Oltre agli spazi dei nomi necessari per l'acquisizione multimediale di base, l'uso dell'effetto di stabilizzazione video richiede lo spazio dei nomi seguente.In addition to the namespaces required for basic media capture, using the video stabilization effect requires the following namespace.

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

Dichiarare una variabile membro per archiviare l'oggetto VideoStabilizationEffect .Declare a member variable to store the VideoStabilizationEffect object. Nell'ambito dell'implementazione dell'effetto, dovrai modificare le proprietà di codifica usate per codificare il video acquisito.As part of the effect implementation, you will modify the encoding properties that you use to encode the captured video. Dichiara due variabili per archiviare una copia di backup delle proprietà di codifica dell'input e output iniziali in modo che sia possibile ripristinarle in seguito quando l'effetto è disabilitato.Declare two variables to store a backup copy of the initial input and output encoding properties so that you can restore them later when the effect is disabled. Infine, dichiara una variabile membro di tipo MediaEncodingProfile perché questo oggetto sarà accessibile da più posizioni all'interno del codice.Finally, declare a member variable of type MediaEncodingProfile because this object will be accessed from multiple locations within your code.

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

Per questo scenario, devi assegnare l'oggetto del profilo di codifica multimediale a una variabile membro in modo che sia possibile accedervi in un secondo momento.For this scenario, you should assign the media encoding profile object to a member variable so that you can access it later.

_encodingProfile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto);

Inizializzare l'effetto di stabilizzazione videoInitialize the video stabilization effect

Dopo l’inizializzazione dell’oggetto MediaCapture, crea una nuova istanza dell’oggetto VideoStabilizationEffectDefinition.After your MediaCapture object has been initialized, create a new instance of the VideoStabilizationEffectDefinition object. Chiama MediaCapture.AddVideoEffectAsync per aggiungere l’effetto alla pipeline del video e recuperare un’istanza della classe VideoStabilizationEffect.Call MediaCapture.AddVideoEffectAsync to add the effect to the video pipeline and retrieve an instance of the VideoStabilizationEffect class. Specificare MediaStreamType. VideoRecord per indicare che l'effetto deve essere applicato al flusso di record video.Specify MediaStreamType.VideoRecord to indicate that the effect should be applied to the video record stream.

Registra un gestore per l’evento EnabledChanged e chiama il metodo helper SetUpVideoStabilizationRecommendationAsync. L’evento e il metodo helper sono descritti più avanti in questo articolo.Register an event handler for the EnabledChanged event and call the helper method SetUpVideoStabilizationRecommendationAsync, both of which are discussed later in this article. Infine, impostare la proprietà Enabled dell'effetto su true per abilitare l'effetto.Finally, set the Enabled property of the effect to true to enable the effect.

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

Come descritto in precedenza in questo articolo, la tecnica usata dall'effetto di stabilizzazione video necessariamente implica che il video stabilizzato venga leggermente ritagliato rispetto al video di origine.As discussed earlier in this article, the technique that the video stabilization effect uses necessarily causes the stabilized video to be cropped slightly from the source video. Definisci la seguente funzione di supporto nel codice per regolare le proprietà di codifica video in modo che questa limitazione dell'effetto venga gestita in modo ottimale.Define the following helper function in your code in order to adjust the video encoding properties to optimally handle this limitation of the effect. Questo passaggio non è necessario per l'uso dell'effetto di stabilizzazione video, ma se non viene eseguito, il video risultante avrà una scala maggiore e pertanto una fedeltà visiva leggermente inferiore.This step is not required in order to use the video stabilization effect, but if you don't perform this step, the resulting video will be upscaled slightly and therefore have slightly lower visual fidelity.

Chiama GetRecommendedStreamConfiguration nell’istanza dell’effetto di stabilizzazione video passando l’oggetto VideoDeviceController, che comunica all’effetto le proprietà di codifica del flusso di input corrente, e MediaEncodingProfile, che comunica all’effetto le proprietà di codifica dell’output corrente.Call GetRecommendedStreamConfiguration on your video stabilization effect instance, passing in the VideoDeviceController object, which informs the effect about your current input stream encoding properties, and your MediaEncodingProfile which lets the effect know your current output encoding properties. Questo metodo restituisce un oggetto VideoStreamConfiguration che contiene le nuove proprietà di codifica del flusso di input e di output consigliate.This method returns a VideoStreamConfiguration object containing new recommended input and output stream encoding properties.

Se supportate dal dispositivo, le proprietà di codifica dell'input consigliate sono una risoluzione più alta rispetto alle impostazioni iniziali fornite affinché si verifichi una perdita minima a livello di risoluzione dopo l'applicazione del ritaglio dell'effetto.The recommended input encoding properties are, if it is supported by the device, a higher resolution that the initial settings you provided so that there is minimal loss in resolution after the effect's cropping is applied.

Chiama VideoDeviceController.SetMediaStreamPropertiesAsync per impostare le nuove proprietà di codifica.Call VideoDeviceController.SetMediaStreamPropertiesAsync to set the new encoding properties. Prima di impostare le nuove proprietà, usa la variabile membro per archiviare le proprietà di codifica iniziali in modo da poterle ripristinare quando disabiliti l'effetto.Before setting the new properties, use the member variable to store the initial encoding properties so that you can change the settings back when you disable the effect.

Se l'effetto di stabilizzazione video deve ritagliare il video di output, le proprietà di codifica dell'output consigliate saranno le dimensioni del video ritagliato.If the video stabilization effect must crop the output video, the recommended output encoding properties will be the size of the cropped video. Ciò significa che la risoluzione di output corrisponderà alle dimensioni del video ritagliato.This means that the output resolution will match the cropped video size. Se non usi le proprietà di output consigliate, al video verrà applicata una scala in modo che corrisponda alla dimensione di output iniziale e ciò comporta una perdita di fedeltà visiva.If you do not use the recommended output properties, the video will be scaled up to match the initial output size, which will result in a loss of visual fidelity.

Imposta la proprietà Video dell'oggetto MediaEncodingProfile.Set the Video property of the MediaEncodingProfile object. Prima di impostare le nuove proprietà, usa la variabile membro per archiviare le proprietà di codifica iniziali in modo da poterle ripristinare quando disabiliti l'effetto.Before setting the new properties, use the member variable to store the initial encoding properties so that you can change the settings back when you disable the effect.

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;
    }
}

Gestire l'effetto di stabilizzazione video disabilitatoHandle the video stabilization effect being disabled

Il sistema può disabilitare automaticamente l'effetto di stabilizzazione video se la velocità effettiva dei pixel è troppo elevata per poter essere gestita dal sistema o se il sistema rileva che l'effetto è lento.The system may automatically disable the video stabilization effect if the pixel throughput is too high for the effect to handle or if it detects that the effect is running slowly. In questo caso, viene generato l'evento EnabledChanged.If this occurs, the EnabledChanged event is raised. L’istanza VideoStabilizationEffect nel parametro sender indica il nuovo stato dell’effetto, ovvero abilitato o disabilitato.The VideoStabilizationEffect instance in the sender parameter indicates the new state of the effect, enabled or disabled. VideoStabilizationEffectEnabledChangedEventArgs ha un valore VideoStabilizationEffectEnabledChangedReason che indica il motivo per cui l’effetto è stato abilitato o disabilitato.The VideoStabilizationEffectEnabledChangedEventArgs has a VideoStabilizationEffectEnabledChangedReason value indicating why the effect was enabled or disabled. Tieni presente che questo evento viene generato anche se a livello di codice abiliti o disabiliti l’effetto, nel qual caso il motivo sarà Programmatic.Note that this event is also raised if you programmatically enable or disable the effect, in which case the reason will be Programmatic.

In genere usi questo evento per modificare l'interfaccia utente dell'app in modo da indicare lo stato corrente di stabilizzazione video.Typically, you would use this event to adjust your app's UI to indicate the current status of video stabilization.

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

Pulire l'effetto di stabilizzazione videoClean up the video stabilization effect

Per pulire l'effetto di stabilizzazione video, chiamare RemoveEffectAsync per rimuovere l'effetto dalla pipeline video.To clean up the video stabilization effect, call RemoveEffectAsync to remove the effect from the video pipeline. Se le variabili membro contenenti le proprietà di codifica iniziale non sono null, usale per ripristinare le proprietà di codifica.If the member variables containing the initial encoding properties are not null, use them to restore the encoding properties. Infine, rimuovi il gestore dell'evento EnabledChanged e imposta l'effetto su null.Finally, remove the EnabledChanged event handler and set the effect to 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;