録画映像の編集
録画映像を基に構築する作品のためのレシピ集。これらはmontagentのループのビルドステップに組み込まれます。まだロードしていなければ、最初にmontagentをロードしてください。トーキングヘッド、プレゼンタークリップ、またはインタビューカットの場合は、計画を立てる前にトーキングヘッド構造を開いてください。
映像から始める
要素を書く前に、すべてのクリップをprobeしてください。そのサイズ、フレームレート、長さ、そして音声があるかどうかを確認します。次に、音声に基づいて作品を計画します。ワードタイミングは、すべてのキャプション、キュー、ダックが基準とする時計です。そのため、タイミングは最初にチェックされます(キャプションを参照)。
長いクリップから特定の瞬間(例えば、スクリーンレコーディングの挿入部分として表示する範囲)を選択するには、そのクリップを単独でスクラッチプロジェクトに配置し、frame --from 0 --to <長さ> --infill-ceiling <ms>を呼び出します。天井(ceiling)は長さの20分の1に設定します。1回の呼び出しで、数秒ごとにラベル付きのタイルが生成されます。frame --atで任意のタイルを拡大表示できます。
レシピ
すべてのレシピは、答えではなく開始範囲を提供します。各レシピはルックステップで終わります。montagent-craftをロードし、ステップで指定された場所を確認してから先に進みます。
映像の配置
{
"frame": {"width": 1080, "height": 1920}, "fps": 30, "background": "#FF5A36", "duration": 6000, "output": "out/presenter.mp4",
"tracks": [
{"name": "presenter", "layer": 10, "elements": [
{"id": "presenter", "type": "video", "start": 0, "end": 6000, "source": "media/clip.mp4", "source_start": 0, "source_end": 6000, "x": 540, "y": 2160, "origin": "bottom-center", "width": 3413, "height": 1920, "fit": "cover", "effects": [{"name": "chroma", "color": "#00FF00", "tolerance": 0.2, "softness": 0.08, "spill": 0.9}]}
]}
]}
- 縦長フレーム内のワイド映像: 要素の高さをフレームと同じにし、幅をソースのアスペクト比に合わせて(1920の高さに対して16:9なら幅は3413)、話者が中央に来るように横にスライドさせます。
- 目線: フレームの上から25~35%の位置。要素の
bottom-centerをフレームの下端より下に設定して調整します。脚が切れるのは普通です。 - ヘッドルーム: 髪の毛の上部からフレーム上端まで、フレーム高の4~8%。
- 作品より短いテイク:
"overrun": "hold"とすると、最終フレームで停止します。停止時間は0.5秒未満に留めるか、作品を早めに終了します。 - クリップ内の静止フレーム、スピードランプ、逆再生:
source_startとsource_endの代わりにsource_timeを記述します。リテラル値で1つの瞬間を固定し、ソースのミリ秒とタイムラインtのキーフレームでランプを設定します(水平なペアで静止、下降するペアで逆再生)。スローモーション(speed< 1.0)またはスピードランプ(source_time)処理中のクリップで、"frame_blend": "mix"を設定すると、最も近いフレーム間のステップ遷移("none")の代わりに、連続するソースフレーム間でクロスディゾルブします。映像にポスタライズタイム(ストップモーション)風の外観を与えるには、複数のタイムラインフレームにわたってターゲットのソースタイムスタンプを保持する、段階的なsource_timeキーフレームを使用します。source_timeを持つクリップはvolume0で無音になるため、その音声は別のaudio要素に配置します。 - テイク自身の音声: 音声は
volume1.0に保ちます。その他はすべてその下でミックスします。 - 確認:
frameで開始時、中間、最終描画フレームを確認し、目線が適切な範囲にあり、フレームの側面で重要な部分が切れていないことを確認します。
グリーンスクリーンキー
映像要素にchromaを適用してスクリーンをキーアウトします。以下の設定から始めてください:
color: スクリーンの純粋な色。グリーンスクリーンなら#00FF00。照明によって青や黄色に若干ずれたスクリーンでも、この許容値では問題なくキーされるため、サンプリングする必要はありません。tolerance: 0.2(範囲0.18~0.25)。約0.3を超えると、黒い髪、白い襟、濃い色の服を食いつぶします。softness: 0.08(範囲0.05~0.1)。spill: 0.9(範囲0.9~1.0)。
他の要素を重ねる前に確認します:
- 3つのロスレスクロップ。
frame --crop <x,y,w,h> --pngを、髪の毛、肩または袖の端、手の部分で、最終的に配信する背景の上で実行します。クロップは実際のスケールで返されるため、200~400ピクセルのボックスで十分です。 - もう完了? 髪、襟、手がしっかりしていて、端に最大1~2ピクセルの暗い、オリーブ、またはタンの線があるだけの場合:キーは完了しているので、次に進みます。その線はエッジフロアです。0.12から0.3のすべての設定でこの線が残り、
spillはすでにそれを緑からタンに変えているため、緑ピクセルカウントはそこでゼロと読み取られます。 - そうでない場合、欠陥ごとに1つの修正。 背景が髪、襟、または濃い色の服を通して見える場合:
toleranceを0.05下げます。エッジフロアより広い薄いまたは緑のハローがある場合:toleranceを0.03上げるか、softnessを0.03上げます。再度クロップして2に戻ります。最大3つの設定を、1つのキーされた要素に対してのみ行います。領域を分割したキーされたコピーはレンダリング時間を増やし、継ぎ目が残ります。 - ドリフト。
measureでキーされた要素を測定します。不透明な割合はテイク全体を通して1~2ポイント以内に収まるはずです。段差がある場合は、そこで照明が変わったことを意味します。段差の両側にtoleranceのキーフレームを設定するか、そのフレームで要素をカットして各部分を個別にキーします。
- 確認:
frameで話者が最も動く2つの瞬間の全体画像を確認し、輪郭が維持されていることを確認します。
発話のハイライト付きキャプション
キャプションは、手動ではなく、提供されたワードタイミングからバンドルスクリプトを通じて生成されます。python3 scripts/captions.py <project> <words> <spec>(specは--helpで確認)は、タイミングをチェックし、単語をmeasureで1行または2行のページに分割し、各単語に発話中のhighlightウィンドウを与え、キャプションを追加したプロジェクトを出力します。修復内容はすべてstderrにレポートされます。そのレポートを読んでください:それがタイミングチェックです。
- チェック内容: 発話が既に再開された後にフレーズが始まる単語(提供された「Now」が110ミリ秒遅く、20ミリ秒長い古典的なケース)、無音の中にある単語、重複する単語、表示するには短すぎる単語。短い単語は
min_word(150ミリ秒)まで延長されます。次の単語との間のポーズ、そして次の単語から時間を取ります。無音の中にある単語がレポートされた場合、ファイルがそこで位置ずれしていることを意味します。ファイルを修正してから再実行します。 - サイズ: 1080幅のフレームで56~72ピクセル、太字、行には明るい色、発話中の単語にはブランドのアクセントカラーを使用します。
- 行: 最大2行、
widthはフレーム幅の約80%。ページは文の終わりか400ミリ秒以上のポーズで改行します。 - 背景: 最も暗いブランドカラーを80~85%のアルファ(
CC~D9)にしたpillで、どの映像の上でも読みやすくなります。padは横28~36ピクセル、縦14~20ピクセル、radiusは20~28。 - 配置: 顎の下、かつ縦長フレームの下部15~20%(プレイヤーがコントロールを描画する領域)を避けます。1080×1920では、中心は
y1350~1450程度。ワイドフレームでは、下端から10~14%上に中央揃えします。 - ページ は次のページが始まるまで、またはより長いポーズが続く場合は最後の単語から1秒後まで表示されます。
実際のキャプションを書き出すため、validateでキャプションに関する指摘があればそれに従って修正します。
- 確認:
frame --from --toで1ページ分を確認。各ハイライト単語は独自のタイルになります。各タイルが発話順に正確に1つの単語をハイライトし、ボックスが顔にかからないことを確認します。次に、最も長いポーズ後の最初のフレームでframe --atし、新しいページが表示され、何も早期にハイライトされていないことを確認します。
映像上のネームバー
ローワーサードがワイプイン/ワイプアウトします。映像はフラットな色ではないため、montagent-motionのオクルーダーワイプでバー自体を表示することはできません。代わりに、バーは端から成長し、そのテキストはバー自身の色(フラット)のオクルーダーによって表示されます。
{
"frame": {"width": 1080, "height": 1920}, "fps": 30, "background": "#6E7B8B", "duration": 7000, "output": "out/namebar.mp4",
"fonts": {"bold": [{"file": "fonts/Inter-Bold.ttf"}]},
"fontVendor": {"fonts/Inter-Bold.ttf": {"licence": "OFL-1.1", "source": "https://github.com/rsms/inter", "sha256": "288316099b1e0a47a4716d159098005eef7c0066921f34e3200393dbdb01947f"}},
"tracks": [
{"name": "bar", "layer": 20, "elements": [
{"id": "bar", "type": "rect", "start": 1000, "end": 6534, "x": 64, "y": 1160, "origin": "center-left", "width": 760, "height": 160, "fill": "#101418", "radius": 8, "scale": [{"t": 1000, "v": [0.0, 1.0]}, {"t": 1300, "v": [1.0, 1.0], "ease": [0.65, 0, 0.35, 1]}, {"t": 6266, "v": [1.0, 1.0], "ease": "linear"}, {"t": 6533, "v": [0.0, 1.0], "ease": [0.65, 0, 0.35, 1]}]}
]},
{"name": "bar-edge", "layer": 21, "elements": [
{"id": "bar-edge", "type": "rect", "start": 1000, "end": 6534, "x": 64, "y": 1160, "origin": "center-left", "width": 12, "height": 160, "fill": "#FF5A36"}
]},
{"name": "bar-name", "layer": 22, "elements": [
{"id": "bar-name", "type": "text", "start": 1300, "end": 6266, "x": 108, "y": 1128, "origin": "center-left", "width": 400, "height": 70, "font": "bold", "size": 58, "color": "#F5F0E6", "runs": [{"text": "Montagent"}], "caption": false}
]},
{"name": "bar-line", "layer": 22, "elements": [
{"id": "bar-line", "type": "text", "start": 1300, "end": 6266, "x": 108, "y": 1196, "origin": "center-left", "width": 560, "height": 44, "font": "bold", "size": 34, "color": "#F5F0E6", "runs": [{"text": "Video your agent can read"}], "caption": false}
]},
{"name": "bar-cover", "layer": 23, "elements": [
{"id": "bar-cover-on", "type": "rect", "start": 1300, "end": 1700, "x": 800, "y": 1160, "origin": "center-right", "width": 716, "height": 140, "fill": "#101418", "scale": [{"t": 1300, "v": [1.0, 1.0]}, {"t": 1666, "v": [0.0, 1.0], "ease": [0.65, 0, 0.35, 1]}]},
{"id": "bar-cover-off", "type": "rect", "start": 6000, "end": 6266, "x": 84, "y": 1160, "origin": "center-left", "width": 716, "height": 140, "fill": "#101418", "scale": [{"t": 6000, "v": [0.0, 1.0]}, {"t": 6233, "v": [1.0, 1.0], "ease": [0.65, 0, 0.35, 1]}]}
]}
]}
- オン: バーは左端から250~350ミリ秒かけて成長します。
[0.65, 0, 0.35, 1]。テキストとそのカバーは、バーが完全に成長したフレーム(それより早くないこと。早いとカバーが映像の上に表示されます)から開始します。カバーはその遠い端を中心に300~400ミリ秒かけて縮小し、テキストを読む順序で表示します。 - オフ、 そのキューから開始:カバーが200~300ミリ秒でテキストの上に再び成長し、その後バーが250~300ミリ秒で端まで縮小します。バー全体はキューから450~600ミリ秒後に消えます。
- サイズ: 1080幅のフレームでバーの高さは130~180ピクセル、名前は52~64ピクセル、2行目は30~38ピクセル。先端に8~16ピクセル幅のアクセントストリップ。
- カバー: 正確にバーの
fill色、バーの端から内側に20ピクセル、上下から内側に10ピクセルの位置に、テキストの上に配置します。 - 配置: フレームの側面から48~80ピクセル内側、キャプションボックスと話者の顔を避け、通常は縦長フレームの高さの55~65%の位置。
- 確認: 各キューから1秒間、
frame --from --to --keyframesで確認し、どのタイルでもカバーがバーからはみ出していないことを確認します。静止状態のバーでframe --atし、その左端がキャプションボックスのマージンと揃っていることを確認します。
円形のピクチャー・イン・ピクチャー
別のクリップを円形で表示します。ビデオ要素に円形mask、その背後にリング、およびオーバーシュートベジェ曲線によるポップイン効果を使用します。
{
"frame": {"width": 1080, "height": 1920}, "fps": 30, "background": "#6E7B8B", "duration": 6000, "output": "out/pip.mp4",
"tracks": [
{"name": "pip-ring", "layer": 30, "elements": [
{"id": "pip-ring", "type": "ellipse", "start": 1000, "end": 5500, "x": 800, "y": 900, "origin": "center", "width": 384, "height": 384, "fill": "#F5F0E6", "scale": [{"t": 1000, "v": [0.0, 0.0]}, {"t": 1400, "v": [1.0, 1.0], "ease": [0.34, 1.56, 0.64, 1]}, {"t": 5233, "v": [1.0, 1.0], "ease": "linear"}, {"t": 5466, "v": [0.0, 0.0], "ease": "ease-in"}], "effects": [{"name": "shadow", "dx": 0, "dy": 16, "radius": 40, "color": "#101418", "opacity": 0.35}]}
]},
{"name": "pip", "layer": 31, "elements": [
{"id": "pip", "type": "video", "start": 1000, "end": 5500, "source": "media/clip.mp4", "source_start": 10000, "source_end": 14500, "volume": 0, "x": 800, "y": 900, "origin": "center", "width": 640, "height": 360, "fit": "contain", "scale": [{"t": 1000, "v": [0.0, 0.0]}, {"t": 1400, "v": [1.0, 1.0], "ease": [0.34, 1.56, 0.64, 1]}, {"t": 5233, "v": [1.0, 1.0], "ease": "linear"}, {"t": 5466, "v": [0.0, 0.0], "ease": "ease-in"}], "effects": [{"name": "mask", "shape": "circle", "x": 140, "y": 0, "width": 360, "height": 360}]}
]}
]}
- 円の矩形: 要素の高さと同じ正方形。その
xで画像のどの部分を表示するかを選択します。中央は(width - height) / 2で、これを使用します。ポップは要素のoriginを中心にスケーリングするため、中央から移動した円は成長するにつれて横にドリフトします。画像の別の部分を表示するには、その部分が中央に来るようなsource_startを選択するか、要素を大きくして目的の部分が円の内側に収まるようにxを設定し、ポップのカーブに合わせてxをキーフレーム設定して円の中心が静止するようにします。 - サイズ: フレーム幅の30~40%の直径。リングは円より12~24ピクセル広く、背景の最も明るい色で、ソフトな
shadowを付けます。 - ポップ: 両方とも、スケール0から、同じキーで
[0.34, 1.56, 0.64, 1]を使用して350~450ミリ秒。終了は200~300ミリ秒、ease-inで0に戻します。 - タイミング: 話者が最初に表示するものの名前を挙げたときに入り、終了の少し前に出て、クローズをきれいにします。
- 配置: 話者の隣、胸の高さ、顔とキャプションボックスを避け、フレームの端から40ピクセル以上離します。
- 音声:
volume0。ただし、クリップの音声自体が目的の場合は除きます。 - 確認: ポップのピーク時(開始から長さの40%後)に
frameで確認し、円が顔とフレーム端を避けていることを確認します。静止状態でframeし、重要な部分が円の内側にあることを確認します。
音声の下の音楽
音楽は、音声が話している間はダック(音量低下)し、ポーズ中に元に戻ります。scripts/duck.pyは、音声のワードタイミング(--words、...
[翻訳で切り詰められました]