Efeitos de vídeo personalizadosCustom video effects

Este artigo descreve como criar um componente do Windows Runtime que implemente a interface IBasicVideoEffect para criar efeitos personalizados para fluxos de vídeo.This article describes how to create a Windows Runtime component that implements the IBasicVideoEffect interface to create custom effects for video streams. Efeitos personalizados podem ser usados com várias APIs do Windows Runtime diferentes, incluindo MediaCapture, que fornece acesso à câmera do dispositivo, e MediaComposition, que permite que você crie composições complexas de clipes de mídia.Custom effects can be used with several different Windows Runtime APIs including MediaCapture, which provides access to a device's camera, and MediaComposition, which allows you to create complex compositions out of media clips.

Adicionar um efeito personalizado ao seu aplicativoAdd a custom effect to your app

Um efeito de vídeo personalizado é definido em uma classe que implementa a interface IBasicVideoEffect.A custom video effect is defined in a class that implements the IBasicVideoEffect interface. Essa classe não pode ser incluída diretamente no projeto do seu aplicativo.This class can't be included directly in your app's project. Em vez disso, você deve usar um componente do Tempo de Execução do Windows para hospedar sua classe de efeito de vídeo.Instead, you must use a Windows Runtime component to host your video effect class.

Adicionar um componente do Tempo de Execução do Windows para o efeito de vídeoAdd a Windows Runtime component for your video effect

  1. No Microsoft Visual Studio, com sua solução aberta, vá para o menu arquivo e selecione Adicionar- > novo projeto.In Microsoft Visual Studio, with your solution open, go to the File menu and select Add->New Project.
  2. Selecione o tipo de projeto Componente do Tempo de Execução do Windows (Windows Universal).Select the Windows Runtime Component (Universal Windows) project type.
  3. Para este exemplo, chame o projeto de VideoEffectComponent.For this example, name the project VideoEffectComponent. Esse nome será referenciado no código posteriormente.This name will be referenced in code later.
  4. Clique em OK.Click OK.
  5. O modelo de projeto cria uma classe chamada Class1.cs.The project template creates a class called Class1.cs. No Gerenciador de Soluções, clique com botão direito do mouse no ícone de Class1.cs e selecione Renomear.In Solution Explorer, right-click the icon for Class1.cs and select Rename.
  6. Renomeie o arquivo para ExampleVideoEffect.cs.Rename the file to ExampleVideoEffect.cs. O Visual Studio mostrará um aviso perguntando se você deseja atualizar todas as referências para o novo nome.Visual Studio will show a prompt asking if you want to update all references to the new name. Clique em Sim.Click Yes.
  7. Abra ExampleVideoEffect.cs e atualize a definição de classe para implementar a interface IBasicVideoEffect.Open ExampleVideoEffect.cs and update the class definition to implement the IBasicVideoEffect interface.
public sealed class ExampleVideoEffect : IBasicVideoEffect

Você precisa incluir os seguintes namespaces no arquivo de classe do efeito para acessar todos os tipos usados nos exemplos deste artigo.You need to include the following namespaces in your effect class file in order to access all of the types used in the examples in this article.

using Windows.Media.Effects;
using Windows.Media.MediaProperties;
using Windows.Foundation.Collections;
using Windows.Graphics.DirectX.Direct3D11;
using Windows.Graphics.Imaging;

Implementar a interface IBasicVideoEffect usando o processamento de softwareImplement the IBasicVideoEffect interface using software processing

O efeito de vídeo deve implementar todos os métodos e propriedades da interface IBasicVideoEffect.Your video effect must implement all of the methods and properties of the IBasicVideoEffect interface. Esta seção percorre uma implementação simples dessa interface que usa o processamento de software.This section walks you through a simple implementation of this interface that uses software processing.

Método CloseClose method

O sistema chamará o método Close em sua classe quando o efeito for encerrado.The system will call the Close method on your class when the effect should shut down. Você deve usar esse método para descartar quaisquer recursos que você criou.You should use this method to dispose of any resources you have created. O argumento para o método é um MediaEffectClosedReason que permite que você saiba se o efeito foi fechado normalmente, se ocorreu um erro ou se o efeito não é compatível com o formato de codificação necessário.The argument to the method is a MediaEffectClosedReason that lets you know whether the effect was closed normally, if an error occurred, or if the effect does not support the required encoding format.

public void Close(MediaEffectClosedReason reason)
{
    // Dispose of effect resources
}

Método DiscardQueuedFramesDiscardQueuedFrames method

O método DiscardQueuedFrames é chamado quando o efeito deve ser redefinido.The DiscardQueuedFrames method is called when your effect should reset. Um cenário típico para isso é se o efeito armazena quadros processados anteriormente para serem usados no processamento do quadro atual.A typical scenario for this is if your effect stores previously processed frames to use in processing the current frame. Quando esse método é chamado, você deve descartar o conjunto de quadros anteriores que foram salvos.When this method is called, you should dispose of the set of previous frames you saved. Esse método possa ser usado para restaurar qualquer estado relacionado ao quadros anteriores, não apenas quadros de vídeo acumulados.This method can be used to reset any state related to previous frames, not only accumulated video frames.

private int frameCount;
public void DiscardQueuedFrames()
{
    frameCount = 0;
}

Propriedade IsReadOnlyIsReadOnly property

A propriedade IsReadOnly permite que o sistema saiba se o efeito será gravado na saída.The IsReadOnly property lets the system know if your effect will write to the output of the effect. Se o seu aplicativo não modifica os quadros de vídeo (por exemplo, um efeito que só executa uma análise dos quadros do vídeo), você deve definir essa propriedade como true, o que fará com que o sistema copie de forma eficiente a entrada do quadro para a saída do quadro.If your app does not modify the video frames (for example, an effect that only performs analysis of the video frames), you should set this property to true, which will cause the system to efficiently copy the frame input to the frame output for you.

Dica

Quando a propriedade IsReadOnly é definida como true, o sistema copia o quadro de entrada para o quadro de saída antes que ProcessFrame seja chamada.When the IsReadOnly property is set to true, the system copies the input frame to the output frame before ProcessFrame is called. Definir a propriedade IsReadOnly como true não impede que você grave nos quadros de saída do efeito em ProcessFrame.Setting the IsReadOnly property to true does not restrict you from writing to the effect's output frames in ProcessFrame.

public bool IsReadOnly { get { return false; } }

Método SetEncodingPropertiesSetEncodingProperties method

O sistema chama SetEncodingProperties o efeito para permitir que você conheça as propriedades de codificação do fluxo de vídeo no qual o efeito está operando.The system calls SetEncodingProperties on your effect to let you know the encoding properties for the video stream upon which the effect is operating. Esse método também fornece uma referência para o dispositivo Direct3D usado para renderização de hardware.This method also provides a reference to the Direct3D device used for hardware rendering. O uso desse dispositivo é mostrado no exemplo de processamento de hardware mais adiante neste artigo.The usage of this device is shown in the hardware processing example later in this article.

private VideoEncodingProperties encodingProperties;
public void SetEncodingProperties(VideoEncodingProperties encodingProperties, IDirect3DDevice device)
{
    this.encodingProperties = encodingProperties;
}

Propriedade SupportedEncodingPropertiesSupportedEncodingProperties property

O sistema verifica a propriedade SupportedEncodingProperties para determinar quais propriedades de codificação são compatíveis com o efeito.The system checks the SupportedEncodingProperties property to determine which encoding properties are supported by your effect. Observe que se o consumidor do efeito não puder codificar o vídeo usando as propriedades que você especificar, ele chamará Close no efeito e o removerá do pipeline de vídeo.Note that if the consumer of your effect can't encode video using the properties you specify, it will call Close on your effect and will remove your effect from the video pipeline.

public IReadOnlyList<VideoEncodingProperties> SupportedEncodingProperties
{            
    get
    {
        var encodingProperties = new VideoEncodingProperties();
        encodingProperties.Subtype = "ARGB32";
        return new List<VideoEncodingProperties>() { encodingProperties };

        // If the list is empty, the encoding type will be ARGB32.
        // return new List<VideoEncodingProperties>();
    }
}

Observação

Se você retornar uma lista vazia de objetos VideoEncodingProperties de SupportedEncodingProperties, o sistema usará o padrão de codificação ARGB32.If you return an empty list of VideoEncodingProperties objects from SupportedEncodingProperties, the system will default to ARGB32 encoding.

 

Propriedade SupportedMemoryTypesSupportedMemoryTypes property

O sistema verifica a propriedade SupportedMemoryTypes para determinar se o efeito acessará quadros de vídeo na memória do software ou na memória do hardware (GPU).The system checks the SupportedMemoryTypes property to determine whether your effect will access video frames in software memory or in hardware (GPU) memory. Se você retornar MediaMemoryTypes.Cpu, serão passados para o efeito quadros de entrada e de saída que contêm dados de imagem em objetos SoftwareBitmap.If you return MediaMemoryTypes.Cpu, your effect will be passed input and output frames that contain image data in SoftwareBitmap objects. Se você retornar MediaMemoryTypes.Gpu, serão passados para o efeito quadros de entrada e de saída que contêm dados de imagem em objetos IDirect3DSurface.If you return MediaMemoryTypes.Gpu, your effect will be passed input and output frames that contain image data in IDirect3DSurface objects.

public MediaMemoryTypes SupportedMemoryTypes { get { return MediaMemoryTypes.Cpu; } }

Observação

Se você especificar MediaMemoryTypes.GpuAndCpu, o sistema usará a memória do sistema ou a GPU, o que for mais eficiente para o pipeline.If you specify MediaMemoryTypes.GpuAndCpu, the system will use either GPU or system memory, whichever is more efficient for the pipeline. Ao usar esse valor, você precisa verificar o método ProcessFrame para ver se SoftwareBitmap ou IDirect3DSurface passado para o método contém dados e processar o quadro de acordo.When using this value, you must check in the ProcessFrame method to see whether the SoftwareBitmap or IDirect3DSurface passed into the method contains data, and then process the frame accordingly.

 

Propriedade TimeIndependentTimeIndependent property

A propriedade TimeIndependent permite que o sistema saiba se o efeito não requer tempo uniforme.The TimeIndependent property lets the system know if your effect does not require uniform timing. Quando definida como true, o sistema pode usar otimizações que aprimorem o desempenho do efeito.When set to true, the system can use optimizations that enhance effect performance.

public bool TimeIndependent { get { return true; } }

Método SetPropertiesSetProperties method

O método SetProperties permite que o aplicativo que está usando o efeito ajuste os parâmetros do efeito.The SetProperties method allows the app that is using your effect to adjust effect parameters. As propriedades são passadas como um mapa de nomes e valores de propriedade IPropertySet.Properties are passed as an IPropertySet map of property names and values.

private IPropertySet configuration;
public void SetProperties(IPropertySet configuration)
{
    this.configuration = configuration;
}

Este exemplo simples escurecerá os pixels em cada quadro de vídeo de acordo com um valor especificado.This simple example will dim the pixels in each video frame according to a specified value. Uma propriedade é declarada e TryGetValue é usado para obter o valor definido pelo aplicativo de chamada.A property is declared and TryGetValue is used to get the value set by the calling app. Se nenhum valor foi definido, um valor padrão de 0,5 será usado.If no value was set, a default value of .5 is used.

public double FadeValue
{
    get
    {
        object val;
        if (configuration != null && configuration.TryGetValue("FadeValue", out val))
        {
            return (double)val;
        }
        return .5;
    }
}

Método ProcessFrameProcessFrame method

O método ProcessFrame é onde o efeito modifica os dados da imagem do vídeo.The ProcessFrame method is where your effect modifies the image data of the video. O método é chamado uma vez por quadro e um objeto ProcessVideoFrameContext é passado.The method is called once per frame and is passed a ProcessVideoFrameContext object. Este objeto contém um objeto VideoFrame de entrada que contém o quadro de entrada a ser processado e um objeto VideoFrame de saída no qual você grava os dados da imagem que serão passados para o resto do pipeline do vídeo.This object contains an input VideoFrame object that contains the incoming frame to be processed and an output VideoFrame object to which you write image data that will be passed on to rest of the video pipeline. Cada um desses objetos VideoFrame possui uma propriedade SoftwareBitmap e uma propriedade Direct3DSurface, mas o valor da propriedade SupportedMemoryTypes determina qual delas pode ser usada.Each of these VideoFrame objects has a SoftwareBitmap property and a Direct3DSurface property, but which of these can be used is determined by the value you returned from the SupportedMemoryTypes property.

Este exemplo mostra uma implementação simples do método ProcessFrame usando processamento de software.This example shows a simple implementation of the ProcessFrame method using software processing. Para obter informações sobre como trabalhar com objetos SoftwareBitmap, consulte Geração de imagens.For more information about working with SoftwareBitmap objects, see Imaging. Uma implementação de ProcessFrame de exemplo usando o processamento de hardware é mostrada mais adiante neste artigo.An example ProcessFrame implementation using hardware processing is shown later in this article.

Acessar o buffer de dados de um SoftwareBitmap requer interoperabilidade COM, portanto, você deve incluir o namespace System.Runtime.InteropServices no arquivo de classe do efeito.Accessing the data buffer of a SoftwareBitmap requires COM interop, so you should include the System.Runtime.InteropServices namespace in your effect class file.

using System.Runtime.InteropServices;

Adicione o código a seguir ao namespace para que o efeito importe a interface para acessar o buffer de imagem.Add the following code inside the namespace for your effect to import the interface for accessing the image buffer.

[ComImport]
[Guid("5B0D3235-4DBA-4D44-865E-8F1D0E4FD04D")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
unsafe interface IMemoryBufferByteAccess
{
    void GetBuffer(out byte* buffer, out uint capacity);
}

Observação

Como essa técnica acessa um buffer de imagem nativo não gerenciado, você precisará configurar seu projeto para permitir código não seguro.Because this technique accesses a native, unmanaged image buffer, you will need to configure your project to allow unsafe code.

  1. No Gerenciador de Soluções, clique com o botão direito do mouse no projeto VideoEffectComponent e selecione Propriedades.In Solution Explorer, right-click the VideoEffectComponent project and select Properties.
  2. Selecione a guia Compilar .Select the Build tab.
  3. Marque a caixa de seleção Permitir código não seguro .Select the Allow unsafe code check box.

 

Agora você pode adicionar a implementação do método ProcessFrame.Now you can add the ProcessFrame method implementation. Primeiro, esse método obtém um objeto BitmapBuffer a partir dos bitmaps de software de entrada e de saída.First, this method obtains a BitmapBuffer object from both the input and output software bitmaps. Observe que o quadro de saída é aberto para gravação e o de entrada para leitura.Note that the output frame is opened for writing and the input for reading. Em seguida, um IMemoryBufferReference é obtido para cada buffer, chamando-se CreateReference.Next, an IMemoryBufferReference is obtained for each buffer by calling CreateReference. Em seguida, o buffer de dados real é obtido, transmitindo os objetos IMemoryBufferReference como a interface de interoperabilidade COM definida acima, IMemoryByteAccess, e chamando GetBuffer.Then, the actual data buffer is obtained by casting the IMemoryBufferReference objects as the COM interop interface defined above, IMemoryByteAccess, and then calling GetBuffer.

Agora que os buffers de dados foram obtidos, você pode ler o buffer de entrada e gravar no buffer de saída.Now that the data buffers have been obtained, you can read from the input buffer and write to the output buffer. O layout do buffer é obtido chamando GetPlaneDescription, que fornece informações sobre a largura, a distância e o deslocamento inicial do buffer.The layout of the buffer is obtained by calling GetPlaneDescription, which provides information on the width, stride, and initial offset of the buffer. Os bits por pixel são determinados pelas propriedades de codificação definidas anteriormente com o método SetEncodingProperties.The bits per pixel is determined by the encoding properties set previously with the SetEncodingProperties method. As informações de formato do buffer são usadas para encontrar o índice de cada pixel no buffer.The buffer format information is used to find the index into the buffer for each pixel. O valor de pixel do buffer de origem é copiado para o buffer de destino, com os valores de cores sendo multiplicados pela propriedade FadeValue definida para esse efeito escurecê-las pelo valor especificado.The pixel value from the source buffer is copied into the target buffer, with the color values being multiplied by the FadeValue property defined for this effect to dim them by the specified amount.

public unsafe void ProcessFrame(ProcessVideoFrameContext context)
{
    using (BitmapBuffer buffer = context.InputFrame.SoftwareBitmap.LockBuffer(BitmapBufferAccessMode.Read))
    using (BitmapBuffer targetBuffer = context.OutputFrame.SoftwareBitmap.LockBuffer(BitmapBufferAccessMode.Write))
    {
        using (var reference = buffer.CreateReference())
        using (var targetReference = targetBuffer.CreateReference())
        {
            byte* dataInBytes;
            uint capacity;
            ((IMemoryBufferByteAccess)reference).GetBuffer(out dataInBytes, out capacity);

            byte* targetDataInBytes;
            uint targetCapacity;
            ((IMemoryBufferByteAccess)targetReference).GetBuffer(out targetDataInBytes, out targetCapacity);

            var fadeValue = FadeValue;

            // Fill-in the BGRA plane
            BitmapPlaneDescription bufferLayout = buffer.GetPlaneDescription(0);
            for (int i = 0; i < bufferLayout.Height; i++)
            {
                for (int j = 0; j < bufferLayout.Width; j++)
                {

                    byte value = (byte)((float)j / bufferLayout.Width * 255);

                    int bytesPerPixel = 4; 
                    if (encodingProperties.Subtype != "ARGB32")
                    {
                        // If you support other encodings, adjust index into the buffer accordingly
                    }
                    

                    int idx = bufferLayout.StartIndex + bufferLayout.Stride * i + bytesPerPixel * j;

                    targetDataInBytes[idx + 0] = (byte)(fadeValue * (float)dataInBytes[idx + 0]);
                    targetDataInBytes[idx + 1] = (byte)(fadeValue * (float)dataInBytes[idx + 1]);
                    targetDataInBytes[idx + 2] = (byte)(fadeValue * (float)dataInBytes[idx + 2]);
                    targetDataInBytes[idx + 3] = dataInBytes[idx + 3];
                }
            }
        }
    }
}

Implementar a interface IBasicVideoEffect usando o processamento de hardwareImplement the IBasicVideoEffect interface using hardware processing

Criar um efeito de vídeo personalizado usando o processamento de hardware (GPU) é quase idêntico a usar o processamento de software conforme descrito anteriormente.Creating a custom video effect by using hardware (GPU) processing is almost identical to using software processing as described above. Esta seção mostrará as algumas diferenças em um efeito que usa o processamento de hardware.This section will show the few differences in an effect that uses hardware processing. Este exemplo usa a API do Windows Runtime Win2D.This example uses the Win2D Windows Runtime API. Para obter mais informações sobre como usar Win2D, consulte a Documentação do Win2D.For more information about using Win2D, see the Win2D documentation.

Use as etapas a seguir para adicionar o pacote NuGet Win2D ao projeto que você criou, conforme descrito na seção Adicionar um efeito personalizado ao seu aplicativo no início deste artigo.Use the following steps to add the Win2D NuGet package to the project you created as described in the Add a custom effect to your app section at the beginning of this article.

Para adicionar o pacote NuGet Win2D ao seu projeto de efeitoTo add the Win2D NuGet package to your effect project

  1. No Gerenciador de Soluções, clique com o botão direito do mouse no projeto VideoEffectComponent e selecione Gerenciar Pacotes NuGet.In Solution Explorer, right-click the VideoEffectComponent project and select Manage NuGet Packages.
  2. Na parte superior da janela, selecione a guia Procurar.At the top of the window, select the Browse tab.
  3. Na caixa de pesquisa, digite Win2D.In the search box, enter Win2D.
  4. Selecione Win2D.uwp e, em seguida, selecione Instalar no painel à direita.Select Win2D.uwp, and then select Install in the right pane.
  5. A caixa de diálogo Revisar Alterações mostra o pacote a ser instalado.The Review Changes dialog shows you the package to be installed. Clique em OK.Click OK.
  6. Aceite a licença do pacote.Accept the package license.

Além dos namespaces incluídos na instalação do projeto básico, você precisará incluir os namespaces a seguir fornecidos pelo Win2D.In addition to the namespaces included in the basic project setup, you will need to include the following namespaces provided by Win2D.

using Microsoft.Graphics.Canvas.Effects;
using Microsoft.Graphics.Canvas;

Como esse efeito usará a memória GPU para operar nos dados da imagem, você deve retornar MediaMemoryTypes.Gpu da propriedade SupportedMemoryTypes.Because this effect will use GPU memory for operating on the image data, you should return MediaMemoryTypes.Gpu from the SupportedMemoryTypes property.

public MediaMemoryTypes SupportedMemoryTypes { get { return MediaMemoryTypes.Gpu; } }

Defina as propriedades de codificação com as quais o efeito será compatível com a propriedade SupportedEncodingProperties.Set the encoding properties that your effect will support with the SupportedEncodingProperties property. Ao trabalhar com Win2D, você deve usar a codificação ARGB32.When working with Win2D, you must use ARGB32 encoding.

public IReadOnlyList<VideoEncodingProperties> SupportedEncodingProperties {
    get
    {
        var encodingProperties = new VideoEncodingProperties();
        encodingProperties.Subtype = "ARGB32";
        return new List<VideoEncodingProperties>() { encodingProperties };
    }
}

Use o método SetEncodingProperties para criar um novo objeto CanvasDevice Win2D do IDirect3DDevice passado para o método.Use the SetEncodingProperties method to create a new Win2D CanvasDevice object from the IDirect3DDevice passed into the method.

private CanvasDevice canvasDevice;
public void SetEncodingProperties(VideoEncodingProperties encodingProperties, IDirect3DDevice device)
{
    canvasDevice = CanvasDevice.CreateFromDirect3D11Device(device);
}

A implementação SetProperties é idêntica ao exemplo anterior de processamento de software.The SetProperties implementation is identical to the previous software processing example. Este exemplo usa uma propriedade BlurAmount para configurar um efeito de desfoque Win2D.This example uses a BlurAmount property to configure a Win2D blur effect.

private IPropertySet configuration;
public void SetProperties(IPropertySet configuration)
{
    this.configuration = configuration;
}
public double BlurAmount
{
    get
    {
        object val;
        if (configuration != null && configuration.TryGetValue("BlurAmount", out val))
        {
            return (double)val;
        }
        return 3;
    }
}

A última etapa é implementar o método ProcessFrame que realmente processa os dados da imagem.The last step is to implement the ProcessFrame method that actually processes the image data.

Usando as APIs Win2D, um CanvasBitmap é criado a partir da propriedade Direct3DSurface do quadro de entrada.Using Win2D APIs, a CanvasBitmap is created from the input frame's Direct3DSurface property. Um CanvasRenderTarget é criado a partir do Direct3DSurface do quadro de saída e um CanvasDrawingSession é criado a partir desse destino de renderização.A CanvasRenderTarget is created from the output frame's Direct3DSurface and a CanvasDrawingSession is created from this render target. Um novo GaussianBlurEffect Win2D é inicializado, usando a propriedade BlurAmount que o nosso efeito expõe via SetProperties.A new Win2D GaussianBlurEffect is initialized, using the BlurAmount property our effect exposes via SetProperties. Por fim, o método CanvasDrawingSession.DrawImage é chamado para desenhar o bitmap de entrada para o destino de renderização usando o efeito de desfoque.Finally, the CanvasDrawingSession.DrawImage method is called to draw the input bitmap to the render target using the blur effect.

public void ProcessFrame(ProcessVideoFrameContext context)
{

    using (CanvasBitmap inputBitmap = CanvasBitmap.CreateFromDirect3D11Surface(canvasDevice, context.InputFrame.Direct3DSurface))
    using (CanvasRenderTarget renderTarget = CanvasRenderTarget.CreateFromDirect3D11Surface(canvasDevice, context.OutputFrame.Direct3DSurface))
    using (CanvasDrawingSession ds = renderTarget.CreateDrawingSession())
    {


        var gaussianBlurEffect = new GaussianBlurEffect
        {
            Source = inputBitmap,
            BlurAmount = (float)BlurAmount,
            Optimization = EffectOptimization.Speed
        };

        ds.DrawImage(gaussianBlurEffect);

    }
}

Adicionando efeito personalizado ao seu aplicativoAdding your custom effect to your app

Para usar o efeito de vídeo do seu aplicativo, você deve adicionar uma referência ao projeto do efeito ao seu aplicativo.To use your video effect from your app, you must add a reference to the effect project to your app.

  1. No Gerenciador de Soluções, no projeto do seu aplicativo, clique com o botão direito do mouse em Referências e selecione Adicionar referência.In Solution Explorer, under your app project, right-click References and select Add reference.
  2. Expanda a guia Projetos, selecione Solução e marque a caixa de seleção com o nome do projeto do efeito.Expand the Projects tab, select Solution, and then select the check box for your effect project name. Neste exemplo, o nome é VideoEffectComponent.For this example, the name is VideoEffectComponent.
  3. Clique em OK.Click OK.

Adicionar o efeito personalizado a um fluxo de vídeo da câmeraAdd your custom effect to a camera video stream

Você pode configurar um fluxo de visualização simples da câmera seguindo as etapas do artigo Acesso de visualização de câmera simples.You can set up a simple preview stream from the camera by following the steps in the article Simple camera preview access. As etapas a seguir fornecerão um objeto MediaCapture inicializado que é usado para acessar o fluxo de vídeo da câmera.Following those steps will provide you with an initialized MediaCapture object that is used to access the camera's video stream.

Para adicionar o efeito de vídeo personalizado ao fluxo de uma câmera, primeiro crie um novo objeto VideoEffectDefinition, passando o namespace e o nome de classe do efeito.To add your custom video effect to a camera stream, first create a new VideoEffectDefinition object, passing in the namespace and class name for your effect. Em seguida, do objeto MediaCapture, chame o método AddVideoEffect para adicionar o efeito ao fluxo especificado.Next, call the MediaCapture object's AddVideoEffect method to add your effect to the specified stream. Este exemplo usa o valor MediaStreamType.VideoPreview para especificar se esse efeito deve ser adicionado ao fluxo de inicialização.This example uses the MediaStreamType.VideoPreview value to specify that the effect should be added to the preview stream. Se o seu aplicativo der suporte à captura de vídeo, você também poderia usar MediaStreamType.VideoRecord para adicionar o efeito ao fluxo de captura.If your app supports video capture, you could also use MediaStreamType.VideoRecord to add the effect to the capture stream. AddVideoEffect retorna um objeto IMediaExtension que representa o efeito personalizado.AddVideoEffect returns an IMediaExtension object representing your custom effect. Você pode usar o método SetProperties para definir a configuração do efeito.You can use the SetProperties method to set the configuration for your effect.

Depois que o efeito tiver sido adicionado, StartPreviewAsync é chamado para iniciar o fluxo de visualização.After the effect has been added, StartPreviewAsync is called to start the preview stream.

var videoEffectDefinition = new VideoEffectDefinition("VideoEffectComponent.ExampleVideoEffect");

IMediaExtension videoEffect =
   await mediaCapture.AddVideoEffectAsync(videoEffectDefinition, MediaStreamType.VideoPreview);

videoEffect.SetProperties(new PropertySet() { { "FadeValue", .25 } });

await mediaCapture.StartPreviewAsync();

Adicionar o efeito personalizado a um clipe em um MediaCompositionAdd your custom effect to a clip in a MediaComposition

Para obter orientações gerais sobre como criar composições de mídia a partir de clipes de vídeo, consulte Composições e edição de mídia.For general guidance for creating media compositions from video clips, see Media compositions and editing. O trecho de código a seguir mostra a criação de uma composição de mídia simples com um efeito de vídeo personalizado.The following code snippet shows the creation of a simple media composition that uses a custom video effect. Um objeto MediaClip é criado, chamando-se CreateFromFileAsync, passando um arquivo de vídeo que foi selecionado pelo usuário com um FileOpenPicker e o clipe é adicionado a um novo MediaComposition.A MediaClip object is created by calling CreateFromFileAsync, passing in a video file that was selected by the user with a FileOpenPicker, and the clip is added to a new MediaComposition. Em seguida, um novo objeto VideoEffectDefinition é criado, passando o namespace e nome de classe do efeito para o construtor.Next a new VideoEffectDefinition object is created, passing in the namespace and class name for your effect to the constructor. Por fim, a definição do efeito é adicionada à coleção VideoEffectDefinitions do objeto MediaClip.Finally, the effect definition is added to the VideoEffectDefinitions collection of the MediaClip object.

MediaComposition composition = new MediaComposition();
var clip = await MediaClip.CreateFromFileAsync(pickedFile);
composition.Clips.Add(clip);

var videoEffectDefinition = new VideoEffectDefinition("VideoEffectComponent.ExampleVideoEffect", new PropertySet() { { "FadeValue", .5 } });

clip.VideoEffectDefinitions.Add(videoEffectDefinition);