name: export-final description: ユーザーが完成した動画ファイルを要求した場合に使用します - "exportier das", "render das fertig", "mach das final", "renderte das Video", "mach den Endexport", "bau das Video zusammen", "mach es fertig für YouTube", "gib mir die MP4", "export the final", "render the final cut", "make the master", "export for TikTok", "give me the mp4" など。セグメントレンダリング(キャッシュ利用)、ガード付き連結、ワンパスオーディオ、ラウドネス正規化、シングルマルチプレクサをカバーします。 argument-hint: [project-slug] [platform] arguments: [project, platform]
export-final
完成したファイルを組み立てます。引数: $project スラッグ、$platform は output.platform をオーバーライドし、ユーザーが2つ目のデリバラブルを希望する場合に使用します。完全なリクエストは $ARGUMENTS に含まれます。空の $-プレースホルダは、スキルがスラッシュ呼び出しではなく自動トリガーされたことを意味します。その場合、セッションコンテキストの PIPELINE_STATE からプロジェクトを取得し、選択したプロジェクトを伝えます。動詞名はビルドコントラクトに従います。python engine/ve.py --help が優先されます。
レンダリングアーキテクチャ(確定事項)
- ビデオ: セグメントごとに1つのキャッシュされたMP4/MKV、同一エンコードパラメータ、各セグメントはIDRフレームで開始し、
-f concat -safe 0 -c copyで結合。ロスレスかつほぼ瞬時であることが確認済み。 - オーディオ: タイムライン全体を1回の連続パスで
pcm_s24leにレンダリング。セグメントごとにキャッシュされることはありません。 - マルチプレクサは1回のみ、AACエンコードも正確に1回。
これをエクスポート時に再設計しないでください。特に、すべてのセグメントを単一の filter_complex に「簡略化」しないでください。150セグメントのグラフは約19,000文字になり、約260セグメントを超えるとWindowsコマンドラインがオーバーフローし、役立つエラーメッセージではなく起動できないプロセスになります。また、セグメントごとのキャッシュを捨てることになりますが、これこそが2回目のエクスポートを数秒で完了させる理由です。
フィルターグラフは常にファイルに書き込み、-/filter_complex fc.txt として渡します。長くなった場合だけでなく、無条件にこれを行います。
ステップ1 - プリフライト
エンコードを開始する前に:
- QCパスを実行します。QCに失敗するプロジェクトをエクスポートすると、パイプラインで最も長い操作を無駄にします。
output.platformを確認します。これにより、ラウドネスターゲット、解像度、キャプションのセーフエリアが決まります。$platformがoutput.platformと異なる場合、プロジェクトを黙って変更しないでください。代わりに2つ目の出力パスをレンダリングし、どちらがどちらかを明示します。- 計画を報告します: セグメント数、予想総フレーム数、予想時間、コーデック、およびこのパスでキャプションとグラフィックを焼き込むかどうか。
ステップ2 - セグメントのレンダリング
python engine/ve.py render $project
.cache/seg/ の下にセグメントごとにキャッシュされ、ソースのstrong key、入出力フレーム、フィルター、エンコーダー、ツールバージョンでキーが付けられます。変更されたセグメントのみが再レンダリングされます。--only seg_0012 で1つのセグメントを検査用にレンダリングします。
エンコーダーのデフォルト: h264_nvenc、cq 20、preset p6。このAdaカードのNVENCは、libx264と概ねVMAFで同等です(2 Mbpsで0.19 VMAF劣り、8 Mbpsで0.06優れている)が、2〜4倍高速です。プレビューには適切なデフォルトであり、最終版にも妥当な選択です。ユーザーがビットあたりの最大品質を求め、待つ意思がある場合にのみlibx264に切り替えてください。
どちらのエンコーダーも、このマシンでは実行ごとにバイトレベルで再現可能であり、これによってコンテンツアドレス可能なセグメントキャッシュが安全になります。
ステップ3 - 連結、ただし事前にガードする
concat_compatible() は、例外なくすべての -c copy 連結の前に実行します。 パラメータが一致しない場合、concatデマルチプレクサはexit 0で破損したファイルを出力します。警告もエラーもなく、10秒間再生してから崩れるファイルです。QCチェック(c) がこのチェックです。
すべてのセグメント間で、解像度、ピクセルフォーマット、コーデック、プロファイル、レベル、タイムベース、サンプルレート、チャンネルレイアウトを比較します。不一致がある場合、異なるパラメータでレンダリングされたセグメントがあることを意味します。通常、エンコーダー設定が変更される前の古いキャッシュエントリです。連結を強制するのではなく、該当するセグメントを再レンダリングしてください。
ステップ4 - オーディオとラウドネス
python engine/ve.py render $project
次に、output.loudnorm のプラットフォームターゲットに向けて2パス loudnorm を実行します(YouTube: I -14、TP -1.5、LRA 11。他のプラットフォームは異なり、presets/formats/ にあります)。
パス2では、明示的に -ar 48000 を指定する必要があります。 これを指定しないと、出力は暗黙的に192 kHzになります。loudnormの内部レートが出力に漏れ出し、ファイルは予想の4倍のサイズになり、一部のプレーヤーでリサンプリングがうまくいきません。これはチェーン全体で最も見落とされがちなフラグです。
1パスではなく2パス: 1パス loudnorm は動的な推定であり、静かな開始部分がある素材(これはベッド音のあるすべてのトーキングヘッドビデオに当てはまります)では、ターゲットから1デシベル以上ずれます。
ステップ5 - マルチプレクサは1回
ステップ2から5まではすべて ve render $project です。キャッシュされたセグメントをレンダリングまたは再利用し、それらを連結し、オーディオを1パスでレンダリングし、ラウドネス正規化を適用し、AAC 320kを projects/$project/out/final.mp4 に正確に1回だけ output.path に従ってマルチプレクスします。
マルチプレクサでビデオを再エンコードしないでください。画像に変更が必要な場合は、セグメントレベルで変更し、キャッシュが残りを処理します。
マルチプレクスの後、ve render はレンダリングされたオーバーレイを合成し、captions.burn_in が設定されている場合はASSを焼き込みます。この順序で行われるため、キャプションはグラフィックの上に表示されます。どちらもマスターを再エンコードするため、ve gfx と ve captions は ve render の前に実行するものであり、後ではありません。後で実行すると、マスターが1バージョン古いままになり、警告もありません。
ve export は別の後のステップです。完全なQCを実行し、失敗した場合は --force を指定しない限り拒否し、日付入りの配信用コピーにスタンプを押し、その隣に .manifest.json を書き込みます。
ステップ6 - デリバラブルを検証して引き渡す
計画ではなく、実際の出力ファイルに対して必須チェックを実行します:
- フレーム数が、有効なセグメントの
(out_frame - in_frame)の合計と一致する。QC (a)。 - オーディオサンプル数が
frames / fps * 48000と一致する。QC (b)。 ebur128統合ラウドネスがプラットフォームターゲットの0.5 LU以内、トゥルーピークが天井以下。QC (f)。- コンテナ、解像度、フレームレート、継続時間が
outputと一致する。 - 3フレームをスポットチェック: 最初、中間のセグメント境界、最後。境界での黒フレームは、セグメントが短くレンダリングされたことを意味します。
次に報告: 出力パス、ファイルサイズ、継続時間、測定されたLUFSとトゥルーピーク、フレーム数、セグメント数、キャッシュから取得したセグメント数。stage を "export" に設定します。
2つ目のデリバラブル
縦型カットは、完成したファイルの再クロップではありません。それは異なる output.platform であり、異なるラウドネスターゲット、異なるキャプションプリセット、異なるセーフエリア、そして通常は異なるストーリーパスを意味します。16:9のマスターをスケーリングするのではなく、そのように伝えてください。
障害モード
| 症状 | 原因 | 修正 |
|---|---|---|
| 出力が再生され、その後途切れる、ffmpegがexit 0 | concatでのパラメータ不一致 | すべてのconcatの前に concat_compatible() を実行。該当セグメントを再レンダリング |
| マスターが192 kHz | loudnorm パス2で -ar 48000 が欠落 | 追加してパス2を再実行 |
| エンコードプロセスが起動しない | コマンドライン上のフィルターグラフ | 常に fc.txt を書き込み、-/filter_complex を渡す |
| ラウドネスがターゲットから1デシベルずれる | 1パス loudnorm | 2パス |
| エクスポートが毎回遅くなる | エンコーダー設定の変更によりキャッシュが無効化 | 意図した変更であることを確認 |
| カット点で黒フレーム | セグメントが短くレンダリングされた | そのセグメントを再レンダリング。QC (a) を確認 |
| 最終版でプレビューより声が小さい | amix に normalize=0 がない | オーディオグラフを修正し、オーディオを再レンダリング |