How Can I Make A VideoEffect Display Different Data Each Time It Is Added To A MediaClip?

63 views Asked by At

Okay, I have a media composition and have added to it 3 media clips...

MediaComposition composition = new MediaComposition();

MediaClip clip1 = await MediaClip.CreateFromFileAsync(file);
MediaClip clip2 = await MediaClip.CreateFromFileAsync(file);
MediaClip clip3 = await MediaClip.CreateFromFileAsync(file);

composition.Clips.Add(clip1);
composition.Clips.Add(clip2;
composition.Clips.Add(clip3);

Now I want each clip to display a distinct caption and to accomplish this I have written a custom video effect that uses the DrawTextLayout method of the Win2D API. Let me be clear, I don't want to do this with overlays! But since video effects are built using the factory design pattern, how would I go about loading different data on each instance of the video effect?

Here is the core of MyVideoEffect:

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())
    {
    CanvasTextFormat textFormat = new CanvasTextFormat();
    CanvasTextLayout textLayout = new CanvasTextLayout(canvasDevice, text, textFormat, width, height);
            ds.DrawTextLayout(someTextLayout, x, y, Colors.Yellow);       
    }
}

Here, the "text" parameter should have a different value each time.

How can I specify the unique value when adding the video effect?

composition.Clips[0].VideoEffectDefinitions.Add(new VideoEffectDefinition(typeof(MyVideoEffect).FullName));
composition.Clips[1].VideoEffectDefinitions.Add(new VideoEffectDefinition(typeof(MyVideoEffect).FullName));
composition.Clips[2].VideoEffectDefinitions.Add(new VideoEffectDefinition(typeof(MyVideoEffect).FullName));

Is there an elegant way of doing this hopefully without having to resort to timers?

1

There are 1 answers

0
escape-llc On

I know this is way late, but the VideoEffectDefinition constructor has an overload taking PropertySet and this is how you can initialize each instance with different properties.

PropertySet config = new PropertySet();
config.Add("Pipeline", SelectedPipeline);
var vd = new VideoEffectDefinition(typeof(PipelineEffect).FullName, config);
mc.VideoEffectDefinitions.Add(vd);
var mcp = new MediaComposition();
mcp.Clips.Add(mc);
var ms = MediaSource.CreateFromMediaStreamSource(mcp.GenerateMediaStreamSource());