agentsclimarketplace

Fcp image overlay

Skill kiwamust/fcp-six-skills/skills/fcp-image-overlay

Final Cut Pro の video 要素 (PNG/SVG画像) を FCPXML で実装する。 シネマティック帯、半透明box、ロケーションカード、地図アニメ、グラフィック挿入カットなど 「画像系オーバーレイ」専用。video.adjust-transform position の単位 (4K canvas基準で 1080px=50unit、変換係数 1/21.6) を扱う。SVG → rsvg-convert → rgba PNG変換、 format個別定義(r1共有のNG)、transparent alpha の扱い、 lane合成順を含む。 「帯」「シネマ帯」「box」「PNGオーバーレイ」「SVG」「装飾」「ロケーションカード」 「画像挿入」「グラフィック」「rsvg-convert」「半透明」「adjust-transform」等で発動。 テキスト系オーバーレイは fcp-titles、 spine構造変更は fcp-spine-edit、 基本のFCPXML仕様は dji-fcpxml。From its SKILL.md

Install
npx -y skills add kiwamust/fcp-six-skills --skill fcp-image-overlay

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

11.3 KB, ~3.7k tokens by cl100k_base, as published. Nobody here has run it

fcp-image-overlay — FCP の video 要素(PNG/SVG画像オーバーレイ)

<video> 要素は FCPXML 1.13 で PNG/SVG画像 asset をタイムライン上にオーバーレイするための要素。シネマティック帯、半透明box、ロケーションカード、地図アニメ、挿入カットの装飾画像などに使う。

核となる教訓

  • adjust-transform position は 4K canvas基準の独自unit(1080px = 50 unit、変換係数 1/21.6)
  • format は PNGネイティブサイズで個別定義(r1=4K共有だと画像が4Kに伸びる)
  • start="3600s" が必須"0s" だとFCPが処理できない場合あり)
  • 半透明PNGは SVG → rsvg-convert で生成(ffmpeg 直生成は alpha がFCPで効かない)
  • resource ID は動的取得(FCPがclip削除等で再番号付けする)

1. asset 定義(PNG/SVG)

<resources>
    <!-- format は PNG ネイティブサイズで個別定義 (重要: r1共有だとFCPが4Kに伸ばす) -->
    <format id="g_xxx_fmt" name="FFVideoFormatRateUndefined"
            width="<png_width>" height="<png_height>" colorSpace="1-13-1"/>

    <asset id="g_xxx" name="..." start="0s" duration="0s"
           hasVideo="1" format="g_xxx_fmt" videoSources="1">
        <media-rep kind="original-media"
                   src="file:///abs/path/to/image.png"/>
    </asset>
</resources>

2. video 要素の正規構造

<asset-clip ref="rX" ...>
    <video ref="g_xxx" lane="3"
           offset="<親asset-clip.start値>"
           name="..."
           start="3600s"
           duration="<dur>">
        <adjust-transform position="<x_unit> <y_unit>"/>
    </video>
</asset-clip>

決定的ポイント

項目真値注意
start"3600s" 必須generator系の標準
Position<adjust-transform position="x y"/>4K canvas unit(1080px=50unit)
formatPNG ネイティブサイズで個別定義r1 (sequence format=4K) 共有はNG
media-repsrc 絶対パスbookmark なくても動くが、FCP再import時に消える可能性
lane字幕より小さい数値が奥帯=lane1,2、字幕=lane3,4

3. position の単位(重要)

video の <adjust-transform position="x y"/>4K canvas基準の独自単位:

  • 中央: (0, 0)
  • y=50 で画面上端 (4K canvas height 1080 px = 50 unit)
  • y=-50 で画面下端
  • 変換係数: 1 unit = 21.6 pixel (4K canvas基準)

Inspector ↔ XML の対応

  • Inspector で Y=950 (pixel) に動かす → XML 上は position="0 43.9815" (= 950/21.6)
  • 逆に XML で position="0 43.9815" → Inspector では Y=950

title (1920x1080基準pixel) との変換

字幕(title.Position)と帯(video.adjust-transform)を 画面の同じ高さに並べる:

PIXEL_TO_UNIT = 2.0 / 21.6  # ≈ 0.0926

# 例: 字幕 title.Position y=494 (1920基準) と帯 video.position y=45.74 (4K unit) は画面上で同じ高さ
title_y_pixel = 494          # title.Position の Y
video_y_unit = title_y_pixel * PIXEL_TO_UNIT  # ≈ 45.74

理由:

  • title.Position は 1920x1080 基準なので、4K canvas pixel に換算すると ×2
  • 4K canvas pixel → unit に換算すると ÷21.6
  • 合わせて ×2/21.6 ≈ ×0.0926

4. 半透明 PNG は SVG → rsvg-convert が確実

ffmpeg で [email protected] を生成すると pix_fmt=rgb24 になり、FCPで透明度が効かない。

確実な手順

# 1. SVG で fill-opacity を明示
cat > /path/glass-bar.svg <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 92" width="1920" height="92">
    <rect x="0" y="0" width="1920" height="92" fill="black" fill-opacity="0.5"/>
</svg>
EOF

# 2. rsvg-convert で rgba PNG に変換 (SVG alpha が PNG alpha チャンネルに保持される)
rsvg-convert -w 1920 -h 92 /path/glass-bar.svg > /path/glass-bar.png

# 3. 検証
ffprobe -v error -select_streams v:0 -show_entries stream=pix_fmt -of csv=p=0 /path/glass-bar.png
# → rgba (rgb24 でないこと)

magick /path/glass-bar.png -format "%[pixel:p{50,50}]" info:
# → srgba(0,0,0,0.501961) のように alpha が保持されていれば OK

なぜ ffmpeg 直生成はダメか

  • ffmpeg -pix_fmt rgba 指定でも、FCPが alpha を「ストレートalpha vs pre-multiplied alpha」のどちらに解釈すべきか判別できず、結果として alpha が無視される
  • SVG は vector レベルで透明度 を持つ。rsvg-convert は SVG の fill-opacity を PNG alpha チャンネルに正しくエンコードする
  • FCPは rsvg-convert 出力の rgba PNG を確実に半透明として描画する

5. format は PNG ネイティブサイズで個別定義

<!-- 良: PNGネイティブサイズで個別定義 -->
<format id="g_glass_bar_fmt" name="FFVideoFormatRateUndefined"
        width="1920" height="92" colorSpace="1-13-1"/>

<!-- 悪: r1 (sequence format=4K) 共有 -->
<asset id="g_glass_bar" format="r1" ...>  <!-- FCP が画像を3840x2160に拡大する -->

PNG 1920x92 を r1 (4K) format で共有させると、FCPがspatial conformで画像をsequence解像度に拡大してしまう。 結果、上下に置いた帯が画面全体を覆うような表示になる。

専用formatの命名規則

g_<asset_name>_fmt
  └ width=<png_width> height=<png_height> colorSpace="1-13-1"

各PNGに対して 1 format。共有しない。

6. lane 合成順

数値が大きいほど手前。

このスキルは「画像オーバーレイ(<video>)と字幕(<title>)を同一カットに載せる」前提が多いので、fcp-titles と共有する典型スタックをここで固定する:

stack(奥→手前)要素推奨lane
上下帯など「背景寄り」1–2
ロケーションカード等2–3
手前字幕(<title>3–4

例外もある(エンドカードのみ、字幕無しの装飾のみ等)。迷ったら FCP上で上下関係を作って Export XML → lane を読むのが最短。

同じlaneに重複して clip を置くと衝突する。connected clip は lane を別々に。

7. resource ID は動的取得(必須)

import re

GLASS_BAR_ASSET_RE = re.compile(
    r'<asset\s+id="(r\d+|g_\w+)"\s+name="Glass Bar"', re.DOTALL
)

def main():
    content = INFO_FCPXML.read_text(encoding="utf-8")
    m = GLASS_BAR_ASSET_RE.search(content)
    if not m:
        raise SystemExit("Glass Bar asset not found")
    glass_bar_asset_id = m.group(1)

特に自分で名前を付けた asset (g_xxx_fmt) は固定ID で書き込めるが、FCPで実際に import → re-export すると、自動asset (r4, r5 等)に変換される可能性がある。 name 属性で動的取得が頑健。

8. AI下書き → FCP refine → export ループ

最初の1個は FCPで Inspector経由で配置 → export → AI読み取り が最短。

ループ手順

  1. AI: skeleton で video を仮値で書き込む(Position 0,0 など)
  2. ユーザー: FCPで .fcpxmld を re-import → 視聴
  3. ユーザー: Inspector で Position/Scale/Opacity を refine → File → Export XML で上書き
  4. AI: exported XML から <adjust-transform position> の正規値を読み取り、テンプレ化

最初の1個 export で取れる重要情報

  • format の正規構造(width/height/colorSpace/name)
  • asset の正規 attribute(uid/sig/start/duration/hasVideo)
  • video の start 属性の正規値("3600s")
  • adjust-transform position の単位(pixel? unit? の確定)

9. 既知の落とし穴

  • format=r1 共有: FCPが画像を4Kサイズに拡大する。PNGネイティブサイズで個別定義
  • PNG が transparent にならない: ffmpeg 直生成 (rgb24) ではFCPが alpha を読まない。SVG→rsvg-convert で rgba 生成
  • adjust-transform position に 1920基準pixel を入れる: 単位が違う。4K canvas unit (1080=50) に変換
  • start="0s" で書く: generator系は "3600s" が標準
  • bookmark なし: 同じmac でも import時に再認識されないことあり。FCP正規 export 経由で bookmark を取得するのが理想
  • 削除regex を ref="g_xxx" で書く: FCPがimport→re-exportで g_glass_barr3 等に id 再番号付け。残骸が消えず重複蓄積する。name="Top Bar" 等の name属性ベースで識別する
  • シーンごとに帯を配置する: 30シーン × 上下 = 60本の帯がタイムラインに並ぶ。spine全体に1本ずつ (最初のasset-clip lane=1,2 に duration=spine全長) が正解
  • name属性に & を含める: XML escape必須。xml_escape() を name書き出し直前に適用

削除regexの現実的パターン(re-export 耐性)

ref は再番号付けされる。安定キーは name=(運用で名前規約を固定する)。

import re

# 例: name が Top Bar / Bottom Bar の装飾 video を削除(タグは自己閉じ/子要素ありの両対応)
DECO_VIDEO_BY_NAME_RE = re.compile(
    r'\s*<video\b[^>]*\bname="(?:Top Bar|Bottom Bar)"[^>]*(?:/>|>.*?</video>)',
    re.DOTALL,
)

広すぎる <video ...> 全削除は誤爆する(ユーザーの通常クリップまで消える)。削除対象は「このプロジェクトで付けた装飾の name 規約」に限定する。

関連スキル

  • fcp-titles: テキスト系オーバーレイ(字幕・テロップ)。画像と並べる時の単位変換
  • fcp-spine-edit: spine 構造編集(image overlay が連結している parent asset-clip の側)
  • dji-fcpxml: 基本のFCPXML仕様(asset.start/format/TC変換)

関連メモリ

  • feedback_fcpxml_title_structure.md — overlay系の正規構造(title/video 共通)
  • feedback_fcpxml_resource_id_dynamic.md — resource ID 動的取得の必要性

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,367. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.