You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让添加到MediaClip的每个VideoEffect实例展示不同数据

解决方案

1. 构造VideoEffectDefinition时传入自定义参数

VideoEffectDefinition支持第二个构造参数,类型为IPropertySet,你可以将每个剪辑对应的字幕文本、坐标、字号等自定义参数通过这个参数传入不同的效果实例:

// 为第一个剪辑创建带参数的效果定义
var clip0Props = new Windows.Foundation.Collections.PropertySet();
clip0Props.Add("SubtitleText", "第一个剪辑的字幕");
clip0Props.Add("TextX", 100f);
clip0Props.Add("TextY", 800f);
composition.Clips[0].VideoEffectDefinitions.Add(new VideoEffectDefinition(typeof(MyVideoEffect).FullName, clip0Props));

// 第二个剪辑传入不同参数
var clip1Props = new Windows.Foundation.Collections.PropertySet();
clip1Props.Add("SubtitleText", "第二个剪辑的字幕");
clip1Props.Add("TextX", 100f);
clip1Props.Add("TextY", 800f);
composition.Clips[1].VideoEffectDefinitions.Add(new VideoEffectDefinition(typeof(MyVideoEffect).FullName, clip1Props));

// 第三个剪辑同理
var clip2Props = new Windows.Foundation.Collections.PropertySet();
clip2Props.Add("SubtitleText", "第三个剪辑的字幕");
clip2Props.Add("TextX", 100f);
clip2Props.Add("TextY", 800f);
composition.Clips[2].VideoEffectDefinitions.Add(new VideoEffectDefinition(typeof(MyVideoEffect).FullName, clip2Props));

2. 自定义效果类实现IMediaExtension接口接收参数

所有UWP自定义媒体效果都需要实现IMediaExtension接口,系统会在效果实例初始化时自动调用SetProperties方法,将你传入的参数集合传递给效果实例,你只需要将参数存为私有字段供ProcessFrame调用即可:

public sealed class MyVideoEffect : IMediaExtension, IBasicVideoEffect
{
    // 存储传入的参数
    private string _subtitleText = string.Empty;
    private float _textX = 100f;
    private float _textY = 800f;
    private CanvasDevice canvasDevice;

    // 实现IMediaExtension接口的SetProperties方法,接收传入的参数
    public void SetProperties(IPropertySet configuration)
    {
        if (configuration.TryGetValue("SubtitleText", out object textObj))
        {
            _subtitleText = textObj as string ?? _subtitleText;
        }
        if (configuration.TryGetValue("TextX", out object xObj))
        {
            _textX = xObj is float x ? x : _textX;
        }
        if (configuration.TryGetValue("TextY", out object yObj))
        {
            _textY = yObj is float y ? y : _textY;
        }
    }

    // 你的原有ProcessFrame逻辑,直接使用存储的参数即可
    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()
            {
                FontSize = 40,
                HorizontalAlignment = CanvasHorizontalAlignment.Left
            };
            CanvasTextLayout textLayout = new CanvasTextLayout(canvasDevice, _subtitleText, textFormat, renderTarget.Size.Width, renderTarget.Size.Height);
            ds.DrawTextLayout(textLayout, _textX, _textY, Colors.Yellow);       
        }
    }

    // 其余IBasicVideoEffect接口的必要实现(你原有代码应该已经实现,这里省略)
    public bool IsReadOnly => false;
    public IReadOnlyList<VideoEncodingProperties> SupportedEncodingProperties => new List<VideoEncodingProperties>();
    public MediaMemoryTypes SupportedMemoryTypes => MediaMemoryTypes.Gpu;
    public void Close(MediaEffectClosedReason reason) { /* 原有资源释放逻辑 */ }
    public void DiscardQueuedFrames() { /* 原有逻辑 */ }
    public void SetEncodingProperties(VideoEncodingProperties encodingProperties, IDirect3DDevice device) 
    { 
        canvasDevice = CanvasDevice.CreateFromDirect3D11Device(device);
        /* 其余原有初始化逻辑 */ 
    }
}

注意事项

  • 传入PropertySet的参数只支持WinRT基础类型(字符串、数值、布尔值等),不支持自定义类实例
  • SetProperties会在效果实例初始化时、首次调用ProcessFrame之前执行,不需要额外做同步处理
  • 每个剪辑的效果实例是完全独立的,存储的参数不会互相干扰,完全不需要计时器或者其他额外逻辑来区分不同剪辑的字幕

内容的提问来源于stack exchange,提问作者M Psyllakis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 13:06:00