カスタムのビデオ特殊効果Custom video effects

この記事では、ビデオ ストリームのカスタム効果を作成するための IBasicVideoEffect インターフェイスを実装する Windows ランタイム コンポーネントを作成する方法について説明します。This article describes how to create a Windows Runtime component that implements the IBasicVideoEffect interface to create custom effects for video streams. カスタム効果は、デバイスのカメラへのアクセスを提供する MediaCapture、メディア クリップから複雑なコンポジションを作成するための MediaComposition など、さまざまな Windows ランタイム API で使うことができます。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.

アプリへのカスタム効果の追加Add a custom effect to your app

カスタムのビデオ特殊効果は、IBasicVideoEffect インターフェイスを実装するクラスで定義します。A custom video effect is defined in a class that implements the IBasicVideoEffect interface. このクラスは、アプリのプロジェクトに直接含めることはできません。This class can't be included directly in your app's project. 代わりに、Windows ランタイム コンポーネントを使ってビデオ特殊効果のクラスをホストする必要があります。Instead, you must use a Windows Runtime component to host your video effect class.

Windows ランタイム コンポーネント、ビデオ特殊効果の追加します。Add a Windows Runtime component for your video effect

  1. Microsoft Visual Studio で、ソリューションを開き、 [ファイル] メニューから [追加]、[新しいプロジェクト] の順にクリックします。In Microsoft Visual Studio, with your solution open, go to the File menu and select Add->New Project.
  2. プロジェクトの種類として [Windows ランタイム コンポーネント (ユニバーサル Windows)] を選びます。Select the Windows Runtime Component (Universal Windows) project type.
  3. この例では、プロジェクトに VideoEffectComponent という名前を付けます。For this example, name the project VideoEffectComponent. この名前は後でコードで参照されます。This name will be referenced in code later.
  4. [OK] をクリックします。Click OK.
  5. プロジェクト テンプレートに基づいて、Class1.cs という名前のクラスが作成されます。The project template creates a class called Class1.cs. ソリューション エクスプローラーで、Class1.cs のアイコンを右クリックし、 [名前の変更] をクリックします。In Solution Explorer, right-click the icon for Class1.cs and select Rename.
  6. ファイル名を ExampleVideoEffect.cs に変更します。Rename the file to ExampleVideoEffect.cs. すべての参照を新しい名前に更新するかどうかを確認するメッセージが表示されたら、Visual Studio will show a prompt asking if you want to update all references to the new name. [はい] をクリックします。Click Yes.
  7. ExampleVideoEffect.cs を開き、クラス定義を更新して IBasicVideoEffect インターフェイスを実装します。Open ExampleVideoEffect.cs and update the class definition to implement the IBasicVideoEffect interface.
public sealed class ExampleVideoEffect : IBasicVideoEffect

この記事の例で使うすべての型にアクセスできるように、効果のクラス ファイルに次の名前空間を含める必要があります。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;

ソフトウェア処理を使用した IBasicVideoEffect インターフェイスの実装Implement the IBasicVideoEffect interface using software processing

ビデオ特殊効果では、IBasicVideoEffect インターフェイスのすべてのメソッドとプロパティを実装する必要があります。Your video effect must implement all of the methods and properties of the IBasicVideoEffect interface. このセクションでは、このインターフェイスの実装方法の説明として、ソフトウェア処理を使用した簡単な実装を示します。This section walks you through a simple implementation of this interface that uses software processing.

Close メソッドClose method

Close メソッドは、クラスで効果をシャットダウンする必要があるときに呼び出されます。The system will call the Close method on your class when the effect should shut down. このメソッドを使って、作成したすべてのリソースを破棄する必要があります。You should use this method to dispose of any resources you have created. このメソッドの MediaEffectClosedReason 引数により、効果が正常に終了されたかどうかがわかります。エラーが発生したり、必要なエンコード形式が効果でサポートされていないと、この引数で通知されます。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
}

DiscardQueuedFrames メソッドDiscardQueuedFrames method

DiscardQueuedFrames メソッドは、効果をリセットする必要があるときに呼び出されます。The DiscardQueuedFrames method is called when your effect should reset. 典型的なシナリオとしては、現在のフレームの処理で使うために前に処理したフレームを保存している場合などが挙げられます。A typical scenario for this is if your effect stores previously processed frames to use in processing the current frame. このメソッドが呼び出されたときは、保存した一連のフレームを破棄する必要があります。When this method is called, you should dispose of the set of previous frames you saved. このメソッドでは、蓄積されたビデオ フレームだけでなく、前のフレームに関連するすべての状態をリセットできます。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;
}

IsReadOnly プロパティIsReadOnly property

IsReadOnly プロパティは、効果の出力への書き込みを行うかどうかを示します。The IsReadOnly property lets the system know if your effect will write to the output of the effect. アプリでビデオ フレームを変更しない場合 (ビデオ フレームの分析のみを行う場合など) は、このプロパティを true に設定します。これにより、フレーム入力がフレーム出力に効率的にコピーされるようになります。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.

ヒント

IsReadOnly プロパティを true に設定すると、入力フレームが出力フレームにコピーされてから ProcessFrame が呼び出されます。When the IsReadOnly property is set to true, the system copies the input frame to the output frame before ProcessFrame is called. IsReadOnly プロパティを true に設定しても、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; } }

SetEncodingProperties メソッドSetEncodingProperties method

SetEncodingProperties は、効果の対象となるビデオ ストリームのエンコード プロパティを示すために呼び出されます。The system calls SetEncodingProperties on your effect to let you know the encoding properties for the video stream upon which the effect is operating. このメソッドは、ハードウェア レンダリングに使う Direct3D デバイスへの参照も提供します。This method also provides a reference to the Direct3D device used for hardware rendering. このデバイスの用途については、この後のハードウェア処理の例で説明します。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;
}

SupportedEncodingProperties プロパティSupportedEncodingProperties property

SupportedEncodingProperties プロパティは、効果でサポートされるエンコード プロパティを確認するためにシステムでチェックされます。The system checks the SupportedEncodingProperties property to determine which encoding properties are supported by your effect. 効果で指定したプロパティを使ってビデオをエンコードできない場合、Close が呼び出され、効果がビデオ パイプラインから削除されます。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>();
    }
}

注意

SupportedEncodingProperties から返される VideoEncodingProperties オブジェクトの一覧を空にすると、既定で ARGB32 エンコードが使われます。If you return an empty list of VideoEncodingProperties objects from SupportedEncodingProperties, the system will default to ARGB32 encoding.

 

SupportedMemoryTypes プロパティSupportedMemoryTypes property

SupportedMemoryTypes プロパティは、ソフトウェア メモリとハードウェア (GPU) メモリのどちらのビデオ フレームにアクセスするかを確認するためにシステムでチェックされます。The system checks the SupportedMemoryTypes property to determine whether your effect will access video frames in software memory or in hardware (GPU) memory. MediaMemoryTypes.Cpu を指定すると、画像データを SoftwareBitmap オブジェクトに格納する入力フレームと出力フレームが渡されます。If you return MediaMemoryTypes.Cpu, your effect will be passed input and output frames that contain image data in SoftwareBitmap objects. MediaMemoryTypes.Gpu を指定すると、画像データを 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; } }

注意

MediaMemoryTypes.GpuAndCpu を指定すると、GPU とシステム メモリのどちらを使うかがパイプラインの効率に基づいて判断されます。If you specify MediaMemoryTypes.GpuAndCpu, the system will use either GPU or system memory, whichever is more efficient for the pipeline. この値を使う場合は、ProcessFrame メソッドで SoftwareBitmapIDirect3DSurface のどちらにデータが格納されたかをチェックし、それに応じてフレームを処理する必要があります。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.

 

TimeIndependent プロパティTimeIndependent property

TimeIndependent プロパティは、効果のタイミングを合わせる必要がないかどうかを示します。The TimeIndependent property lets the system know if your effect does not require uniform timing. true に設定すると、効果のパフォーマンスを高めるために最適化を使用できるようになります。When set to true, the system can use optimizations that enhance effect performance.

public bool TimeIndependent { get { return true; } }

SetProperties メソッドSetProperties method

SetProperties メソッドは、呼び出し元のアプリで効果のパラメーターを調整するために使われます。The SetProperties method allows the app that is using your effect to adjust effect parameters. プロパティは、プロパティ名と値の IPropertySet マップとして渡されます。Properties are passed as an IPropertySet map of property names and values.

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

指定の値に基づいて各ビデオ フレームのピクセルを暗くする簡単な例を次に示します。This simple example will dim the pixels in each video frame according to a specified value. プロパティを宣言し、呼び出し元アプリで設定された値を TryGetValue で取得しています。A property is declared and TryGetValue is used to get the value set by the calling app. 値が設定されていない場合は、既定値の .5 が使われます。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;
    }
}

ProcessFrame メソッドProcessFrame method

ProcessFrame メソッドは、ビデオの画像データを変更するためのメソッドです。The ProcessFrame method is where your effect modifies the image data of the video. このメソッドはフレームごとに 1 回呼び出され、ProcessVideoFrameContext オブジェクトが渡されます。The method is called once per frame and is passed a ProcessVideoFrameContext object. このオブジェクトには、処理対象の着信フレームを格納する入力 VideoFrame オブジェクトと、ビデオ パイプラインの残りの部分に渡す画像データを書き込む出力 VideoFrame オブジェクトが含まれています。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. それらの VideoFrame オブジェクトのそれぞれに SoftwareBitmap プロパティと Direct3DSurface プロパティがありますが、どちらを使用できるかは SupportedMemoryTypes で指定した値で決まります。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.

ここでは、ソフトウェア処理を使用した ProcessFrame メソッドの簡単な実装例を示します。This example shows a simple implementation of the ProcessFrame method using software processing. SoftwareBitmap オブジェクトの操作について詳しくは、「イメージング」をご覧ください。For more information about working with SoftwareBitmap objects, see Imaging. ハードウェア処理を使用した ProcessFrame の実装例については、この記事の後半で紹介します。An example ProcessFrame implementation using hardware processing is shown later in this article.

SoftwareBitmap のデータ バッファーにアクセスするには COM 相互運用機能が必要になるため、効果のクラス ファイルに System.Runtime.InteropServices 名前空間を含める必要があります。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;

効果の名前空間に次のコードを追加して、画像のバッファーにアクセスするためのインターフェイスをインポートします。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);
}

注意

この手法では管理対象外のネイティブの画像バッファーにアクセスするため、アンセーフ コードを許可するようにプロジェクトを構成する必要があります。Because this technique accesses a native, unmanaged image buffer, you will need to configure your project to allow unsafe code.

  1. ソリューション エクスプローラーで、VideoEffectComponent プロジェクトを右クリックし、 [プロパティ] を選択します。In Solution Explorer, right-click the VideoEffectComponent project and select Properties.
  2. [ビルド] タブを選択します。Select the Build tab.
  3. [アンセーフ コードの許可] チェック ボックスをオンにします。Select the Allow unsafe code check box.

 

これで、ProcessFrame メソッドの実装を追加できます。Now you can add the ProcessFrame method implementation. 最初に、入力と出力の両方のソフトウェア ビットマップから BitmapBuffer オブジェクトを取得します。First, this method obtains a BitmapBuffer object from both the input and output software bitmaps. 出力フレームが書き込み用で、入力フレームが読み取り用です。Note that the output frame is opened for writing and the input for reading. 次に、CreateReference を呼び出して、各バッファーの IMemoryBufferReference を取得します。Next, an IMemoryBufferReference is obtained for each buffer by calling CreateReference. その後、実際のデータ バッファーを取得するために、先ほど定義した COM 相互運用機能のインターフェイス (IMemoryByteAccess) として IMemoryBufferReference オブジェクトをキャストし、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.

これで、データ バッファーが取得され、入力バッファーからの読み取りと出力バッファーへの書き込みが可能になります。Now that the data buffers have been obtained, you can read from the input buffer and write to the output buffer. GetPlaneDescription を呼び出して、バッファーのレイアウトを取得します。バッファーの幅、ストライド、初期オフセットについての情報が提供されます。The layout of the buffer is obtained by calling GetPlaneDescription, which provides information on the width, stride, and initial offset of the buffer. ピクセルあたりのビット数は、SetEncodingProperties メソッドで既に設定したエンコード プロパティで決まります。The bits per pixel is determined by the encoding properties set previously with the SetEncodingProperties method. バッファーの形式情報を使って、各ピクセルのバッファーへのインデックスを特定します。The buffer format information is used to find the index into the buffer for each pixel. ソース バッファーのピクセル値をターゲット バッファーにコピーし、そのカラー値にこの効果の FadeValue プロパティで定義した値を掛けます。これで、指定した値に応じてピクセルが暗くなります。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];
                }
            }
        }
    }
}

ハードウェア処理を使用した IBasicVideoEffect インターフェイスの実装Implement the IBasicVideoEffect interface using hardware processing

カスタムのビデオ特殊効果をハードウェア (GPU) 処理を使って作成する場合も、方法は上記のソフトウェア処理を使った場合とほぼ同じです。Creating a custom video effect by using hardware (GPU) processing is almost identical to using software processing as described above. このセクションでは、効果にハードウェア処理を使う場合のいくつかの違いについて説明します。This section will show the few differences in an effect that uses hardware processing. この例では、Win2D Windows ランタイム API を使います。This example uses the Win2D Windows Runtime API. Win2D を使う方法について詳しくは、Win2D のドキュメントをご覧ください。For more information about using Win2D, see the Win2D documentation.

次の手順に従って、この記事の最初に「アプリへのカスタム効果の追加」で作成したプロジェクトに Win2D NuGet パッケージを追加します。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.

効果プロジェクトに Win2D NuGet パッケージを追加するにはTo add the Win2D NuGet package to your effect project

  1. ソリューション エクスプローラーで、VideoEffectComponent プロジェクトを右クリックし、 [NuGet パッケージの管理] をクリックします。In Solution Explorer, right-click the VideoEffectComponent project and select Manage NuGet Packages.
  2. ウィンドウの上部で [参照] タブをクリックします。At the top of the window, select the Browse tab.
  3. 検索ボックスに 「Win2D」 と入力します。In the search box, enter Win2D.
  4. [Win2D.uwp] を選択し、右のウィンドウで [インストール] を選択します。Select Win2D.uwp, and then select Install in the right pane.
  5. [変更の確認] ダイアログに、インストールするパッケージが表示されます。The Review Changes dialog shows you the package to be installed. [OK] をクリックします。Click OK.
  6. パッケージのライセンスに同意します。Accept the package license.

基本的なプロジェクトのセットアップに含まれる名前空間に加え、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;

この効果では画像データの操作に GPU メモリを使うため、SupportedMemoryTypes プロパティで MediaMemoryTypes.Gpu を返します。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; } }

効果でサポートするエンコード プロパティを SupportedEncodingProperties プロパティで設定します。Set the encoding properties that your effect will support with the SupportedEncodingProperties property. Win2D を操作するときは、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 };
    }
}

SetEncodingProperties メソッドを使って、メソッドに渡される IDirect3DDevice から新しい Win2D CanvasDevice オブジェクトを作成します。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);
}

SetProperties の実装は前述のソフトウェア処理の例と同じです。The SetProperties implementation is identical to the previous software processing example. この例では、BlurAmount プロパティを使って 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;
    }
}

最後に、画像データを実際に処理する ProcessFrame メソッドを実装します。The last step is to implement the ProcessFrame method that actually processes the image data.

Win2D API を使って、入力フレームの Direct3DSurface プロパティから CanvasBitmap を作成します。Using Win2D APIs, a CanvasBitmap is created from the input frame's Direct3DSurface property. 出力フレームの Direct3DSurface から CanvasRenderTarget を作成し、このレンダー ターゲットから CanvasDrawingSession を作成します。A CanvasRenderTarget is created from the output frame's Direct3DSurface and a CanvasDrawingSession is created from this render target. 新しい Win2D GaussianBlurEffect を初期化し、SetPropertiesBlurAmount プロパティを使って効果を公開します。A new Win2D GaussianBlurEffect is initialized, using the BlurAmount property our effect exposes via SetProperties. 最後に、CanvasDrawingSession.DrawImage メソッドを呼び出して、入力ビットマップをレンダー ターゲットにぼかし効果を使って描画します。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);

    }
}

アプリへのカスタム効果の追加Adding your custom effect to your app

アプリからビデオ特殊効果を使うには、効果のプロジェクトへの参照をアプリに追加する必要があります。To use your video effect from your app, you must add a reference to the effect project to your app.

  1. ソリューション エクスプローラーで、アプリのプロジェクトの下にある [参照設定] を右クリックし、 [参照の追加] を選択します。In Solution Explorer, under your app project, right-click References and select Add reference.
  2. [プロジェクト] タブを展開し、 [ソリューション] を選択して、効果のプロジェクトの名前に対応するチェック ボックスをオンにします。Expand the Projects tab, select Solution, and then select the check box for your effect project name. この例では、VideoEffectComponent という名前です。For this example, the name is VideoEffectComponent.
  3. [OK] をクリックします。Click OK.

カメラのビデオ ストリームへのカスタム効果の追加Add your custom effect to a camera video stream

シンプルなカメラ プレビューへのアクセス」の手順に従って、カメラからのシンプルなプレビュー ストリームを設定できます。You can set up a simple preview stream from the camera by following the steps in the article Simple camera preview access. この手順を実行すると、カメラのビデオ ストリームへのアクセスに使う初期化済みの MediaCapture オブジェクトが得られます。Following those steps will provide you with an initialized MediaCapture object that is used to access the camera's video stream.

カスタムのビデオ特殊効果をカメラ ストリームに追加するには、まず、新しい VideoEffectDefinition オブジェクトを作成し、効果の名前空間とクラスの名前を渡します。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. 次に、MediaCapture オブジェクトの AddVideoEffect メソッドを呼び出して、指定したストリームに効果を追加します。Next, call the MediaCapture object's AddVideoEffect method to add your effect to the specified stream. この例では、MediaStreamType.VideoPreview 値を使って、効果をプレビュー ストリームに追加するように指定します。This example uses the MediaStreamType.VideoPreview value to specify that the effect should be added to the preview stream. アプリがビデオ キャプチャをサポートしている場合は、MediaStreamType.VideoRecord を使ってキャプチャ ストリームに効果を追加することもできます。If your app supports video capture, you could also use MediaStreamType.VideoRecord to add the effect to the capture stream. AddVideoEffect から、カスタム効果を表す IMediaExtension オブジェクトが返されます。AddVideoEffect returns an IMediaExtension object representing your custom effect. 効果の設定は SetProperties メソッドを使って設定できます。You can use the SetProperties method to set the configuration for your effect.

効果が追加されると、StartPreviewAsync が呼び出されてプレビュー ストリームが始まります。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();

MediaComposition のクリップへのカスタム効果の追加Add your custom effect to a clip in a MediaComposition

ビデオ クリップからメディア コンポジションを作成する一般的なガイダンスについては、「メディア コンポジションと編集」をご覧ください。For general guidance for creating media compositions from video clips, see Media compositions and editing. 次のコード スニペットは、カスタムのビデオ特殊効果を使ってシンプルなメディア コンポジションを作成する例を示しています。The following code snippet shows the creation of a simple media composition that uses a custom video effect. CreateFromFileAsync を呼び出して MediaClip オブジェクトを作成し、ユーザーが FileOpenPicker で選択したビデオ ファイルを渡して新しい 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. 次に、新しい VideoEffectDefinition オブジェクトを作成し、効果の名前空間とクラスの名前を渡します。Next a new VideoEffectDefinition object is created, passing in the namespace and class name for your effect to the constructor. 最後に、MediaClip オブジェクトの VideoEffectDefinitions コレクションに効果の定義を追加します。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);