paw-cra-multi-platform-export について
承認済みの画像・動画マスターを、各プラットフォーム向けに変換するクリエイティブワークフローです。キャンペーン制作向けに、形式変換、安全領域の確認、ファイル整理、機械可読なマニフェスト生成を一括で行います。
主な機能
- 01画像と動画を一括でエクスポート
- 02プラットフォーム別のサイズ・エンコード
- 03重要な内容のセーフゾーン確認
- 04プラットフォーム別フォルダーとJSONマニフェスト
- 05ヘッドレス実行
活用シーン
- 01ソーシャルプラットフォーム向け素材の準備
- 02マスター画像の異なる縦横比への適応
- 03プラットフォーム別コーデックでの動画出力
- 04マニフェストで出力状況と警告を確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ pawbytes/ skill-suites --skill paw-cra-multi-platform-exportインストール後、Claude Code で/paw-cra-multi-platform-exportを入力して読み込まれたか確認します。
同梱ファイルreferences/platform-export-specs.md
詳細
マルチプラットフォームエクスポート
概要
このワークフローでは、承認済みのマスター画像・動画アセットを、すべての対象プラットフォーム向けのバリエーションに変換します。サイズ変更、再エンコードを行い、機械可読なマニフェストを含む、納品に適したフォルダー構成に整理します。画像と動画の両方を単一の統合パイプラインで処理し、安全領域を適用して、重要なコンテンツ(テキスト、ロゴ、顔)が切り取られたり、プラットフォームの UI に隠されたりしないようにします。
引数: 非対話型の実行には --headless / -H を指定できます。ヘッドレスモードでは、マスターアセットのパスと対象プラットフォームのリストを引数として指定するか、アクティブなキャンペーンブリーフから読み込みます。
出力: プラットフォームごとのフォルダーに整理されたバリエーションファイルと、各バリエーションの仕様を記述した export-manifest.json。
プラットフォームの制約、コーデック要件、安全領域の形状を理解した、技術エクスポートのスペシャリストとして対応してください。視覚的な完全性を優先します。マスターの意図を保ったまま解像度がやや低くなるバリエーションのほうが、正確なピクセル寸法に合わせるために重要なコンテンツを切り取るバリエーションよりも常に優れています。
起動時
{project-root}/.pawbytes/config/config.yaml と {project-root}/.pawbytes/config/config.user.yaml のルートレベルおよび cra セクションから、利用可能な設定を読み込みます。設定ファイルが見つからない場合は、paw-cra-setup を使っていつでもモジュールを設定できることをユーザーに伝えます。設定を解決し、セッション全体を通じて適用します(括弧内はデフォルト値です)。
{output_directory}(.pawbytes/creative-suites)— 基本の出力先{default_brand}(null)— 命名規則に使用するアクティブなブランド
利用可能な場合は、共有エージェンシーメモリーを {project-root}/.pawbytes/creative-suites/index.md から読み込みます。アクティブなキャンペーンがある場合は、ファイル名に使用するブランド名とキャンペーン名を確認するため、キャンペーンブリーフを読み込みます。
ツールの確認: ffmpeg が利用可能か確認します。画像と動画の両方の処理に必要です。見つからない場合は、インストール方法(winget install ffmpeg / brew install ffmpeg)を案内して中止します。ImageMagick は任意ですが、画像関連の処理を強化できます。
--headless が指定されている場合は、指定された入力を使って処理を直接進めます。それ以外の場合は、ユーザーに挨拶し、マスターアセットと対象プラットフォームを確認します。
パイプライン
ステップ 1 — ソースの取り込み
入力を収集します。
- マスターアセット: 1 つ以上のファイルパス(画像または動画)。拡張子と ffprobe のメタデータからメディアタイプを判定します。
- 対象プラットフォーム: エクスポート対象のプラットフォーム。指定がない場合は、サポートされているすべてのプラットフォームをデフォルトにします。
- ブランド名とキャンペーン名: 命名規則に使用します。アクティブなキャンペーンのコンテキストから推定するか、ユーザーに確認します。
サポート対象プラットフォーム:Instagram、TikTok、YouTube、Facebook、LinkedIn、Twitter/X、Pinterest、Google Business。
各ソースファイルを分類します。
- 画像:
.png、.jpg、.jpeg、.webp、.tiff、.bmp、.svg - 動画:
.mp4、.mov、.avi、.mkv、.webm
ステップ 2 — プラットフォーム仕様の参照
./references/platform-export-specs.md を読み込み、寸法、アスペクト比、安全領域、ファイルサイズ上限、コーデック要件、再生時間の上限など、プラットフォームの完全な仕様を確認します。
ソースアセットと対象プラットフォームの組み合わせごとに、以下を決定します。
- 対象寸法とアスペクト比
- 安全領域の余白(プラットフォーム UI がコンテンツに重なる、各端からのピクセル数)
- ファイルサイズの上限
- 動画の場合:コーデック、ビットレート、再生時間の上限、字幕の扱い
ステップ 3 — 画像のエクスポート
画像とプラットフォームの各組み合わせについて、次の手順を実行します。
- ソースを分析する — ffprobe または ImageMagick identify を使って寸法とアスペクト比を取得し、主要なコンテンツ領域を特定します
- リサイズ方法を決定する — 元画像の意図を最もよく保てる方法を選びます。
- アスペクト比が同じ場合: 縦横比を保って拡大・縮小します
- わずかなトリミングが必要な場合: 主要な被写体を中心にトリミングし、重要なコンテンツがセーフゾーン内に収まっていることを確認します
- アスペクト比が大きく変わる場合: 過度なトリミングより、ブランドカラーの余白を加えるレターボックス/ピラーボックスを優先します。ユーザーがトリミングを希望する場合は、まず主要な被写体を確認します。
- セーフゾーンを適用する — リサイズ/トリミング後、重要なコンテンツ(テキストオーバーレイ、ロゴ、主要な被写体)がセーフゾーンの外にないことを確認します。重要なコンテンツはすべての端から、プラットフォームで指定されたセーフゾーンの余白を確保する必要があります。
- 再エンコードする — 写真には JPEG(品質 90)、透明度のあるグラフィックには PNG を使用します。プラットフォームのファイルサイズ上限を超えないようにします。上限を超える場合は、準拠するまで JPEG 品質を段階的に下げます(85 → 80 → 75)。
- 検証する — 最終的な寸法が仕様に一致し、ファイルサイズが上限未満であることを確認します。
画像リサイズ用の ffmpeg の例:
# Scale to fit within dimensions, maintaining aspect ratio
ffmpeg -i master.png -vf "scale=1080:1350:force_original_aspect_ratio=decrease,pad=1080:1350:(ow-iw)/2:(oh-ih)/2:color=#000000" output.jpg
# Crop to exact dimensions centered on focal point
ffmpeg -i master.png -vf "scale=1080:-1,crop=1080:1080" output.jpg
ステップ 4 — 動画のエクスポート
動画とプラットフォームの各組み合わせについて、次の手順を実行します。
- ソースを確認する — ffprobe を使って解像度、再生時間、コーデック、ビットレート、字幕トラックを取得します
- 再生時間を確認する — ソースがプラットフォームの最大再生時間を超える場合は、ユーザーに警告します(ヘッドレスモードでは自動的にトリミングしないでください。マニフェストに
duration_exceededと記録します) - アスペクト比を調整する:
- 横向きから縦向き(例:16:9 から 9:16): アクション領域を中心にスマートトリミングします。縦型動画のプラットフォーム(TikTok、Reels)では、レターボックスよりトリミングを優先します。
- 縦向きから横向き: ぼかした背景またはブランドカラーの余白を加えてピラーボックスにします。
- アスペクト比が同じで解像度が異なる場合: そのまま拡大・縮小します。
- 再エンコードする — H.264(libx264)、AAC オーディオ、およびプラットフォームに適したビットレートを使用します。プラットフォームの上限に応じて、CRF 18~23 を目標にします。
- 字幕の位置を調整する — ソースに字幕トラックがあり、アスペクト比が変わった場合は、新しいセーフゾーン内に収まるように位置を調整します。動画に直接焼き付けられた字幕は、調整後の座標で再レンダリングします。
- 検証する — 解像度、コーデック、再生時間、ファイルサイズがプラットフォームの要件を満たしていることを確認します。
動画用の ffmpeg の例:
# Horizontal to vertical (smart center crop)
ffmpeg -i master.mp4 -vf "scale=1920:-1,crop=1080:1920" -c:v libx264 -crf 20 -c:a aac -b:a 128k output.mp4
# Scale to platform resolution
ffmpeg -i master.mp4 -vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2" -c:v libx264 -crf 20 -c:a aac output.mp4
ステップ 5 — 命名規則
エクスポートするすべてのファイルに、一貫した命名規則を適用します。
{brand}_{campaign}_{platform}_{asset-type}_{variant}.{ext}
| 要素 | ソース | 例 |
|---|---|---|
brand | 有効なブランド(小文字、ハイフン区切り) | acme-corp |
campaign | キャンペーン名(小文字、ハイフン区切り) | spring-launch |
platform | 対象プラットフォーム(小文字) | instagram、tiktok、youtube |
asset-type | image または video | image |
variant | プラットフォーム固有の形式を示す名称 | feed-portrait、story、thumbnail |
ext | プラットフォームに最適な形式 | jpg、png、mp4 |
例:acme-corp_spring-launch_instagram_image_feed-portrait.jpg
ブランドまたはキャンペーンが不明な場合は、該当する要素を省略します:instagram_image_feed-portrait.jpg
ステップ 6 — エクスポートの整理
エクスポートディレクトリ内に、プラットフォーム別のフォルダーを作成して、すべてのバリエーションを整理します。
{output_directory}/brands/{brand}/exports/{campaign}/
instagram/
acme-corp_spring-launch_instagram_image_feed-portrait.jpg
acme-corp_spring-launch_instagram_image_story.jpg
acme-corp_spring-launch_instagram_video_reel.mp4
tiktok/
acme-corp_spring-launch_tiktok_video_feed.mp4
youtube/
acme-corp_spring-launch_youtube_video_main.mp4
acme-corp_spring-launch_youtube_image_thumbnail.jpg
...
export-manifest.json
ステップ 7 — エクスポートマニフェスト
エクスポートディレクトリのルートに export-manifest.json を生成します。
{
"brand": "acme-corp",
"campaign": "spring-launch",
"exported_at": "2026-04-01T14:30:00Z",
"source_assets": [
{
"path": "path/to/master.png",
"type": "image",
"dimensions": "2400x3000",
"file_size_bytes": 4500000
}
],
"variants": [
{
"platform": "instagram",
"variant": "feed-portrait",
"type": "image",
"filename": "acme-corp_spring-launch_instagram_image_feed-portrait.jpg",
"path": "instagram/acme-corp_spring-launch_instagram_image_feed-portrait.jpg",
"dimensions": "1080x1350",
"aspect_ratio": "4:5",
"file_size_bytes": 245000,
"format": "jpeg",
"status": "ok"
},
{
"platform": "tiktok",
"variant": "feed",
"type": "video",
"filename": "acme-corp_spring-launch_tiktok_video_feed.mp4",
"path": "tiktok/acme-corp_spring-launch_tiktok_video_feed.mp4",
"dimensions": "1080x1920",
"aspect_ratio": "9:16",
"duration_seconds": 45,
"codec": "h264",
"file_size_bytes": 12000000,
"status": "ok"
}
],
"warnings": [],
"total_variants": 8,
"total_size_bytes": 45000000
}
ステータスの値:ok、duration_exceeded、size_exceeded、quality_reduced、skipped。
警告があれば記載します(例:「TikTok のバリエーションが 60 秒の再生時間制限を超えています — 手動でのトリミングが必要です」)。
ステップ 8 — ステータスの更新
日次ログ {project-root}/.pawbytes/creative-suites/daily/YYYY-MM-DD.md に追記します。
[Export] Multi-platform export complete for {campaign}
- Source: {N} master asset(s)
- Exported: {M} variants across {P} platforms
- Warnings: {W} (or "none")
- Manifest: {path-to-export-manifest.json}
セーフゾーンの参照
セーフゾーンは、プラットフォームの UI(ボタン、キャプション、ナビゲーションバー)によってコンテンツが隠れないように保護します。各端から確保する最小のピクセル数であり、この範囲には重要なコンテンツを配置しないでください。
| プラットフォーム | 上 | 下 | 左 | 右 | 備考 |
|---|---|---|---|---|---|
| Instagram Feed | 0 | 0 | 0 | 0 | 表示領域に重なる UI なし |
| Instagram Story | 120 | 200 | 60 | 60 | 上部のステータスバー、下部の CTA |
| TikTok | 50 | 150 | 20 | 20 | 下部:ユーザー名、キャプション、音楽 |
| YouTube | 0 | 40 | 0 | 0 | 下部:プログレスバーとコントロールが重なって表示されます |
| Facebook Feed | 0 | 60 | 0 | 0 | 下部:リアクションバーとキャプションが動画に重なって表示されます |
| Facebook Story | 120 | 200 | 60 | 60 | Instagram Story と同じ |
| LinkedIn Feed | 0 | 50 | 0 | 0 | 下部:エンゲージメントバーが動画に重なって表示されます |
| Twitter/X | 0 | 0 | 0 | 0 | 表示領域に重なる UI なし |
| 0 | 50 | 0 | 0 | 下部:ピン情報が重なって表示されます | |
| Google Business | 0 | 0 | 0 | 0 | 表示領域に重なる UI なし |
縦型コンテンツを扱う動画プラットフォーム(TikTok、Reels、Stories)では、セーフゾーンが特に重要です。通常、フレームの下部 10~15% は UI 要素に覆われます。
エラー処理
- ffmpeg が見つからない場合: インストール手順を示して中止します。動画に Python のみで対応するフォールバックは試みません。
- ソースファイルが見つからない場合: マニフェストに警告を記録してスキップし、残りのファイルの処理を続けます。
- ソースの解像度が低すぎる場合: アップスケーリング率が 150% を超える場合は警告します。処理は続行しますが、マニフェストに
quality_reducedを記録します。 - 圧縮後にファイルサイズが上限を超えた場合: マニフェストに
size_exceededを記録します。手動での最適化を提案します。 - 再生時間が上限を超えた場合: マニフェストに
duration_exceededを記録します。自動トリミングは行いません。 - サポートされていない形式の場合: 警告を記録してスキップし、最初に形式を変換するよう提案します。