ビデオエディター は何をしますか?
概要
3つのエンジンで動作するAI支援型動画ワークフロー:
- ffmpeg -- 既存映像の編集(トリミング、圧縮、結合、リサイズ、速度、手ぶれ補正、ウォーターマーク、オーディオ、GIF、サムネイル、トランジション、キャプション)
- Remotion -- 新しい動画コンテンツの作成(タイトルカード、ローワーサード、エンドカード、ティーザー、アニメーションオーバーレイ)
- Whisper -- 文字起こしとキャプション生成
追加機能:
- ハードウェアアクセラレーション Apple Silicon 上で
h264_videotoolbox / hevc_videotoolbox を使用
- テーマ統合
~/design-assets/color-palettes/ のデザインアセットと連携
- プラットフォームプリセット YouTube、Instagram、TikTok、Twitter などに対応
- ワークスペースキャッシュ Remotion の
npm install を繰り返さないためのキャッシュ機能
使用タイミング
以下のユーザー意図のいずれかで起動:
| カテゴリ | キーワード |
|---|
| 基本編集 | トリミング、カット、クリップ、短くする、分割 |
| 圧縮 | 圧縮、ファイルサイズ削減、縮小、小さくする、最適化 |
| 結合 | マージ、結合、連結、ジョイン、ステッチ |
| リサイズ | リサイズ、スケール、クロップ、パッド、アスペクト比、縦向き、横向き、正方形 |
| 速度 | 高速化、スローダウン、スローモーション、タイムラプス、早送り、逆再生 |
| 手ぶれ補正 | 手ぶれ補正、ぶれ、スムーズ、手ぶれ修正 |
| トランジション | フェード、クロスフェード、ディゾルブ、ワイプ、トランジション |
| キャプション | キャプション、字幕、SRT、文字起こし、音声テキスト変換 |
| タイトルカード | タイトルカード、イントロ、オープニング、アニメーションテキスト |
| ローワーサード | ローワーサード、名前タグ、カイロン、ネームバー |
| エンドカード | エンドカード、アウトロ、エンドスクリーン、クロージング |
| ティーザー | ティーザー、予告編、プロモ、ハイライトリール、モンタージュ |
| サムネイル | サムネイル、ポスター、フレーム抽出、スクリーンショット |
| GIF | GIF、アニメーション画像、ループ、ミーム |
| ウォーターマーク | ウォーターマーク、ロゴオーバーレイ、ブランディング |
| オーディオ | オーディオ、音量、ノーマライズ、ラウドネス、ミュート、フェードイン、フェードアウト、ミックス、オーディオ抽出 |
| 情報 | 情報、詳細、長さ、解像度、コーデック、ビットレート、メタデータ |
| パイプライン | パイプライン、バッチ、ワークフロー、複数ステップ |
| プラットフォーム | YouTube、Instagram、TikTok、Twitter、Reels、Shorts |
コマンドリファレンス
編集コマンド (ffmpeg)
| コマンド | 説明 | 例 |
|---|
/trim | 動画から一部分を切り出す | "video.mp4 を 0:30 から 1:45 までトリミング" |
/compress | 品質を制御してファイルサイズを削減 | "10MB以下に圧縮" |
/merge | 複数のクリップを結合 | "clip1.mp4 と clip2.mp4 をフェードで結合" |
/resize | サイズ、アスペクト比、クロップ、パッドを変更 | "1080x1080 の正方形にリサイズ" |
/speed | 早送り、スローダウン、または逆再生 | "2倍速" または "0.5倍スローモーション" |
/stabilize | カメラの手ぶれを除去(vidstab 2パス) | "shaky.mp4 を手ぶれ補正" |
/watermark | 動画に画像またはテキストを重ねる | "logo.png を右下に追加" |
/audio | 音量、ノーマライズ、ミックス、フェード、抽出、ミュート | "オーディオを -14 LUFS にノーマライズ" |
/thumbnail | フレームを画像として抽出 | "0:15 のサムネイル" |
/gif | 動画の一部からアニメーションGIFを作成 | "0:05 から 0:10 まで、320px の GIF" |
/extract | オーディオまたは字幕トラックを抽出 | "オーディオを mp3 で抽出" |
/info | 動画のメタデータとストリーム情報を表示 | "video.mp4 の情報" |
作成コマンド (Remotion)
| コマンド | 説明 | 例 |
|---|
/title-card | テーマ対応のアニメーションタイトルカード | "タイトルカード: Coming Soon、wad テーマ、ズームアニメーション" |
/lower-third | アニメーション付き名前/タイトルオーバーレイ | "ローワーサード: John Doe、CEO、モダンスタイル" |
/end-card | CTAとソーシャルリンク付きアニメーションアウトロ | "エンドカード: Subscribe!、@handle、ea テーマ" |
/teaser | トランジションとタイトル付きマルチクリップモンタージュ | "clips/ フォルダから30秒のティーザー" |
文字起こしコマンド (Whisper)
| コマンド | 説明 | 例 |
|---|
/transcribe | 音声からSRT/VTTを生成 | "interview.mp4 を文字起こし" |
/add-captions | 文字起こし + キャプションを動画に焼き付ける | "talk.mp4 にキャプションを追加" |
オーケストレーション
| コマンド | 説明 | 例 |
|---|
/pipeline | 複数ステップの処理チェーン | "トリミング、タイトルカード追加、Instagram用に圧縮" |
ワークフロー
ステップ 1: 利用可能なツールを確認
which ffmpeg ffprobe && echo "ffmpeg: ok"
node --version && echo "node: ok"
which whisper && echo "whisper: ok" || echo "whisper: not installed (captions need manual .srt)"
ffmpeg -encoders 2>/dev/null | grep videotoolbox && echo "hw accel: ok" || echo "hw accel: not available"
ffmpeg -filters 2>/dev/null | grep vidstab && echo "vidstab: ok" || echo "vidstab: not available (brew install ffmpeg with --with-libvidstab)"
ffmpeg がない場合: "brew install ffmpeg でインストールしてください"
Node.js がない場合: "https://nodejs.org からインストールするか、brew install node でインストールしてください"
vidstab がない場合: "vidstab 付きで ffmpeg を再インストール: brew install ffmpeg --with-libvidstab"
ステップ 2: リクエストを分類
| ユーザー意図 | エンジン | パス |
|---|
| 既存映像の編集 | ffmpeg | ステップ 3a |
| 新しい動画コンテンツの作成 | Remotion | ステップ 3b |
| オーディオ操作 | ffmpeg オーディオフィルター | ステップ 3a |
| 情報/調査 | ffprobe | ステップ 3a |
| 複合パイプライン | 両方を統括 | ステップ 3c |
| プラットフォーム公開 | リサイズ + 圧縮プリセット | ステップ 3a |
| 文字起こし | Whisper + ffmpeg | ステップ 3a |
ステップ 3a: ffmpeg パス
- 入力ファイルが指定されていない場合はユーザーに確認
- ffprobe で調査:
ffprobe -v quiet -print_format json -show_format -show_streams "<file>"
- ハードウェアアクセラレーション検出 (macOS Apple Silicon):
ffmpeg -encoders 2>/dev/null | grep h264_videotoolbox
- 出力ファイルの衝突処理:
OUTPUT="trimmed_video.mp4"
COUNTER=2
while [ -f "$OUTPUT" ]; do
OUTPUT="trimmed_video_${COUNTER}.mp4"
COUNTER=$((COUNTER + 1))
done
- ffmpeg コマンドを構築
- 各フラグを平易な英語で説明
- 出力ファイル名を表示(ソースファイルを上書きしない)
- 確認: "実行しますか?"
- 実行後、検証:
if [ $? -eq 0 ]; then
echo "Success"
ffprobe -v quiet -print_format json -show_format "$OUTPUT" | grep -E '"duration"|"size"'
else
echo "Error — check ffmpeg output above"
fi
- 出力パス + ファイルサイズ + 長さを報告
出力ファイル命名規則:
| コマンド | 出力パターン |
|---|
| トリミング | trimmed_<filename> |
| 圧縮 | compressed_<filename> |
| 結合 | merged_output.<ext> |
| リサイズ | resized_<filename> |
| 速度 | speed_<factor>x_<filename> |
| 手ぶれ補正 | stabilized_<filename> |
| ウォーターマーク | watermarked_<filename> |
| キャプション | captioned_<filename> |
| オーディオ抽出 | <name>.mp3 |
| オーディオ変更 | audio_<filename> |
| 字幕抽出 | <name>.srt |
| サムネイル | thumb_<name>_<timecode>.jpg |
| GIF | <name>.gif |
ステップ 3b: Remotion パス
- Node.js がインストールされていることを確認
- ワークスペースキャッシュ -- 既存のワークスペースを再利用:
WORKSPACE="/tmp/remotion-workspace"
if [ -d "$WORKSPACE/node_modules" ]; then
echo "Reusing cached Remotion workspace"
else
echo "Creating Remotion workspace (first run)..."
mkdir -p "$WORKSPACE"
cp -r ~/project-templates/remotion-video/* "$WORKSPACE/"
cd "$WORKSPACE" && npm install
fi
- テーマの読み込み
~/design-assets/color-palettes/ から:
- 必要に応じてコンポジションのソースファイルを作成または更新
- 利用可能なコンポジション:
TitleCard -- 複数のアニメーションプリセットを持つアニメーションタイトル
LowerThird -- アクセントバー付きの名前/タイトルオーバーレイ
EndCard -- CTA、ソーシャルリンク、ロゴ付きアウトロ
Teaser -- TransitionSeries を使用したマルチクリップモンタージュ
- レンダリング:
cd "$WORKSPACE"
npx remotion render src/index.ts <CompositionId> /path/to/output.mp4 \
--props='{"text":"Title","bg":"#09090B","fg":"#FFFFFF","accent":"#7C3AED"}'
- 出力をユーザーの作業ディレクトリにコピー
- 出力パス + 長さを報告
ステップ 3c: 複合パイプライン
複数ステップのリクエスト(例: "タイトルカード、クリップ、エンドカード付きのティーザーを作成")の場合:
- 計画 -- 実行前に各ステップをユーザーに説明
- 作成 -- 最初に Remotion コンテンツ(タイトルカード、エンドカード)を生成
- 処理 -- ffmpeg でソースクリップをトリミング/リサイズ
- 組み立て -- ffmpeg でトランジションを付けてすべてのパーツを結合
- 最終化 -- 指定されたターゲットプラットフォーム用に圧縮
- 主要フェーズ(作成 vs. 編集 vs. 組み立て)間で確認を取る
ffmpeg クイックリファレンス
トリミング(無劣化)
ffmpeg -ss <start> -to <end> -i input.mp4 -c copy trimmed_input.mp4
圧縮 -- Web (CRF 23)
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 128k compressed_input.mp4
圧縮 -- ハードウェアアクセラレーション (macOS)
ffmpeg -i input.mp4 -c:v h264_videotoolbox -b:v 5M -c:a aac -b:a 128k compressed_input.mp4
フェードトランジション付き結合
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "[0][1]xfade=transition=fade:duration=1:offset=<offset>,format=yuv420p[v];[0:a][1:a]acrossfade=d=1[a]" \
-map "[v]" -map "[a]" merged_output.mp4
リサイズ / スケール
ffmpeg -i input.mp4 -vf "scale=1920:1080" resized_input.mp4
ffmpeg -i input.mp4 -vf "scale=1080:-1" resized_input.mp4
ffmpeg -i input.mp4 -vf "crop=min(iw\,ih):min(iw\,ih)" cropped_input.mp4
ffmpeg -i input.mp4 -vf "scale=1080:1080:force_original_aspect_ratio=decrease,pad=1080:1080:(ow-iw)/2:(oh-ih)/2:black" padded_input.mp4
速度変更
ffmpeg -i input.mp4 -vf "setpts=0.5*PTS" -af "atempo=2.0" speed_2x_input.mp4
ffmpeg -i input.mp4 -vf "setpts=2.0*PTS" -af "atempo=0.5" speed_0.5x_input.mp4
ffmpeg -i input.mp4 -vf "setpts=0.25*PTS" -af "atempo=2.0,atempo=2.0" speed_4x_input.mp4
ffmpeg -i input.mp4 -vf "reverse" -af "areverse" reversed_input.mp4
ウォーターマークオーバーレイ
ffmpeg -i input.mp4 -i logo.png \
-filter_complex "overlay=W-w-20:H-h-20" watermarked_input.mp4
ffmpeg -i input.mp4 -i logo.png \
-filter_complex "overlay=20:20" watermarked_input.mp4
ffmpeg -i input.mp4 -i logo.png \
-filter_complex "[1]format=rgba,colorchannelmixer=aa=0.3[wm];[0][wm]overlay=(W-w)/2:(H-h)/2" watermarked_input.mp4
ffmpeg -i input.mp4 \
-vf "drawtext=text='My Brand':fontsize=24:[email protected]:x=W-tw-20:y=H-th-20" watermarked_input.mp4
手ぶれ補正 (vidstab 2パス)
ffmpeg -i shaky.mp4 -vf vidstabdetect=shakiness=10:accuracy=15 -f null -
ffmpeg -i shaky.mp4 -vf vidstabtransform=smoothing=30:input=transforms.trf stabilized_shaky.mp4
オーディオ操作
ffmpeg -i input.mp4 -af "volume=1.5" audio_input.mp4
ffmpeg -i input.mp4 -af "loudnorm=I=-14:TP=-1:LRA=11" audio_input.mp4
ffmpeg -i video.mp4 -i music.mp3 \
-filter_complex "[0:a]volume=1.0[a1];[1:a]volume=0.3[a2];[a1][a2]amix=inputs=2:duration=first[a]" \
-map 0:v -map "[a]" audio_input.mp4
ffmpeg -i input.mp4 -af "afade=t=in:ss=0:d=3,afade=t=out:st=<end-3>:d=3" audio_input.mp4
ffmpeg -i input.mp4 -an muted_input.mp4
ffmpeg -i input.mp4 -i newtrack.mp3 -c:v copy -map 0:v:0 -map 1:a:0 replaced_audio_input.mp4
GIF作成(品質向上のため2パスパレット)
ffmpeg -ss <start> -t <duration> -i input.mp4 \
-vf "fps=15,scale=320:-1:flags=lanczos,palettegen" palette.png
ffmpeg -ss <start> -t <duration> -i input.mp4 -i palette.png \
-filter_complex "[0:v]fps=15,scale=320:-1:flags=lanczos[v];[v][1:v]paletteuse" output.gif
rm palette.png
サムネイル抽出
ffmpeg -ss <timestamp> -i input.mp4 -frames:v 1 -q:v 2 thumb_input_<timestamp>.jpg
ffmpeg -i input.mp4 -vf "fps=1/<interval>,scale=320:-1,tile=4x4" thumb_grid_input.jpg
.srt キャプションを焼き付ける
ffmpeg -i input.mp4 -vf "subtitles=captions.srt:force_style='FontSize=24,PrimaryColour=&H00FFFFFF'" captioned_input.mp4
オーディオの抽出
ffmpeg -i input.mp4 -vn -c:a libmp3lame -q:a 2 output.mp3
ビデオ情報
ffprobe -v quiet -print_format json -show_format -show_streams input.mp4
Remotion クイックリファレンス
キャッシュ済みワークスペースのセットアップ
WORKSPACE="/tmp/remotion-workspace"
if [ ! -d "$WORKSPACE/node_modules" ]; then
cp -r ~/project-templates/remotion-video/* "$WORKSPACE/"
cd "$WORKSPACE" && npm install
fi
TitleCard コンポジション
import { AbsoluteFill, spring, useCurrentFrame, useVideoConfig, Img } from 'remotion';
type Animation = 'fade' | 'slide-up' | 'slide-down' | 'zoom' | 'typewriter' | 'glitch' | 'blur-in';
export const TitleCard: React.FC<{
text: string;
subtitle?: string;
bg?: string;
fg?: string;
accent?: string;
animation?: Animation;
logo?: string;
}> = ({ text, subtitle, bg = '#09090B', fg = '#FFFFFF', accent = '#7C3AED', animation = 'fade', logo }) => {
const frame = useCurrent
…
[翻訳のため省略]