Last updated: July 16, 2026
YukkuriMovieMaker.Controls.dllYukkuriMovieMaker.Plugin.dllSharpGen.Runtime.dllSharpGen.Runtime.COM.dllVortice.Direct2D1.dllVortice.DirectX.dllVortice.Mathematics.dllIShapePluginShapeParameterBaseIShapeSourceこのサンプルを読み込ませると、YMM4の図形アイテムで使用できる図形として「サンプル四角形」が追加される。
Size プロパティに対応する「サイズ」が表示される。SampleShapeSource が描画した白い四角形が表示される。つまり、IShapePlugin がYMM4に「この図形を追加します」と伝え、ShapeParameterBase が編集項目を持ち、IShapeSource が実際の見た目を描画する。
まず動かすだけなら、次の流れでよい。
IShapePlugin を実装したクラスを作成する。ShapeParameterBase を継承したパラメータークラスを作成する。IShapeSource を実装した描画クラスを作成する。最初は Size だけを変更して、YMM4上の表示が変わることを確認するとよい。
ビルドしたdllは、YMM4のプラグインフォルダに配置する。
サンプルプロジェクトでは、ビルド後に次の場所へdllをコピーする設定になっている。
<Exec Command="mkdir "$(YMM4DirPath)user\plugin\$(ProjectName)" ... copy "$(TargetPath)" "$(YMM4DirPath)user\plugin\$(ProjectName)\"" />手動で配置する場合も、基本的にはYMM4本体側のプラグインフォルダに置く。
YukkuriMovieMaker4
└─ user
└─ plugin
└─ プラグイン名
└─ プラグイン名.dllYukkuriMovieMaker.Plugin.dll や YukkuriMovieMaker.Controls.dll など、YMM4本体に含まれるdllは、通常は同梱しない。参照リストにあるdllは「開発時に参照するもの」と「配布時に同梱するもの」を分けて考える必要がある。YMM4本体のdllとバージョンがずれると、ビルドは通ってもYMM4起動時にプラグインが読み込まれないことがある。
図形プラグインの名前や、図形パラメーターの生成処理を定義する。
GitHubより引用
public class SampleShapePlugin : IShapePlugin
{
public string Name => "サンプル四角形";
public bool IsExoShapeSupported => true;
public bool IsExoMaskSupported => true;
public IShapeParameter CreateShapeParameter(SharedDataStore? sharedData)
{
return new SampleShapeParameter(sharedData);
}
}Name プロパティで、YMM4上に表示される図形名を指定する。IsExoShapeSupported で、図形アイテムとしてのexo出力に対応しているかどうかを返す。IsExoMaskSupported で、図形切り抜きエフェクトやエフェクトアイテムなど、マスク系のexo出力に対応しているかどうかを返す。CreateShapeParameter 関数で、後述する ShapeParameterBase を継承したパラメータークラスを返す。sharedData は、図形の種類を切り替えたときに設定を復元するために使用する。Name が他の図形プラグインと被っていると、YMM4上で判別しづらくなるため、固有の名前にしておく。図形の設定項目、exo出力、図形ソースの生成処理を定義する。
GitHubより引用
internal class SampleShapeParameter(SharedDataStore? sharedData) : ShapeParameterBase(sharedData)
{
[Display(Name = "サイズ")]
[AnimationSlider("F0", "px", 0, 100)]
public Animation Size { get; } = new Animation(100, 0, 1000);
public SampleShapeParameter() : this(null)
{
}
public override IShapeSource CreateShapeSource(IGraphicsDevicesAndContext devices)
{
return new SampleShapeSource(devices, this);
}
protected override IEnumerable<IAnimatable> GetAnimatables() => [Size];
}Display 属性で項目名を指定し、AnimationSlider などのアイテム編集コントロール属性を付与する。CreateShapeSource 関数で、後述する描画処理用のクラスのインスタンスを返す。GetAnimatables 関数のオーバーライドでそのプロパティを入れた配列を返す。図形アイテムやマスクとしてexo出力する場合、対応する関数でAviUtl向けのフィルタ文字列を返す。
GitHubより引用
public override IEnumerable<string> CreateShapeItemExoFilter(int keyFrameIndex, ExoOutputDescription desc)
{
var fps = desc.VideoInfo.FPS;
return
[
$"_name=図形\r\n" +
$"サイズ={Size.ToExoString(keyFrameIndex, "F0", fps)}\r\n" +
$"縦横比=0\r\n" +
$"ライン幅=4000\r\n" +
$"type=0\r\n" +
$"color=FFFFFF\r\n" +
$"name=\r\n"
];
}CreateShapeItemExoFilter 関数では、図形アイテムとしてexo出力する際のフィルタを返す。CreateMaskExoFilter 関数では、図形切り抜きなどのマスクとしてexo出力する際のフィルタを返す。ToExoString を使用する。IShapePlugin 側の IsExoShapeSupported や IsExoMaskSupported を false にし、各関数では空配列を返してもよい。図形の描画処理を定義する。
GitHubより引用
internal class SampleShapeSource : IShapeSource
{
readonly private IGraphicsDevicesAndContext devices;
readonly private SampleShapeParameter sampleShapeParameter;
readonly ID2D1SolidColorBrush whiteBrush;
ID2D1CommandList? commandList;
public ID2D1Image Output => commandList ?? throw new Exception($"{nameof(commandList)}がnullです。事前にUpdateを呼び出す必要があります。");
public void Update(TimelineItemSourceDescription timelineItemSourceDescription)
{
var fps = timelineItemSourceDescription.FPS;
var frame = timelineItemSourceDescription.ItemPosition.Frame;
var length = timelineItemSourceDescription.ItemDuration.Frame;
var size = sampleShapeParameter.Size.GetValue(frame, length, fps);
// CommandListを作成し、白い四角形を描画する
}
}Output プロパティで、YMM4が読み取る描画結果を返す。IGraphicsDevicesAndContext と、上で定義した ShapeParameterBase の継承オブジェクトを保持する。Update 関数で、現在のフレーム、アイテムの長さ、FPSを取得し、設定項目の値を読み取る。ID2D1CommandList を作成し、FillRectangle で白い四角形を描画している。DeviceContext.Target に CommandList を設定した場合、描画後は必ず null に戻す。CommandList は EndDraw() の後に Close() を呼んで閉じる必要がある。CommandList やブラシなどのDirect2Dリソースは、Dispose 関数で開放する。図形の種類を切り替えたときに設定を復元する場合、LoadSharedData と SaveSharedData を実装する。
GitHubより引用
protected override void LoadSharedData(SharedDataStore store)
{
var sharedData = store.Load<SharedData>();
if (sharedData is null)
return;
sharedData.CopyTo(this);
}
protected override void SaveSharedData(SharedDataStore store)
{
store.Save(new SharedData(this));
}SaveSharedData 関数で、現在の設定を一時保存用クラスにコピーして保存する。LoadSharedData 関数で、保存されていた設定を読み込み、現在のパラメーターに反映する。Animation などの値は、参照をそのまま渡すのではなく、CopyFrom で中身をコピーする。IGraphicsDevicesAndContext は、YMM4側から渡される描画用のコンテキストです。
DeviceContext を取得できる。図形プラグインでは、この devices.DeviceContext を使って、ブラシや CommandList、PathGeometry などを作成する。
IShapeSource は、図形の描画を担当するクラスです。
Update 関数で、現在のフレームに合わせて描画内容を更新する。Output プロパティで、YMM4に描画結果を渡す。Dispose 関数でDirect2Dリソースを開放する。Update は、再生中のフレーム更新やパラメーター変更時に呼ばれる。リアルタイムプレビュー中は何度も呼ばれるため、毎回重い処理を行うとプレビューが重くなる。
サンプルでは、描画結果を ID2D1CommandList に記録して、それを Output として返している。
CommandList をそのまま使える。このサンプルでも、サイズが変わっていない場合は何もせずに戻る処理が入っている。
if (commandList != null && this.size == size)
return;リアルタイムプレビューを前提にするYMM4では、このようなキャッシュが重要になる。
図形プラグインはプレビュー中に頻繁に更新されるため、次の点に注意する。
new しない。CommandList や PathGeometry を作り直す場合は、前回のものを必ず Dispose する。DeviceContext.Target を変更した場合は、描画後に必ず null に戻す。特に Update の中で毎回ブラシやGeometryを作ると、プレビューが重くなったり、リソースの開放漏れで不安定になったりする。
SamplePolygonShapePlugin では、複数の頂点を持つ多角形を描画します。
GitHubより引用
IShapeSource2VideoControllerControllerPointID2D1PathGeometry多角形の各頂点は、SamplePolygonShapePoint クラスで定義されている。
public class SamplePolygonShapePoint : Animatable
{
[Display(GroupName = "頂点", Name = "X")]
[AnimationSlider("F1", "px", -500, 500)]
public Animation X { get; } = new Animation(0, -100000, 100000);
[Display(GroupName = "頂点", Name = "Y")]
[AnimationSlider("F1", "px", -500, 500)]
public Animation Y { get; } = new Animation(0, -100000, 100000);
protected override IEnumerable<IAnimatable> GetAnimatables() => [X, Y];
}X と Y の Animation を持つ。GetAnimatables 関数で X と Y を返すことで、頂点の座標をアニメーション可能にしている。SamplePolygonShapeParameter 側では、この頂点のリストを ImmutableList<SamplePolygonShapePoint> として保持している。SamplePolygonShapeSource は IShapeSource2 を実装し、描画結果に加えてプレビュー上の制御点を提供する。
public IEnumerable<VideoController> Controllers { get; private set; } = [];Controllers プロパティで、プレビュー上に表示する制御点を返す。ControllerPoint を作成し、ドラッグされたときに頂点の X と Y に移動量を加算する。IShapeSource2 が重要になる。IShapeSource でよいが、頂点やハンドルをユーザーに触らせたい場合は IShapeSource2 を使う。多角形の描画には ID2D1PathGeometry を使用する。
using (var sink = geometry.Open())
{
sink.BeginFigure(points[0], FigureBegin.Filled);
sink.AddLines(points[1..]);
sink.EndFigure(FigureEnd.Closed);
sink.Close();
}BeginFigure で最初の頂点を指定する。AddLines で残りの頂点を追加する。EndFigure(FigureEnd.Closed) で図形を閉じる。PathGeometry を FillGeometry に渡すことで、多角形を塗りつぶして描画する。SampleShapePlugin は、サイズだけを持つ単純な四角形。SamplePolygonShapePlugin は、頂点リストを持つ多角形。SampleShapePlugin は IShapeSource を実装する。SamplePolygonShapePlugin は IShapeSource2 を実装し、プレビュー上の制御点も提供する。YMM4プラグインでは、コードが正しく見えても読み込みや表示で詰まることがある。
YukkuriMovieMaker.Plugin.dll など、参照しているYMM4本体のdllが現在使っているYMM4のものか確認する。IShapePlugin を実装したクラスがあるか確認する。Name が他の図形と被っていないか確認する。ShapeParameterBase を継承したクラスに、引数なしコンストラクタがあるか確認する。LoadSharedData と SaveSharedData で、参照をそのまま使い回していないか確認する。Update が呼ばれる前に Output が参照されても問題ない作りになっているか確認する。commandList を作成しているか確認する。dc.EndDraw() の後に commandList.Close() を呼んでいるか確認する。dc.Target = null に戻しているか確認する。Update 内で毎回Direct2Dリソースを作り続けていないか確認する。CommandList、Geometry、Brush を Dispose しているか確認する。SampleShapePlugin が動いたら、次は次のような変更を試すとよい。
FillRectangle を変更して、円や楕円を描画する。Size 以外のパラメーターを追加する。IShapeSource2 を使って、プレビュー上で操作できる制御点を追加する。まず図形プラグインを作成する場合は、SampleShapePlugin のように、IShapePlugin、ShapeParameterBase、IShapeSource の3つを用意する構成から始めるとよい。
Last updated: July 16, 2026
YukkuriMovieMaker.Controls.dllYukkuriMovieMaker.Plugin.dllSharpGen.Runtime.dllSharpGen.Runtime.COM.dllVortice.Direct2D1.dllVortice.DirectX.dllVortice.Mathematics.dllIShapePluginShapeParameterBaseIShapeSourceこのサンプルを読み込ませると、YMM4の図形アイテムで使用できる図形として「サンプル四角形」が追加される。
Size プロパティに対応する「サイズ」が表示される。SampleShapeSource が描画した白い四角形が表示される。つまり、IShapePlugin がYMM4に「この図形を追加します」と伝え、ShapeParameterBase が編集項目を持ち、IShapeSource が実際の見た目を描画する。
まず動かすだけなら、次の流れでよい。
IShapePlugin を実装したクラスを作成する。ShapeParameterBase を継承したパラメータークラスを作成する。IShapeSource を実装した描画クラスを作成する。最初は Size だけを変更して、YMM4上の表示が変わることを確認するとよい。
ビルドしたdllは、YMM4のプラグインフォルダに配置する。
サンプルプロジェクトでは、ビルド後に次の場所へdllをコピーする設定になっている。
<Exec Command="mkdir "$(YMM4DirPath)user\plugin\$(ProjectName)" ... copy "$(TargetPath)" "$(YMM4DirPath)user\plugin\$(ProjectName)\"" />手動で配置する場合も、基本的にはYMM4本体側のプラグインフォルダに置く。
YukkuriMovieMaker4
└─ user
└─ plugin
└─ プラグイン名
└─ プラグイン名.dllYukkuriMovieMaker.Plugin.dll や YukkuriMovieMaker.Controls.dll など、YMM4本体に含まれるdllは、通常は同梱しない。参照リストにあるdllは「開発時に参照するもの」と「配布時に同梱するもの」を分けて考える必要がある。YMM4本体のdllとバージョンがずれると、ビルドは通ってもYMM4起動時にプラグインが読み込まれないことがある。
図形プラグインの名前や、図形パラメーターの生成処理を定義する。
GitHubより引用
public class SampleShapePlugin : IShapePlugin
{
public string Name => "サンプル四角形";
public bool IsExoShapeSupported => true;
public bool IsExoMaskSupported => true;
public IShapeParameter CreateShapeParameter(SharedDataStore? sharedData)
{
return new SampleShapeParameter(sharedData);
}
}Name プロパティで、YMM4上に表示される図形名を指定する。IsExoShapeSupported で、図形アイテムとしてのexo出力に対応しているかどうかを返す。IsExoMaskSupported で、図形切り抜きエフェクトやエフェクトアイテムなど、マスク系のexo出力に対応しているかどうかを返す。CreateShapeParameter 関数で、後述する ShapeParameterBase を継承したパラメータークラスを返す。sharedData は、図形の種類を切り替えたときに設定を復元するために使用する。Name が他の図形プラグインと被っていると、YMM4上で判別しづらくなるため、固有の名前にしておく。図形の設定項目、exo出力、図形ソースの生成処理を定義する。
GitHubより引用
internal class SampleShapeParameter(SharedDataStore? sharedData) : ShapeParameterBase(sharedData)
{
[Display(Name = "サイズ")]
[AnimationSlider("F0", "px", 0, 100)]
public Animation Size { get; } = new Animation(100, 0, 1000);
public SampleShapeParameter() : this(null)
{
}
public override IShapeSource CreateShapeSource(IGraphicsDevicesAndContext devices)
{
return new SampleShapeSource(devices, this);
}
protected override IEnumerable<IAnimatable> GetAnimatables() => [Size];
}Display 属性で項目名を指定し、AnimationSlider などのアイテム編集コントロール属性を付与する。CreateShapeSource 関数で、後述する描画処理用のクラスのインスタンスを返す。GetAnimatables 関数のオーバーライドでそのプロパティを入れた配列を返す。図形アイテムやマスクとしてexo出力する場合、対応する関数でAviUtl向けのフィルタ文字列を返す。
GitHubより引用
public override IEnumerable<string> CreateShapeItemExoFilter(int keyFrameIndex, ExoOutputDescription desc)
{
var fps = desc.VideoInfo.FPS;
return
[
$"_name=図形\r\n" +
$"サイズ={Size.ToExoString(keyFrameIndex, "F0", fps)}\r\n" +
$"縦横比=0\r\n" +
$"ライン幅=4000\r\n" +
$"type=0\r\n" +
$"color=FFFFFF\r\n" +
$"name=\r\n"
];
}CreateShapeItemExoFilter 関数では、図形アイテムとしてexo出力する際のフィルタを返す。CreateMaskExoFilter 関数では、図形切り抜きなどのマスクとしてexo出力する際のフィルタを返す。ToExoString を使用する。IShapePlugin 側の IsExoShapeSupported や IsExoMaskSupported を false にし、各関数では空配列を返してもよい。図形の描画処理を定義する。
GitHubより引用
internal class SampleShapeSource : IShapeSource
{
readonly private IGraphicsDevicesAndContext devices;
readonly private SampleShapeParameter sampleShapeParameter;
readonly ID2D1SolidColorBrush whiteBrush;
ID2D1CommandList? commandList;
public ID2D1Image Output => commandList ?? throw new Exception($"{nameof(commandList)}がnullです。事前にUpdateを呼び出す必要があります。");
public void Update(TimelineItemSourceDescription timelineItemSourceDescription)
{
var fps = timelineItemSourceDescription.FPS;
var frame = timelineItemSourceDescription.ItemPosition.Frame;
var length = timelineItemSourceDescription.ItemDuration.Frame;
var size = sampleShapeParameter.Size.GetValue(frame, length, fps);
// CommandListを作成し、白い四角形を描画する
}
}Output プロパティで、YMM4が読み取る描画結果を返す。IGraphicsDevicesAndContext と、上で定義した ShapeParameterBase の継承オブジェクトを保持する。Update 関数で、現在のフレーム、アイテムの長さ、FPSを取得し、設定項目の値を読み取る。ID2D1CommandList を作成し、FillRectangle で白い四角形を描画している。DeviceContext.Target に CommandList を設定した場合、描画後は必ず null に戻す。CommandList は EndDraw() の後に Close() を呼んで閉じる必要がある。CommandList やブラシなどのDirect2Dリソースは、Dispose 関数で開放する。図形の種類を切り替えたときに設定を復元する場合、LoadSharedData と SaveSharedData を実装する。
GitHubより引用
protected override void LoadSharedData(SharedDataStore store)
{
var sharedData = store.Load<SharedData>();
if (sharedData is null)
return;
sharedData.CopyTo(this);
}
protected override void SaveSharedData(SharedDataStore store)
{
store.Save(new SharedData(this));
}SaveSharedData 関数で、現在の設定を一時保存用クラスにコピーして保存する。LoadSharedData 関数で、保存されていた設定を読み込み、現在のパラメーターに反映する。Animation などの値は、参照をそのまま渡すのではなく、CopyFrom で中身をコピーする。IGraphicsDevicesAndContext は、YMM4側から渡される描画用のコンテキストです。
DeviceContext を取得できる。図形プラグインでは、この devices.DeviceContext を使って、ブラシや CommandList、PathGeometry などを作成する。
IShapeSource は、図形の描画を担当するクラスです。
Update 関数で、現在のフレームに合わせて描画内容を更新する。Output プロパティで、YMM4に描画結果を渡す。Dispose 関数でDirect2Dリソースを開放する。Update は、再生中のフレーム更新やパラメーター変更時に呼ばれる。リアルタイムプレビュー中は何度も呼ばれるため、毎回重い処理を行うとプレビューが重くなる。
サンプルでは、描画結果を ID2D1CommandList に記録して、それを Output として返している。
CommandList をそのまま使える。このサンプルでも、サイズが変わっていない場合は何もせずに戻る処理が入っている。
if (commandList != null && this.size == size)
return;リアルタイムプレビューを前提にするYMM4では、このようなキャッシュが重要になる。
図形プラグインはプレビュー中に頻繁に更新されるため、次の点に注意する。
new しない。CommandList や PathGeometry を作り直す場合は、前回のものを必ず Dispose する。DeviceContext.Target を変更した場合は、描画後に必ず null に戻す。特に Update の中で毎回ブラシやGeometryを作ると、プレビューが重くなったり、リソースの開放漏れで不安定になったりする。
SamplePolygonShapePlugin では、複数の頂点を持つ多角形を描画します。
GitHubより引用
IShapeSource2VideoControllerControllerPointID2D1PathGeometry多角形の各頂点は、SamplePolygonShapePoint クラスで定義されている。
public class SamplePolygonShapePoint : Animatable
{
[Display(GroupName = "頂点", Name = "X")]
[AnimationSlider("F1", "px", -500, 500)]
public Animation X { get; } = new Animation(0, -100000, 100000);
[Display(GroupName = "頂点", Name = "Y")]
[AnimationSlider("F1", "px", -500, 500)]
public Animation Y { get; } = new Animation(0, -100000, 100000);
protected override IEnumerable<IAnimatable> GetAnimatables() => [X, Y];
}X と Y の Animation を持つ。GetAnimatables 関数で X と Y を返すことで、頂点の座標をアニメーション可能にしている。SamplePolygonShapeParameter 側では、この頂点のリストを ImmutableList<SamplePolygonShapePoint> として保持している。SamplePolygonShapeSource は IShapeSource2 を実装し、描画結果に加えてプレビュー上の制御点を提供する。
public IEnumerable<VideoController> Controllers { get; private set; } = [];Controllers プロパティで、プレビュー上に表示する制御点を返す。ControllerPoint を作成し、ドラッグされたときに頂点の X と Y に移動量を加算する。IShapeSource2 が重要になる。IShapeSource でよいが、頂点やハンドルをユーザーに触らせたい場合は IShapeSource2 を使う。多角形の描画には ID2D1PathGeometry を使用する。
using (var sink = geometry.Open())
{
sink.BeginFigure(points[0], FigureBegin.Filled);
sink.AddLines(points[1..]);
sink.EndFigure(FigureEnd.Closed);
sink.Close();
}BeginFigure で最初の頂点を指定する。AddLines で残りの頂点を追加する。EndFigure(FigureEnd.Closed) で図形を閉じる。PathGeometry を FillGeometry に渡すことで、多角形を塗りつぶして描画する。SampleShapePlugin は、サイズだけを持つ単純な四角形。SamplePolygonShapePlugin は、頂点リストを持つ多角形。SampleShapePlugin は IShapeSource を実装する。SamplePolygonShapePlugin は IShapeSource2 を実装し、プレビュー上の制御点も提供する。YMM4プラグインでは、コードが正しく見えても読み込みや表示で詰まることがある。
YukkuriMovieMaker.Plugin.dll など、参照しているYMM4本体のdllが現在使っているYMM4のものか確認する。IShapePlugin を実装したクラスがあるか確認する。Name が他の図形と被っていないか確認する。ShapeParameterBase を継承したクラスに、引数なしコンストラクタがあるか確認する。LoadSharedData と SaveSharedData で、参照をそのまま使い回していないか確認する。Update が呼ばれる前に Output が参照されても問題ない作りになっているか確認する。commandList を作成しているか確認する。dc.EndDraw() の後に commandList.Close() を呼んでいるか確認する。dc.Target = null に戻しているか確認する。Update 内で毎回Direct2Dリソースを作り続けていないか確認する。CommandList、Geometry、Brush を Dispose しているか確認する。SampleShapePlugin が動いたら、次は次のような変更を試すとよい。
FillRectangle を変更して、円や楕円を描画する。Size 以外のパラメーターを追加する。IShapeSource2 を使って、プレビュー上で操作できる制御点を追加する。まず図形プラグインを作成する場合は、SampleShapePlugin のように、IShapePlugin、ShapeParameterBase、IShapeSource の3つを用意する構成から始めるとよい。