🎯 はじめに
AviUtl2 beta17 SDKに含まれる plugin2.h を元に、
Delphi で動作する汎用プラグイン(拡張子 .aux2)を実装しました。
このサンプルでは、AviUtl2 上に独自ウィンドウを追加し、
ボタン操作でシーン情報(フレーム/レイヤーなど)を取得・表示する最小構成になっています。
🧠 背景と目的
AviUtl2 SDK では以下の 5 種類のプラグイン形式が定義されています。
| 種類 | 拡張子 | 役割 |
|---|---|---|
| Input Plugin | .aui2 |
ファイル入力(画像・動画など) |
| Output Plugin | .auo2 |
ファイル出力 |
| Filter Plugin | .auf2 |
画像や音声の加工 |
| Script Module | .mod2 |
Luaスクリプト拡張 |
| Generic Plugin | .aux2 |
アプリ全体の拡張(ウィンドウ・メニューなど) |
今回はその中の Generic Plugin (.aux2) を使用しています。
これは AviUtl2 にウィンドウやボタンなどの「機能拡張UI」を追加できる仕組みで、
入力/出力/フィルタとは独立して動作します。
💡 実装方針
- Delphi で
plugin2.hの構造体を再現 -
RegisterPlugin()から AviUtl2 にウィンドウを登録 -
CallEditSection()経由で AviUtl2 の編集情報に安全にアクセス - 取得結果をウィンドウ上のラベルやメッセージボックスに表示
AviUtl2 側から呼び出されるため、DLL は通常の EXE とは異なり
AviUtl2 実行中にロードされる動的モジュールとして扱われます。
🧩 サンプルコード
Delphi での主要部分は以下の通りです。
library AviUtl2Plugin;
uses
Windows, Messages, SysUtils, Classes;
const
SampleWindowName = 'DelphiPSDControl';
IDC_BUTTON_INFO = 1001;
IDC_LABEL_INFO = 1002;
type
TObjectHandle = Pointer;
TObjectFrameInfo = record
StartFrame: Integer;
EndFrame: Integer;
end;
PEditInfo = ^TEditInfo;
TEditInfo = record
Width, Height: Integer;
Rate, Scale: Integer;
SampleRate: Integer;
Frame, Layer: Integer;
FrameMax, LayerMax: Integer;
end;
PEditSection = ^TEditSection;
TEditSection = record
Info: PEditInfo;
CreateObjectFromAlias: function(Alias: PAnsiChar; Layer, Frame, Length: Integer): TObjectHandle; cdecl;
FindObject: function(Layer, Frame: Integer): TObjectHandle; cdecl;
GetObjectFrameInfo: function(Obj: TObjectHandle): TObjectFrameInfo; cdecl;
end;
TProcEditSection = procedure(Edit: PEditSection); cdecl;
PEditHandle = ^TEditHandle;
TEditHandle = record
CallEditSection: function(FuncProcEdit: TProcEditSection): BOOL; cdecl;
end;
PInputPluginTable = Pointer;
POutputPluginTable = Pointer;
PFilterPluginTable = Pointer;
PScriptModuleTable = Pointer;
PHOST_APP_TABLE = ^THostAppTable;
THostAppTable = record
SetPluginInformation: procedure(Info: PWideChar); cdecl;
RegisterInputPlugin: procedure(InputTable: PInputPluginTable); cdecl;
RegisterOutputPlugin: procedure(OutputTable: POutputPluginTable); cdecl;
RegisterFilterPlugin: procedure(FilterTable: PFilterPluginTable); cdecl;
RegisterScriptModule: procedure(ScriptTable: PScriptModuleTable); cdecl;
RegisterImportMenu: procedure(Name: PWideChar; Func: TProcEditSection); cdecl;
RegisterExportMenu: procedure(Name: PWideChar; Func: TProcEditSection); cdecl;
RegisterWindowClient: procedure(Name: PWideChar; HWnd: HWND); cdecl;
CreateEditHandle: function(): PEditHandle; cdecl;
end;
var
EditHandle: PEditHandle = nil;
LabelWnd : HWND = 0;
{-------------------------------------------------------------}
{ シーン情報取得とラベル更新 }
{-------------------------------------------------------------}
procedure ShowSceneInfo(Edit: PEditSection); cdecl;
var
Info: PEditInfo;
S: string;
begin
if (Edit = nil) or (Edit^.Info = nil) then Exit;
Info := Edit^.Info;
S := Format('Scene Info:'#13#10 +
'Size: %d x %d'#13#10 +
'Rate/Scale: %d / %d'#13#10 +
'Frame: %d / %d'#13#10 +
'Layer: %d / %d',
[Info^.Width, Info^.Height,
Info^.Rate, Info^.Scale,
Info^.Frame, Info^.FrameMax,
Info^.Layer, Info^.LayerMax]);
if LabelWnd <> 0 then
SetWindowTextW(LabelWnd, PWideChar(WideString(S)));
end;
{-------------------------------------------------------------}
{ ウィンドウプロシージャ }
{-------------------------------------------------------------}
function WndProc(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
case uMsg of
WM_COMMAND:
if LOWORD(wParam) = IDC_BUTTON_INFO then
begin
if Assigned(EditHandle) then
EditHandle^.CallEditSection(@ShowSceneInfo)
else
MessageBox(hWnd, 'EditHandleが無効です。', 'Error', MB_ICONERROR);
Exit(0);
end;
end;
Result := DefWindowProc(hWnd, uMsg, wParam, lParam);
end;
{-------------------------------------------------------------}
{ プラグイン登録関数(AviUtl2本体から呼び出される) }
{-------------------------------------------------------------}
procedure RegisterPlugin(Host: PHOST_APP_TABLE); cdecl;
var
WndClass: WNDCLASSEXW;
MainWnd: HWND;
begin
Host^.SetPluginInformation('Delphi AviUtl2 Scene Info Viewer');
// ウィンドウクラス登録
FillChar(WndClass, SizeOf(WndClass), 0);
WndClass.cbSize := SizeOf(WndClass);
WndClass.lpszClassName := SampleWindowName;
WndClass.lpfnWndProc := @WndProc;
WndClass.hInstance := HInstance;
WndClass.hbrBackground := GetSysColorBrush(COLOR_WINDOW);
WndClass.hCursor := LoadCursor(0, IDC_ARROW);
RegisterClassExW(WndClass);
// メインウィンドウ作成
MainWnd := CreateWindowExW(
0, // 拡張スタイル(0なら特に無し)
SampleWindowName, // クラス名
'Scene Info Viewer',// ウィンドウタイトル(AviUtl内では使われない)
WS_POPUP, // スタイル(RegisterWindowClientで子ウィンドウ化される)
CW_USEDEFAULT, // X座標(AviUtlが配置を制御するので無視される)
CW_USEDEFAULT, // Y座標(同上)
260, // ★ 幅(Width)
140, // ★ 高さ(Height)
0, 0, HInstance, nil
);
// ------------------------------------------------------
// ボタンを作成
// ------------------------------------------------------
CreateWindowExW(
0, // 拡張スタイル(特になし)
'BUTTON', // クラス名(ボタン)
'シーン情報取得', // ボタンに表示する文字列
WS_VISIBLE or WS_CHILD or BS_PUSHBUTTON, // スタイル:子ウィンドウ+押しボタン
30, // X座標(左から30px)
15, // Y座標(上から15px)
200, // 幅(260px全体のうち中央寄り)
30, // 高さ(一般的なボタン高さ)
MainWnd, // 親ウィンドウハンドル
IDC_BUTTON_INFO, // コントロールID
HInstance, // インスタンスハンドル
nil // 追加パラメータ(未使用)
);
// ------------------------------------------------------
// ラベルを作成
// ------------------------------------------------------
LabelWnd := CreateWindowExW(
0, // 拡張スタイル(特になし)
'STATIC', // クラス名(静的テキスト)
'未取得', // 初期テキスト
WS_VISIBLE or WS_CHILD or SS_LEFT or SS_NOTIFY, // 左寄せ・クリック通知あり
30, // X座標(左から30px)
55, // Y座標(ボタンの下、約40px下げ)
200, // 幅(ボタンと同じ200px)
120, // 高さ(複数行テキストのため余裕を確保)
MainWnd, // 親ウィンドウハンドル
IDC_LABEL_INFO, // コントロールID
HInstance, // インスタンスハンドル
nil // 追加パラメータ(未使用)
);
// AviUtl2本体へ登録
Host^.RegisterWindowClient(SampleWindowName, MainWnd);
// 編集ハンドルを取得
EditHandle := Host^.CreateEditHandle;
end;
exports
RegisterPlugin;
begin
end.
AviUtl2 でロードすると、
独自ウィンドウ内に「シーン情報取得」ボタンが追加されます。
🖥️ 実行結果
ボタンを押すと、AviUtl2 の現在シーン情報を取得して
メッセージボックスやラベルに表示します。

⚙️ ビルド手順
-
AviUtl2Plugin.dprを Delphi で開く - Win32 DLL としてビルド
- 出力ファイルをリネーム:
AviUtl2Plugin.dll → AviUtl2Plugin.aux2 -
AviUtl2Plugin.aux2を AviUtl2 フォルダに配置 - AviUtl2 起動後、「ウィンドウクライアント」に追加されていることを確認
🧱 応用可能性
この .aux2 形式は「アプリ全体の拡張」に相当するため、
複数のプラグインを統合する UI ハブとしても活用できます。
たとえば:
-
.aui2(入力プラグイン)で PSD ファイルを読み込み -
.aux2(汎用プラグイン)でレイヤー表示/非表示設定を制御 -
.auf2(フィルタプラグイン)で描画調整を行う
という構成を取ることで、
PSD Toolkit のような複数モジュール連携が Delphi 側からも実現可能になります。
🧭 今後の展開
- PSDファイルレイヤーの表示/非表示切替UIを追加
- Base64化されたレイヤー設定をテキストボックスに保存
- 入力プラグインとの連携によるリアルタイム更新
この仕組みを基礎にして、AviUtl2 上で
「PSDファイルを編集・制御できる完全な描画拡張」を構築していく予定です。
📦 GitHub リポジトリ
本サンプルは GitHub にて公開中です: