composition について
EditframeのWebコンポーネントまたはReactコンポーネントで動画コンポジションを作るスキルです。シーン、メディア、時間、トランジション、レンダリングに共通のタイムラインモデルを提供します。
主な機能
- 01WebコンポーネントとReact構文
- 02シーンの順序と時間モード
- 03動画、音声、画像、テキスト要素
- 04タイムラインに同期するアニメーション
- 05ブラウザーまたはAPIからの動画出力
活用シーン
- 01動画クリップからシーンを構成
- 02ナレーション、音楽、効果音を追加
- 03時間指定テキストや音声字幕を作成
- 04コンポジションを動画として出力
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ editframe/ skills --skill compositionインストール後、Claude Code で/compositionを入力して読み込まれたか確認します。
詳細
動画コンポジション
Editframe の要素を使って動画シーンを作成します。<ef-timegroup> や <ef-video> などの Web コンポーネント、または <Timegroup> や <Video> などの React コンポーネントを使用します。どちらの構文も、同じコンポジションモデルと同じレンダリングパイプラインを共有します。プロジェクトに合った構文を選んでください。
Web コンポーネントの属性は、file-id や api-host のようにケバブケースを使用します。React の props は、fileId や apiHost のようにキャメルケースを使用します。このパターンに当てはまらない属性が 4 つあります。sourcein、sourceout、trimstart、trimend です。これらはそれぞれ、HTML 属性と React の prop の両方で同じ小文字の文字列を使用します。各属性の両方の形式については、「要素リファレンス」セクションをご覧ください。
Editframe に時間とメディアを管理させる
Editframe はコンポジションのクロックとすべてのメディアソースを管理します。タイミングとメディアは、Editframe の要素と属性を使って構成します。レイアウトと外観には CSS を使います。Editframe のフレームフック内で算出するビジュアルには JavaScript を使います。
| 必要なもの | Editframe のツール |
|---|---|
| シーン、シーンの順序、カット | mode="sequence" を指定した ef-timegroup |
| シーンの長さ | メディアから長さを決める場合は contain、編集上の区切りとして長さを指定する場合は duration を指定した fixed、親の長さに合わせる場合は fit |
| シーン内の開始時刻 | 子要素に offset を指定 |
| トランジション | シーケンスに overlap を指定し、--ef-transition-duration と --ef-transition-out-start を設定 |
| ビデオクリップとトリミング | sourcein、sourceout、trimstart、trimend を指定した ef-video |
| ナレーション、音楽、サウンドキュー | offset、volume、同じトリミング属性を指定した ef-audio |
| 画像 | ef-image |
| 時差をつけたテキスト | split と stagger を指定した ef-text |
| 音声の字幕 | 単語ごとのタイミング情報を含むトランスクリプトデータを指定した ef-captions |
| 音声に反応するビジュアル | target を指定した ef-waveform |
| 進行に応じて変化するスタイル | --ef-progress と --ef-duration |
| 各フレームの計算状態 | addFrameTask、React の onFrame、または useTimingInfo() |
| ビデオ出力 | ブラウザーエディターからエクスポートするか、renderTimegroupToVideo() または ef-workbench の exportVideo() メソッドを使う |
Editframe は、コンポジション内のすべての CSS アニメーションと element.animate() アニメーションも管理します。各アニメーションを一時停止し、その時間要素のローカル時刻に移動します。時間要素は、アニメーション対象の要素自身、または最も近い時間的祖先要素です。animation-delay はページ読み込み時ではなく、その要素の開始時点から計算されます。アニメーションは、それが追従するクロックを持つ timegroup の中に配置してください。
汎用的なブラウザーツールを使って、これらのシステムを再構築しないでください。
<video>要素や<audio>要素は使わないでください。Editframe はこれらのシークを行いません。エクスポート時に音声がミックスされるのは、ef-videoとef-audioのみです。setTimeout、setInterval、requestAnimationFrame、または実時間のクロックでイベントのタイミングを制御しないでください。これらのタイマーはシークやレンダリングクロックに対応しません。- コンポーネントのレンダリング時やフレームタスクの実行時に
Math.random()を呼び出さないでください。エクスポートではオフスクリーンクローン内で各フレームにシークし、一部のレンダリングではタイムラインの途中で新しいドキュメントが開始されます。そのため、プレビュー、レンダリング、レンダリングの各パートで値が変わってしまいます。値に変化をつける場合は、インデックスまたは渡された時刻から算出してください。ランダムな値には、モジュールスコープで一度だけ呼び出す、固定シードのジェネレーターを使ってください。表示内容にはDate、performance.now()、cryptoを使わないでください。これらは決定的ではありません。 - アニメーションライブラリのタイムラインを自動再生するなど、別のアニメーションクロックを動かさないでください。ライブラリアニメーションは一時停止状態で作成し、
addFrameTaskから渡された時刻にシークしてください。GSAP タイムラインは{ paused: true }を指定して作成し、秒単位でseek(ownCurrentTime)を呼び出します。anime.js アニメーションはautoplay: falseを指定して作成し、ミリ秒単位でseek(ownCurrentTime * 1000)を呼び出します。Three.js シーンはフレームタスク内でrenderer.render()を使ってレンダリングし、WebGLRendererはpreserveDrawingBuffer: trueを指定して作成してください。また、setAnimationLoop()は呼び出さないでください。 - Editframe の属性で編集内容を表現できる場合、メディアファイルをカット、結合、またはリミックスしないでください。
- 字幕テキストのタイミングを手作業で設定しないでください。単語ごとのタイミング情報を含むトランスクリプトデータを
ef-captionsに渡してください。
クイックスタート
<ef-timegroup mode="sequence" class="w-full h-full">
<ef-timegroup mode="fixed" duration="2s" class="absolute w-full h-full">
<ef-image src="logo.png" class="size-full object-contain"></ef-image>
<ef-text class="absolute inset-x-0 bottom-12 text-center text-white text-3xl">My Brand</ef-text>
</ef-timegroup>
<ef-timegroup class="absolute w-full h-full">
<ef-video src="main.mp4" class="size-full object-cover"></ef-video>
</ef-timegroup>
</ef-timegroup>
import { Timegroup, Video, Image, Text, TimelineRoot } from "@editframe/react";
const MyVideo = ({ id }: { id: string }) => (
<Timegroup id={id} mode="sequence" className="w-full h-full">
<Timegroup mode="fixed" duration="2s" className="absolute w-full h-full">
<Image src="logo.png" className="size-full object-contain" />
<Text className="absolute inset-x-0 bottom-12 text-center text-white text-3xl">My Brand</Text>
</Timegroup>
<Timegroup className="absolute w-full h-full">
<Video src="main.mp4" className="size-full object-cover" />
</Timegroup>
</Timegroup>
);
export const App = () => <TimelineRoot id="my-video" component={MyVideo} />;
この例では、2つの長さの決め方を示しています。ロゴカードでは fixed duration="2s" を使用しています。ロゴには自然な表示時間がないため、この長さは編集上の判断です。
2つ目のシーンは、デフォルトで contain モードです。唯一の子要素は main.mp4 なので、クリップによって長さが決まります。より長い音声の兄弟要素があると、このシーンの長さは延長されます。BGM の場合は、「タイムグループとシーケンス」の fit の例を参照してください。
レンダリングまたはエクスポートを行うすべての React コンポジションには、TimelineRoot ラッパーが必要です。その理由については、下記の React を参照してください。
この例では、<ef-configuration>/<Configuration> を使用せずにメディアを直接読み込みます。ローカル JIT トランスコーディング、API ルーティング、または署名には、このラッパーを追加してください。下記の「高度な設定」→「設定」を参照してください。
長さの単位
5s(秒) | 1000ms(ミリ秒) | 2m(分)
npm create @editframe を実行して、新しいプロジェクトを開始してください。詳細は editframe-create スキルを参照してください。
コアコンセプト
時間モデル
すべての要素(ef-timegroup、ef-video、ef-text など)は時間要素です。各時間要素は、秒単位の時間プロパティを2つ持ちます。
duration— 要素の長さです。ownCurrentTime— 要素のローカルな再生ヘッド位置です。Editframe は、最も近い祖先の時間に、要素自身のoffset/ウィンドウを加えてこの値を導出します。
メディア要素は、もう1つ時間プロパティを持ちます。currentSourceTime は、sourcein/トリム適用後の、元のソースファイル内の位置です。
ルート要素の currentTime だけが直接書き込みを受け付けます。seek() または seekForRender() で設定してください。Editframe は、他のすべての時間値をルートから導出します。導出された各値は、ツリーを下方向に一方向に伝わります。
これらのプロパティには *Ms 形式(durationMs、ownCurrentTimeMs など)も後方互換性のために残されています。これらの形式は非推奨です。新しいコードでは秒単位のフィールドを使用してください。
Editframe は、次の4つのトリム属性をサポートしています。
sourcein/sourceout— ソースファイル内のウィンドウを選択します。trimstart/trimend— 要素自身の長さの先頭または末尾から時間をカットします。
fixed、contain、または fit の親要素内で子要素の位置を指定するには、offset を使用してください。
タイムグループとシーケンス
ef-timegroup は唯一のコンテナー要素です。その mode 属性は、タイムグループ自体の長さと、各子要素の時間範囲の2つを制御します。以下の表に各モードを示します。
| モード | 長さ | 子要素 |
|---|---|---|
fixed | duration 属性で指定します。 | それぞれの offset に配置され、並行して再生されます。 |
sequence | 子要素の長さを合計し、隣接する各ペア間の overlap を差し引いた長さです。 | 順番に再生され、アクティブな要素のみが表示されます(hidden が切り替わり、data-active 属性が設定されます)。 |
contain(デフォルト) | 子要素の offset + duration のうち、最も後の時点までの長さです。 | それぞれの offset に配置され、並行して再生されます。 |
fit | 最も近い祖先タイムグループの長さを継承します(ルートの場合は contain にフォールバックします)。 | それぞれの offset に配置され、並行して再生されます。 |
一連のシーンを順番に再生するには、sequence モードを使用します。上記のクイックスタートの例を参照してください。overlap(overlap="1s" のような CSS 時間値)を設定すると、次のシーンの開始時点がその値だけ早まります。これにより、次のシーンを前のシーンの末尾と同時に再生でき、クロスフェードやトランジションの時間を設けられます。
モードを選ぶときは、次の1つの質問を考えてください。この要素の長さをメディアが決めるのか、それとも自分で設定するのか?
- メディア主導。 動画クリップ、ナレーション、または長さがコンテンツ自体によって決まるものに使用します。
durationは設定しないでください。modeは未設定のままにして、デフォルトのcontainを使います。タイムグループの長さはコンテンツから決まります。この方法を選ぶと、コンポジションを再利用可能なテンプレートにできます。最終的なメディアの長さがわかる前にタイムラインを作成できます。後から長さの異なるクリップに差し替えても、手動で変更することなくタイミングが機能します。 - 編集上の選択。 タイトルカード、長さを固定したアウトロ、自分でタイミングを決める場面に使用します。ここでは自然に導き出せる長さがありません。
fixed duration="..."を設定してください。 - 継承。
fitモードは、要素自体のコンテンツの長さではなく、常に最も近い祖先タイムグループの長さに追従します。長さが事前にわからない相対要素と、要素の長さを正確に一致させる必要がある場合は、fitを使用します。最もよくあるのは、シーンのsequenceの下に背景音声を配置するケースです。
<ef-timegroup class="w-full h-full">
<ef-timegroup mode="sequence" class="absolute w-full h-full">
<ef-timegroup mode="fixed" duration="3s" class="absolute w-full h-full">
<ef-video src="a.mp4" class="size-full object-cover"></ef-video>
</ef-timegroup>
<ef-timegroup class="absolute w-full h-full">
<ef-video src="b.mp4" class="size-full object-cover"></ef-video>
</ef-timegroup>
</ef-timegroup>
<ef-timegroup mode="fit">
<ef-audio src="bed.mp3" volume="0.3"></ef-audio>
</ef-timegroup>
</ef-timegroup>
音声はシーケンスと正確に同じ長さだけ再生されます。現在、シーケンスの長さは8秒です。明日、クリップを変更した後は12秒になります。どちらの場合も、長さを手動で同期する必要はありません。
すべてのシーンでデフォルトとして fixed を使わないでください。テンプレートの主な利点が失われます。メディアソースの長さが変わるたびに手動でタイミングを調整する必要が生じ、コンポジションが自動で適応できなくなります。
トランジション
sequence タイムグループの overlap を使ってトランジションを作成します。Editframe に個別のトランジション要素はありません。シーケンスに overlap を設定すると、Editframe は重なり合う各子シーンに2つの CSS カスタムプロパティを設定します。
--ef-transition-duration— 重なりの時間(秒単位)です。--ef-transition-out-start— シーンの終了アニメーションを開始する時点(秒単位)です。これはduration - overlapと等しくなります。
この2つのプロパティを使って、シーンのフェード、スライド、ズームの遅延と長さを設定します。Editframe はアニメーションをシーンのクロックに合わせてシークするため、どのシークやレンダリングでも終了タイミングが正しく保たれます。
<ef-timegroup mode="sequence" overlap="0.5s">
<ef-timegroup mode="fixed" duration="3s" class="scene">
<ef-video src="a.mp4" class="size-full object-cover"></ef-video>
</ef-timegroup>
<ef-timegroup mode="fixed" duration="3s" class="scene">
<ef-video src="b.mp4" class="size-full object-cover"></ef-video>
</ef-timegroup>
</ef-timegroup>
<style>
.scene {
animation: fade-out linear;
animation-duration: var(--ef-transition-duration, 0s);
animation-delay: var(--ef-transition-out-start, 9999s);
animation-fill-mode: forwards;
}
@keyframes fade-out {
to { opacity: 0; }
}
</style>
時間変数
Editframe は、シークのたびにすべての時間要素に2つの CSS カスタムプロパティを公開します。
--ef-duration— CSS 時間値(たとえば5s)で表した要素自体の長さです。--ef-progress— 単位のない0から1までの数値です。
これらのプロパティを使って、要素のクロックに連動するスタイルを設定できます。スクリプトは不要です。
ef-timegroup[mode="fixed"] .progress-bar {
transform: scaleX(var(--ef-progress));
}
ef-text のセグメント(以下を参照)には、--ef-index、--ef-word-index、--ef-stagger-offset、--ef-seed も設定されます。ef-captions の単語には、--ef-word-index、--ef-word-seed、--ef-word-start が設定されます。
スクリプティング
Editframe には、コンポジションのクロックと同期して JavaScript を実行するためのフックが 2 つあります。requestAnimationFrame の代わりにこれらのフックを使用してください。
フレームごとの状態を requestAnimationFrame、setInterval、または実時間ベースのタイマーで制御しないでください。 ブラウザーは、バックグラウンドのタブやウィンドウで requestAnimationFrame のコールバックを間引いたり、完全に停止したりします。ヘッドレスエクスポートとオフスクリーンエクスポートは、常にこのバックグラウンド状態で実行されます。プレビュータブがフォーカスを失うと、通常の編集でもこの状態になることがよくあります。requestAnimationFrame で制御されるコンポジションは、アニメーションが気付かないうちに停止するか、レンダークロックと同期しなくなります。
addFrameTask にはこのような問題がありません。シーク/レンダーパイプラインが、レンダリングされるすべてのフレームで直接呼び出します。タブの表示状態に関係なく、正しく動作します。
timegroup.initializer = (timegroup) => { ... }— HTML 属性ではなく、JavaScript 専用のプロパティです。インスタンスごとに 1 回、レンダークローンごとに 1 回実行されます(「レンダリング」を参照)。同期関数として記述してください。内部で何もawaitしないでください。addFrameTaskコールバックの登録や状態の設定に使用します。内部からresolveDuration()またはaddFrameTaskを呼び出せます。エラーがスローされた場合、または実行時間が 10ms を超えた場合は警告が記録されます。実行時間が 100ms を超えた場合はエラーが記録されます。timegroup.addFrameTask((info) => { ... })— フレームごとのコールバックを登録します。Editframe は、シークのたびに{ ownCurrentTime, currentTime, duration, percentComplete, element }(時間はすべて秒単位)を指定してこのコールバックを呼び出します。このメソッドは登録解除関数を返します。
<ef-timegroup id="scene" mode="fixed" duration="5s">
<ef-text id="counter" class="absolute inset-0 flex items-center justify-center text-6xl"></ef-text>
</ef-timegroup>
<script>
const scene = document.getElementById("scene");
scene.initializer = (timegroup) => {
const counter = timegroup.querySelector("#counter");
timegroup.addFrameTask(({ ownCurrentTime }) => {
counter.textContent = Math.floor(ownCurrentTime * 10).toString();
});
};
</script>
React では、同じ関数を <Timegroup> の initializer/onFrame プロパティとして渡します。onFrame は、単一の addFrameTask 呼び出しの省略形です。
メディア要素
すべての動画、音声、画像のソースは、ef-video、ef-audio、または ef-image を通じて読み込みます。それぞれが時間軸上のリーフ要素です。Editframe はプレビューとエクスポート時に、コンポジションの時間に合わせてシークします。エクスポート時には、ef-video と ef-audio 要素の音声がミックスされます。
メディアの編集には、個別のメディアツールではなく属性を使用します。
sourceinとsourceoutでソースの一部を選択します。trimstartとtrimendで、要素自体の長さから時間をカットします。offsetで、シーン内にクリップや効果音を配置します。volumeで音量を設定するか、muteで消音します。ef-surfaceで、動画のデコード済みフレームをもう一度表示します。
属性の全一覧(トリミング、音量、バリアントラダー、FFT 解析など)は、以下の「要素リファレンス」を参照してください。いくつかの要素には、補足説明が必要な動作があります。
ef-text は、テキストコンテンツを子の ef-text-segment に分割します。分割単位は split="word"、split="char"、または split="line" で指定します。stagger(CSS の時間値)を設定すると、各セグメントの開始を遅らせられます。
各 ef-text-segment はシャドウルートを持たず、ライト DOM 内にレンダリングされます。--ef-index、--ef-word-index、--ef-stagger-offset、--ef-seed のカスタムプロパティを持ちます。
セグメント自体に入場アニメーションを設定します。各セグメントは開始後も表示されたままです。次のスタッガー付きセグメントが始まると、その data-active 属性は終了します。一時的な強調表示には、この属性を使用します。[data-active] に設定した入場アニメーションは、アニメーション終了前に次のセグメントが始まると、早期に停止します。
@keyframes pop-in {
from { opacity: 0; transform: scale(0.5); }
}
ef-text-segment {
animation: pop-in 0.4s calc(var(--ef-stagger-offset)) both;
}
ef-captions は、次の3つの方法でキャプションデータを受け取ります。
captions-src— JSON ファイルの URL。captions-script— インラインの<script type="application/json">要素の ID。captions.captionsData = {...}— HTML 属性ではなく、JavaScript プロパティです。コードで動的に生成した文字起こしに使用します。
JSON データには segments 形式または word_segments 形式を使用します。各単語またはセグメントには、秒またはミリ秒単位の start と end が含まれます。Editframe は数値の大きさから単位を判定します。
ef-captions-active-word のパートまたは子要素を通じて、アクティブな単語をスタイル設定できます。または、--ef-word-index/--ef-word-seed を使用して、単語ごとのスタッガー効果を設定できます。
ef-waveform は、ef-audio または ef-video の target を視覚化します。mode は bars、line、curve、bricks、pixel、wave、spikes、roundBars から選択します。
ef-surface は、別の要素のピクセルを自身のキャンバスにミラーリングします。target には、キャンバスまたは任意の HTMLElement を指定します。動画を再デコードすることなく、デコード済みフレームを別のスタイルの要素で再利用できます。
レンダリング
ブラウザーでのエクスポート。 @editframe/elements の renderTimegroupToVideo(timegroup, options) を呼び出すと、レイアウト済みの ef-timegroup を動画ファイルにエンコードできます。この関数は WebCodecs を使用し、再生と同じ seekForRender 経路を実行します。
主なオプション:
width/height/fpsfrom/to— 秒単位のエクスポート範囲です。videoCodec/audioCodec/videoBitrate/audioBitratetarget—mediabunnyの出力ターゲットです。signal—AbortSignalです。onProgress(({ frame, totalFrames, time, duration }) => ...)
直接呼び出すと、渡した timegroup のシークが行われ、その状態が変更されます。そのコンポジションがライブのインタラクティブなプレビューとしても使われている場合は、直接呼び出さないでください。
誰かが現在表示または編集中のコンポジションをエクスポートする場合は、createRenderClone を直接呼び出さないでください。この関数は内部プリミティブであり、公開 API ではありません。代わりに、次の 2 つの方法のいずれかを使用してください。
- アプリ内のカスタムエクスポートアクションでは、
ef-workbenchのexportVideo()メソッドを呼び出してください(editor-guiスキルを参照)。このメソッドがオフスクリーンコピーを複製、レンダリングし、破棄します。 - クラウドレンダリング(
@editframe/apiのcreateRender)では、追加の操作は不要です。この経路はすでにwindow.EF_RENDERを経由しており、これは自動的にインストールされ、オフスクリーンクローンを処理します。
カスタムレンダリングデータ。 レンダリングホスト(たとえば Playwright スクリプト)は、コンポジションの実行前に任意の JSON を window.EF_RENDER_DATA に注入できます。ブラウザーでは、モジュールレベル関数の getRenderData<T>() または React フックの useRenderData<T>() を使ってこのデータを読み取ります。これを使うと、コンポジション自体をテンプレート化せずに、たとえばユーザー名を使ってレンダリングをパラメーター化できます。
ランタイムとクラウドレンダリング。 このスキルで扱うのはブラウザー内でのエクスポートのみです。インストール済みの Editframe ランタイムを通じたエクスポートについては、editframe-api スキルの CLI セクションを参照してください。サーバーサイドのレンダリングジョブと文字起こしジョブについては、editframe-api スキルのほかのセクションを参照してください。
React
レンダリングまたはエクスポートを行う React コンポジションには、TimelineRoot ラッパーが必要です。TimelineRoot はコンポジションをマウントし、クローンファクトリーも登録します。exportVideo() と window.EF_RENDER(上記の「レンダリング」を参照)は、このファクトリーを使ってオフスクリーンのレンダリング用クローンを作成します。このファクトリーを使うと、クローンはフック、initializer、onFrame クロージャーが機能する、React のライブな 2 つ目のマウントになります。ファクトリーがない場合、クローンはこれらを一切持たない、動作しない cloneNode コピーになります。
const MyTimeline = ({ id }: { id: string }) => (
<Timegroup id={id} mode="sequence">
<MyScenes />
</Timegroup>
);
<TimelineRoot id="root" component={MyTimeline} />
component プロパティは React.ComponentType<{ id: string }> である必要があります。ルートに <Timegroup id={id}> を直接、またはネストされたカスタムコンポーネントを介してレンダリングする必要があります。TimelineRoot は、ライブマウントとクローンの両方で、マウントのたびに id を component に渡します。
フック(すべて @editframe/react から提供):
useTimingInfo()— 返されたrefをTimegroupに設定します。各フレームで、コンポーネントが{ ownCurrentTime, duration, percentComplete }(秒単位)とともに再レンダリングされます。useMediaInfo(ref)—VideoまたはAudio要素のrefを渡します。{ readyState, duration, currentTime, paused }を返します。usePanZoomTransform(ref)—PanZoom要素のrefを渡します。{ transform: { x, y, scale }, reset(), fitToContent(padding?), screenToCanvas(x, y), canvasToScreen(x, y) }を返します。useRenderData<T>()— 上記の「レンダリング」を参照してください。usePlayback(target)— 再生、一時停止、シーク、音量の状態を購読します。カスタムプレビューコントロールの作成に使用できます。editor-guiスキルのすぐに使える GUI コンポーネントを使えば、このフックの大半の用途を置き換えられます。
高度な内容
設定。 ef-configuration/<Configuration> は、メディアのルーティングと認証の設定を提供します。ローカルメディアを直接読み込み、API ルートや署名が不要な場合は省略できます。
インストール済みの Editframe ランタイムを使うプロジェクトでは、メディアはランタイムが管理します。カスタム設定でローカルの JIT トランスコードを行う場合は、メディアの子要素が接続される前に、先祖の設定に api-host を設定してください。ローカルメディアルートを公開するブラウザーのオリジンを使用します。どちらの設定についても、dev-server スキルを参照してください。
認証が必要なメディアでは、デプロイ先に合わせて api-host と signing-url を設定してください。image-proxy 属性は、クロスオリジン画像のプロキシ処理を制御します。属性の一覧については、以下の「要素リファレンス」を参照してください。
media-engine は今後の使用に備えて予約されています。現在利用できるエンジンはローカルレンダリングのみです。
React Three Fiber。 <Timegroup> の子要素を、@editframe/react/r3f の <CompositionCanvas> でラップします。これにより、コンポジションの時間と同期する R3F の <Canvas> が利用できます。シーンコンポーネント内で useCompositionTime() を使ってクロックを読み取ります。この関数は秒単位の { time, duration } を返します。
<Timegroup mode="fixed" duration="14s">
<CompositionCanvas shadows>
<MyScene />
</CompositionCanvas>
</Timegroup>
メインスレッドを空けたまま Web Worker で 3D をレンダリングするには、OffscreenCompositionCanvas を使用します。Worker は自分で構築してください。ワーカーのスクリプト内で呼び出す、@react-three/offscreen 独自の render() 関数で制御します。renderOffscreen エクスポートはありません。
サーバーサイドレンダリング。 @editframe/react/server と @editframe/elements/server は、コンポジションコンポーネントと型のみをエクスポートします。カスタム要素の登録や、DOM、canvas、WebCodecs のコードは含まれていません。Next.js または Remix のサーバーコードから安全にインポートできます。
これらのサーバーエントリーポイントには、GUI コンポーネントやフックは含まれていません。代わりに、dynamic(() => import("@editframe/react"), { ssr: false }) または同等の方法を使って、クライアント側でレンダリングしてください。
Next.js では、@editframe/nextjs-plugin の withEditframe() で next.config.mjs をラップし、ルートハンドラーを追加します。設定とオプションについては、dev-server スキルを参照してください。動作する例については、editframe-create スキルの nextjs テンプレートを参照してください。
いずれかのサーバーエントリーポイントから利用できる getRenderInfo() は、呼び出し時に ef-timegroup がマウントされた有効な document が必要です。レンダリングされたページ内でのみ呼び出してください。たとえば、Playwright スクリプトやクラウドレンダリングホストから呼び出せます。サーバー上で HTML 文字列を解析するために呼び出さないでください。
パッケージのエントリーポイント
| インポート | 環境 | 内容 |
|---|---|---|
@editframe/elements | ブラウザー | すべてのカスタム要素、canvas/WebCodecs レンダリング。 |
@editframe/elements/server | ブラウザー、Node、SSR | 型のみと、getRenderInfo()(実行時はブラウザーのみ)。 |
@editframe/elements/gui | ブラウザー | エディター GUI のカスタム要素(タイムライン、スクラバー、ハンドルなど) — editor-gui スキルを参照してください。 |
@editframe/elements/styles.css、/theme.css | ブラウザー | ベーススタイルとテーマスタイル。 |
@editframe/react | ブラウザー | React のコンポジションと GUI コンポーネント、フック。 |
@editframe/react/server | ブラウザー、Node、SSR | コンポジションコンポーネントのみ。フックや GUI は含まれません。 |
@editframe/react/r3f | ブラウザー | CompositionCanvas、OffscreenCompositionCanvas、useCompositionTime。 |
スタイリング
CSS または Tailwind で要素をスタイリングします。スタイルはレイアウトと外観を制御します。Editframe の要素と属性は時間を制御します。子要素の位置には absolute を指定します。サイズには w-full h-full または size-full を指定します。
コンポジションの作成方法
意図したシーケンスと後からの編集に適した構造を選びます。以下のガイダンスは、HTML と React のコンポジションに適用されます。
シーン構成
シーンごとに独立したローカルクロックが必要な場合は、入れ子のタイムグループを使用します。前述の時間モデルから contain、fixed、または fit を選択します。シーンの ownCurrentTime はゼロから始まるため、前のシーンに依存せずにアニメーションできます。
sequence は、隣接するすべての子要素に同じ overlap 値を適用します。トランジションごとに異なる時間が必要な場合は、個別のグループまたは明示的なオフセットを使用します。両隣のシーンより短いオーバーラップの場合、合計時間は sum(durations) − overlap × (n−1) になります。宣言された各シーンの長さには、そのシーンのトランジション時間が含まれます。
sequence は非アクティブなシーンを非表示にします。クロスフェードなど、ビジュアルデザインで必要な場合にのみ、シーンレベルの不透明度を追加します。トランジション変数はオーバーラップ区間を表すもので、すべての要素が同時に表示・非表示になる必要はありません。
シーン固有のアニメーションは、そのシーン内に配置します。動きが複数のシーンや常時表示されるオーバーレイにまたがる場合は、親フレームタスクを使用します。指定された時間から状態を導出すると、任意の位置へのシークや逆方向へのシークでも同じフレームを再現できます。増分シミュレーションでは、決定論的なリセットと再生の戦略が必要です。
アニメーション
まず Editframe の構造でタイミングを設定します。各ビートに独自のタイムグループを割り当てます。offset を使って、ビート内に要素を配置します。ef-text の split と stagger でテキストを表示します。トランジション変数を使ってシーンを終了します。
次に、各ビジュアルプロパティの変化方法を選びます。
- 固定タイムラインで記述できる動きには、キーフレームを使用します。Editframe は、時間要素のクロックに合わせてキーフレームをシークします。
- 手続き型のジオメトリ、カウンター、その他の計算された状態には、
addFrameTaskまたは React のonFrameを使用します。 - 要素の進行状況に連動するスタイルには、
--ef-progressを使用します。
単一の表示パターンに頼らず、デザインに合わせて表示、保持、終了のタイミングを設定します。表示方法、トランジション、注目を集める演出を選ぶ際は、モーションデザインカタログを使用します。
- 繰り返し要素では、インデックスから固定遅延を一度だけ計算します。
- 環境アニメーションのループでは、各アイテムに個別の位相を設定し、キーフレームを繰り返します。
- トランスフォームを個別に適用するには、入れ子のラッパーを使うか、トランスフォームを明示的に合成します。
sequenceのオーバーラップ中に終了させるには、--ef-transition-out-startと--ef-transition-durationを使用します。
各アニメーションの前後に意図する状態に合わせて、アニメーションのフィルモードを設定します。
- 遅延中に最初のキーフレームを適用するには、
backwardsを使用します。 - 完了後も最後のキーフレームを保持するには、
forwardsを使用します。 - 両方の状態を保持する必要がある場合は、
bothを使用します。
これらのルールはテキストセグメントにも適用されます。Editframe はフィルモードを自動的に追加しません。同じプロパティに対するアニメーションが重なっていないか確認してください。保持された状態が別のアニメーションを上書きする場合があります。
CSS のトランスフォームアニメーションは、デフォルトで静的なトランスフォームを置き換えます。別のラッパーを使うと、内側の要素をアニメーションさせながら、中央揃えなどのレイアウト用トランスフォームを維持できます。
アセット
プレビューとエクスポートの両方で解決できるアセット URL を使用します。インストール済みの Editframe ランタイムでは、ブラウザーエディターまたはエージェントランタイムからメディアをインポートします。新しいソースファイルはそれぞれ、プラグインの source.files リストに追加します。カスタム設定でローカルメディアルートを使用する場合、ローカルパスは設定済みの root を基準に解決されます。
バンドラーにアセットを含める必要がある場合は、アセットのインポートまたは別のサポート対象のバンドラー参照を使用します。src/ 内に配置しただけでは、ファイルはインライン化されません。パブリックディレクトリ内のファイルには、ホストまたは別途パッケージ化する手順が必要です。最終的なエクスポート環境で、未解決の URL がないか確認します。
後で変更する可能性がある編集可能なソースアセットは保持します。トリミングやオフセットなどの時間的な編集には、コンポジション属性を使用します。ラウドネスの正規化など、必要な効果に応じてメディアを事前処理します。唯一のソースファイルに対して、破壊的な編集を繰り返すのは避けてください。
React では、<Image> はカスタム要素をラップします。alt プロパティは受け取りません。HTMLImageElement ではなく、HTMLElement と互換性のある要素参照を使用してください。
オーディオ
プレビュー時と書き出し時のタイミングを一致させる必要がある場合は、コンポジションにオーディオを含めます。
sequence の直接の子要素は、もうひとつのビートになります。連続する音楽のベッドは、外側のタイムグループの下で、シーケンスの隣に配置します。上記のように、長さが不明な場合にベッドを追従させるには fit を使用します。再生時間が固定の場合は、その長さに合わせてベッドを制限します。短いオーディオソースで長い動画全体をカバーするには、明示的なリピート方法が必要です。
シーン固有の効果音は、そのシーンの中に配置します。offset はシーンの開始位置を基準に設定します。ソースの選択と時間方向のトリミングには、sourcein/sourceout と trimstart/trimend を使用します。
volume はデシベルではなく、線形ゲイン値です。要素によって値は 0~1 の範囲に制限されます。1 を超える値でもソースは増幅されません。増幅が必要な場合は、オフラインでゲインを適用します。クリッピングがないことを確認してください。
検証
開発中は、代表的なフレームを確認します。冒頭、テキストの多いフレーム、トランジションの境界、終端を含めてください。seekForRender() の完了を待ってから撮影したブラウザーのスクリーンショットは、レイアウトの確認に役立ちます。書き出したフレームからは、キャプチャ時の差異も確認できます。
納品前に、想定する出力をレンダリングします。レンダリングした動画を再生し、タイミング、連続性、読みやすさ、トランジションを確認します。効果音の配置、音声の明瞭さ、音楽のバランス、クリッピングの有無も確認します。エンコードが正常に完了しただけでは、映像や音声の品質が保証されたことにはなりません。
出力メタデータで、長さ、寸法、フレームレート、オーディオストリームを確認します。実際の出力パスを使用してください。
ffprobe output/demo.mp4
ffmpeg -i output/demo.mp4 -af volumedetect -f null -
音量統計は、無音やクリッピングのリスクを検出するのに役立ちますが、実際に聴いて確認する代わりにはなりません。レンダリングや確認ができない場合は、その制約と、実施できる確認項目を報告してください。
フィードバックを送信する
問題や改善案について、Editframe にフィードバックを送信してください。
- Editframe またはこのスキルが原因で問題が発生した場合は、回避策を見つけてタスクを続行してください。その後、問題と回避策を報告してください。
- 現在のタスクだけでなく、ほかのタスクにも役立つ改善案を見つけた場合は、提案を送信してください。たとえば、より明確な指示、不足している例、より適切なデフォルト、新機能などを提案できます。
問題や提案の内容が異なる場合は、それぞれ個別に報告してください。報告に失敗した場合も、タスクを続行してください。
curl -sS https://editframe.com/api/v1/feedback \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $EDITFRAME_API_KEY" \
--data-binary @- <<'JSON'
{
"category": "bug",
"skill": "composition",
"summary": "One line that names the problem or the suggestion",
"details": "For a problem: steps, expected result, actual result, and errors. For a suggestion: the change and how it helps.",
"workaround": "The workaround that you used. Omit this field for a suggestion."
}
JSON
category は bug、documentation、feature_request、performance、other のいずれかに設定してください。API キーは任意です。キーなしの報告は匿名になります。報告にシークレット、API キー、個人データを含めないでください。すべてのフィールド、制限、応答については、editframe-api スキルを参照してください。
要素リファレンス
ef-audio
<ef-audio>はコンポジション内で音声を再生します。
属性
| 属性 | React プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|---|
duration | duration | string | — | この要素がアクティブな時間(CSS の時間値。例:"5s")。 |
fft-decay | fftDecay | number | 8 | getFrequencyDataで平均化する減衰フレーム数(デフォルトは8)。 |
fft-gain | fftGain | number | 3 | 周波数解析の前に適用する線形ゲイン(デフォルトは3.0)。 |
fft-size | fftSize | number | 128 | getFrequencyData/getTimeDomainDataのFFTウィンドウサイズ(2の累乗に丸められます。デフォルトは128)。 |
file-id | fileId | string | null | — | クラウドファイル識別子。${apiHost}/api/v1/files/${fileId}に解決され、srcより優先されます。 |
interpolate-frequencies | interpolateFrequencies | boolean | false | 最近傍サンプリングの代わりにFFTバンド間を補間して、getFrequencyDataのビンを滑らかにします。 |
loop | loop | boolean | false | ループ属性。PlaybackController配下の自動駆動ルートとしてこの時間要素が動作する場合、コントローラーはdurationで一時停止せずに0へ戻ります。 |
mute | muted | boolean | false | この要素の音声をミュートします。 |
offset | offset | number | — | 並列(fixed/contain/fit)の親タイムグループ内での開始オフセット(秒)。 |
sourcein | sourcein | string | — | ソースファイル内の開始時間(CSS の時間値。例:"1.5s")。 |
sourceout | sourceout | string | — | ソースファイル内の終了時間(CSS の時間値。例:"1.5s")。 |
src | src | string | — | ソース音声ファイルの URL。 |
trimend | trimend | string | — | ソースの末尾からトリミングする長さ(CSS の時間値)。 |
trimstart | trimstart | string | — | ソースの先頭からトリミングする長さ(CSS の時間値)。 |
volume | volume | number | 1 | 音量(0.0~1.0)。 |
発火イベント
child-duration-changed({ duration: number })— ネストされたメディア要素の長さが判明または変更されたとき、最も近いコンテキスト提供祖先で発火します。
ef-captions
<ef-captions>は、単語単位のハイライト付きで同期字幕を表示します。
属性
| 属性 | React プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|---|
captions-script | captionsScript | string | "" | captionsSrcの代替として、字幕データを含む<script type="application/json">要素の ID を指定します。 |
captions-src | captionsSrc | string | "" | segments/word_segments形式の字幕データを含む JSON ファイルの URL またはパス。 |
duration | duration | string | — | この要素がアクティブな時間(CSS の時間値。例:"5s")。 |
loop | loop | boolean | false | ループ属性。PlaybackController配下の自動駆動ルートとしてこの時間要素が動作する場合、コントローラーはdurationで一時停止せずに0へ戻ります。 |
offset | offset | number | — | 並列(fixed/contain/fit)の親タイムグループ内での開始オフセット(秒)。 |
target | target | string | "" | 字幕のタイミングの基準となる<ef-video>/<ef-audio>要素の ID。 |
word-style | wordStyle | string | "" | 自由形式のスタイル指定フック(組み込みの動作はありません)。@editframe/elementsのword-style属性を反映し、これを対象とする利用側の CSS/セレクターが引き続き機能するようにします(例:ef-captions[word-style="highlight"])。 |
発火イベント
child-duration-changed({ duration: number })— ネストされたメディア要素の長さが判明または変更されたとき、最も近いコンテキスト提供祖先で発火します。
ef-captions-active-word
<ef-captions-active-word>は、現在読み上げられている単語を<ef-captions>内で囲みます。
ef-captions-after-active-word
<ef-captions-after-active-word>は、<ef-captions>内でアクティブな単語の後に続く字幕テキストを囲みます。
ef-captions-before-active-word
<ef-captions-before-active-word>は、<ef-captions>内でアクティブな単語の前にある字幕テキストを囲みます。
ef-captions-segment
<ef-captions-segment> は、1 行の字幕に含まれる再生前・再生中・再生後の単語要素をまとめます。<ef-captions> 内に独自に記述しない限り、<ef-captions> がこの要素を自動的に作成します。
ef-configuration
<ef-configuration> はルート設定要素です。
属性
| 属性 | React プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|---|
api-host | apiHost | string | "" | ファイル/アセットのリクエストに使用する Editframe API のベース URL です。 |
image-proxy | imageProxy | "auto" \ | "none" | "auto" |
media-engine | mediaEngine | string | "local" | 将来のエンジン切り替え用に予約されています。ローカルレンダリングでは常にデフォルトのコーデックセットを使用します。 |
signing-url | signingURL | string | "/@ef-sign-url" | 認証が必要なクロスオリジンのメディアアクセス用に、署名付きベアラートークンをリクエストする URL です(デフォルトは "/@ef-sign-url" で、@editframe/elements と一致します)。 |
発火するイベント
playback-attached({ controller: PlaybackController }) —EFConfigurationElement.attachPlaybackが新しいPlaybackControllerを作成したときに発火します。これにより、アタッチ前にPlaybackBridgeを解決した GUI コントロールは、ポーリングせずにその通知を受け取れます。
ef-image
<ef-image> は、静止画像の時間ベースのリーフ要素です。
属性
| 属性 | React プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|---|
asset-id | assetId | string | null | — | 非推奨の file-id エイリアスです。 |
duration | duration | string | — | この要素が有効な時間です(CSS 時間、例:"5s")。 |
file-id | fileId | string | null | — | クラウド上のファイル識別子です。${apiHost}/api/v1/files/${fileId} に解決され、src より優先されます。 |
loop | loop | boolean | false | ループ属性です。この時間ベースの要素が PlaybackController 配下の自動進行するルートである場合、コントローラーは duration で一時停止せず、時間を 0 に戻します。 |
offset | offset | number | — | 並列(fixed/contain/fit)の親タイムグループ内での開始オフセット(秒)です。 |
src | src | string | — | 元画像ファイルの URL です。 |
CSS パーツ
canvas— レンダリング用キャンバスです。このキャンバスはライト DOM の子要素であり、シャドウ DOM 要素ではありません。
発火するイベント
child-duration-changed({ duration: number }) — 入れ子になったメディア要素の再生時間が判明したとき、または変更されたときに、最も近いコンテキスト提供祖先要素で発火します。contentchange({ reason: string }) — レンダリングに影響する形で画像ソースが変更されたときに発火します。たとえば、src、file-id、asset-idの新しい値によってこのイベントが発火します。
ef-motionblur
<ef-motionblur> は、子要素にモーションブラーを適用します。
属性
| 属性 | React プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|---|
amount | amount | number | 0 | ピクセル単位の明示的なブラー量です。 |
angle | angle | number | 0 | 度単位の明示的なブラーの方向です。 |
fps | fps | number | 30 | shutterAngle をシャッター時間に変換するために使用するフレームレートです。 |
sensitivity | sensitivity | number | 1 | ブラー量を計算する前に、検出された動きに適用する倍率です。 |
shutter-angle | shutterAngle | number | 180 | 度単位のシミュレートされたカメラのシャッター角度です。自動サンプリング時のブラーの強さを制御します(デフォルトは 180)。 |
threshold | threshold | number | 0.5 | ブラーが適用される前の最小動きの大きさ(px/度)です。 |
ef-pan-zoom
<ef-pan-zoom> は、パンとズームに対応したビューポートです。
属性
| 属性 | React プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|---|
auto-fit | autoFit | boolean | false | 明示的な x/y/scale を使用する代わりに、コンテンツをビューポートに自動的に合わせます。 |
scale | scale | number | 1 | 現在のズーム倍率です。 |
x | x | number | 0 | 現在の水平方向のパンオフセット(ピクセル単位)です。 |
y | y | number | 0 | 現在の垂直方向のパンオフセット(ピクセル単位)です。 |
CSS パーツ
content— 変換対象のラッパーです。スロットに割り当てられたコンテンツにパンとズームを適用します。
発火するイベント
transform-changed({ x: number; y: number; scale: number; })— パンまたはズームのたびに、{ x, y, scale }とともに発火します。
メソッド
screenToCanvas(screenX: number, screenY: number): { x: number; y: number }— 画面座標(例:event.clientXとevent.clientY)をキャンバス座標に変換します。canvasToScreen(canvasX: number, canvasY: number): { x: number; y: number }— キャンバス座標を画面座標に変換します。reset(): void— パンとズームを単位変換(x: 0, y: 0, scale: 1)にリセットします。fitToContent(padding?: number): void— コンテンツがビューポートに収まるように、中央に配置して拡大縮小します。paddingパラメーターは余白を指定するもので、0 から 1 までの数値です。
ef-surface
<ef-surface> は、別の要素のピクセルを内部キャンバスにミラーリングします。
属性
| 属性 | React プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|---|
duration | duration | string | — | この要素がアクティブな時間(CSS 時間、例:"5s")です。 |
loop | loop | boolean | false | ループ属性です。PlaybackController の下で、この temporal が自走するルートである場合、コントローラーは duration で一時停止せずに 0 に戻ります。 |
offset | offset | number | — | 並列(fixed/contain/fit)親タイムグループ内での開始オフセット(秒単位)です。 |
target | target | string | "" | ミラーリングする要素(ビットマップソースまたは任意の HTMLElement)の ID です。 |
CSS パーツ
canvas— レンダリング用キャンバスです。このキャンバスはライト DOM の子要素であり、シャドウ DOM 要素ではありません。
発火するイベント
child-duration-changed({ duration: number })— ネストされたメディア要素の duration が判明したとき、または変化したときに、最も近いコンテキスト提供祖先で発火します。
ef-text
<ef-text>は、行、単語、または文字ごとに分割されるアニメーションテキストです。
属性
| 属性 | React プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|---|
blur-amount | blur-amount | number | — | motion-blurが設定されている場合、ラップする<ef-motionblur>のamountに渡されます。 |
blur-angle | blur-angle | number | — | motion-blurが設定されている場合、ラップする<ef-motionblur>のangleに渡されます。 |
blur-fps | blur-fps | number | — | motion-blurが設定されている場合、ラップする<ef-motionblur>のfpsに渡されます。 |
blur-sensitivity | blur-sensitivity | number | — | motion-blurが設定されている場合、ラップする<ef-motionblur>のsensitivityに渡されます。 |
blur-shutter-angle | blur-shutter-angle | number | — | motion-blurが設定されている場合、ラップする<ef-motionblur>のshutter-angleに渡されます。 |
blur-threshold | blur-threshold | number | — | motion-blurが設定されている場合、ラップする<ef-motionblur>のthresholdに渡されます。 |
duration | duration | string | — | この要素がアクティブである時間です(CSS時間、例:"5s")。 |
easing | easing | string | "linear" | スタガーのタイミングに適用されるCSSイージングキーワードです。 |
loop | loop | boolean | false | ループ属性です。PlaybackControllerの下にあるこの時間要素が自律駆動するルートの場合、コントローラーはdurationで一時停止せず、0に戻ります。 |
motion-blur | motionBlur | boolean | false | 各セグメントを<ef-motionblur>要素でラップし、方向を自動検出してぼかしを適用します。 |
offset | offset | number | — | 並列(fixed/contain/fit)の親タイムグループ内での開始オフセット(秒)です。 |
split | split | "line" \ | "word" \ | "char" |
stagger | stagger | string | "" | 分割された各セグメントのアニメーション開始間の遅延です(CSS時間、例:"100ms")。 |
イベント
child-duration-changed({ duration: number })— ネストされたメディア要素の長さが判明または変更されたとき、最も近いコンテキスト提供元の祖先要素で発火します。
ef-text-segment
<ef-text-segment>は、EFTextElementにおけるスタガーアニメーションの1単位です。
ef-timegroup
<ef-timegroup>は時間コンテナーです。
属性
| 属性 | React プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|---|
duration | duration | string | — | mode="fixed"の場合の固定時間(CSS の時間値、例:"5s")。それ以外のモードでは無視されます。 |
fps | fps | number | — | レンダリングのフレームレートです。 |
loop | loop | boolean | false | ループ属性です。この時間要素がPlaybackController配下の自動駆動ルートである場合、コントローラーはdurationで一時停止せず、時間を0に戻します。 |
mode | mode | "fixed" \ | "sequence" \ | "contain" \ |
offset | offset | number | — | 並列の(fixed/contain/fit)親タイムグループ内での開始オフセット(秒)です。 |
overlap | overlap | number | 0 | sequenceモードの隣接する項目間の重なり時間です(例:"1s")。 |
発火するイベント
child-duration-changed({ duration: number })— 入れ子のメディア要素の時間が判明したとき、または変更されたときに、最も近いコンテキスト提供祖先で発火します。playback-attached({ controller: PlaybackController })— TODO: このイベントの説明を追加します。
メソッド
addFrameTask(callback: FrameTaskCallback): () => void— フレームごとのコールバック関数を登録します。このメソッドは登録解除関数を返します。waitForContentReady(): Promise<void>— このタイムグループと、現在のプレゼンテーションに関係する時間要素の子要素が準備できるまで待機します。シーケンスモードでは、アクティブなシーンのみを待機します。アイドル状態の兄弟要素すべてを待機していたことで、後続クリップの#load()メソッドが共有レジストリ入力と競合し、Showcaseのエクスポートがいつまでも完了しない問題が発生したことがあります。seekForRender(time: number, options?: SeekForRenderOptions): Promise<void>—strictVideoPaintがtrueの場合、このメソッドは、アクティブなすべてのef-video子孫要素が、このシークの再生ヘッドをカバーするサンプルを描画したことも検証します。以前のサンプルがキャンバスに残っている(hasPaintedFrameはスティッキーです)だけでは不十分です。キャンバスに古い映像が残ったままだと、カットでN-1がエンコードされます。このメソッドは、例外をスローする前に短時間再試行します。このチェックにはマイクロタスクのターンが少し余分に必要になるため、インタラクティブなプレビューではなく、最終レンダリングのキャプチャに使用してください。このメソッドが基盤とする決定論的な同期とコンテンツ準備の契約については、ベースのTemporalElement.seekForRenderメソッドを参照してください。options.strictVideoPaint(任意):boolean—trueの場合、アクティブなすべての<ef-video>子孫要素がこのフレームのサンプルを描画したことも検証します。メタデータ状態が解決済みであるだけでは不十分です。詳細なチェックについては、EFTimegroupElement.seekForRenderを参照してください。コンテナーのみが子孫要素をたどれるため、このオプションはベース実装では効果がありません。options.paintPhaseTiming(任意):boolean— 厳密な描画フェーズの診断情報を出力します。検証は引き続き独立して有効です。options.preferProxy(任意):boolean—trueの場合、ラダーに用意されていれば、軽量なスクラブ用または低解像度のプロキシを優先します。タイムラインのフィルムストリップやコンポジションのサムネイルでは、このオプションを設定してください。これにより、重いシーンが小さなプレビューを描画するためだけに、すべてのクリップの再生用(role=high)入力を開くのを防げます。最終エクスポートまたはEF_FRAMEGENでは、このオプションを設定しないでください。そうすれば、syncは引き続き再生用ティアを待機します。options.signal(任意):AbortSignal— SampleChaseのポンプ処理やイテレーターのnext呼び出しなど、進行中の準備または表示ステップを中止するために使用します。新しいbeginFrame呼び出しが停止中の呼び出しに置き換わるとき、EF_FRAMEGENはこのオプションを使用します。
ef-video
<ef-video>は動画の時間的リーフです。
属性
| 属性 | React のプロパティ | 型 | デフォルト値 | 説明 |
|---|---|---|---|---|
duration | duration | string | — | この要素がアクティブになる時間です(CSS 時間、例:"5s")。 |
fft-decay | fftDecay | number | 8 | getFrequencyDataで平均化する減衰フレーム数です(デフォルトは8)。 |
fft-gain | fftGain | number | 3 | 周波数解析の前に適用する線形ゲインです(デフォルトは3.0)。 |
fft-size | fftSize | number | 128 | getFrequencyData/getTimeDomainData用のFFTウィンドウサイズです(2の累乗に丸められます。デフォルトは128)。 |
file-id | fileId | string | null | — | クラウドファイル識別子です。${apiHost}/api/v1/files/${fileId}に解決され、src/variantsより優先されます。 |
interpolate-frequencies | interpolateFrequencies | boolean | false | 最近傍サンプリングではなく、FFTバンド間を補間してgetFrequencyDataのビンを平滑化します。 |
loop | loop | boolean | false | ループ属性です。この時間要素がPlaybackControllerの下で自走するルートである場合、コントローラーはdurationで一時停止せず、0に戻ります。 |
mute | muted | boolean | false | 動画のオーディオトラックをミュートします。 |
offset | offset | number | — | 並列(fixed/contain/fit)の親タイムグループ内での開始オフセット(秒)です。 |
play-role | playRole | "low" \ | "high" | "high" |
sourcein | sourcein | string | — | ソースファイル内の開始時刻です(CSS 時間、例:"1.5s")。 |
sourceout | sourceout | string | — | ソースファイル内の終了時刻です(CSS 時間、例:"1.5s")。 |
src | src | string | — | ソース動画ファイルのURLです。 |
trimend | trimend | string | — | ソースの末尾から切り取る長さです(CSS 時間)。 |
trimstart | trimstart | string | — | ソースの先頭から切り取る長さです(CSS 時間)。 |
variant-mode | variantMode | "single-high" \ | "scrub-upgrade" \ | "multi-bitrate" \ |
variants | variants | string | "" | バリアントラダーマニフェスト(複数の解像度/ビットレート)のURLです。srcの代わりに使用されます。 |
volume | volume | number | 1 | オーディオ音量(0.0~1.0)です。 |
CSS パーツ
canvas— フレーム描画用キャンバスです。このキャンバスはライト DOM の子要素であり、シャドウ DOM の要素ではありません。
発火するイベント
child-duration-changed({ duration: number })— ネストされたメディア要素の長さが判明したとき、または変化したときに、最も近いコンテキスト提供祖先で発火します。variantchange({ role: "scrub" \| "low" \| "high"; url: string; window: number \| null })— アクティブなデコードバリアントが変化したときに発火します。たとえば、役割、URL、スクラブウィンドウの変化時です。
ef-waveform
<ef-waveform>は、ef-audioまたはef-videoのターゲットにバインドされる、音声にリアルタイムで反応する波形ビジュアライゼーションです。
属性
| 属性 | React プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|---|
bar-spacing | barSpacing | number | 0.5 | バーを使うビジュアルモードにおける、バー間の間隔の比率(0~1)です。 |
color | color | string | "currentColor" | "currentColor"(デフォルト)の場合、ホストの計算済み CSS color が適用されます。 |
duration | duration | string | — | この要素がアクティブになる時間です(CSS の時間指定。例:"5s")。 |
line-width | lineWidth | number | 4 | 線/曲線のビジュアルモードにおける線幅(px)です。 |
loop | loop | boolean | false | ループ属性です。この時間要素がPlaybackControllerの下で自動再生するルートの場合、コントローラーはdurationで一時停止せず、0に戻ります。 |
mode | mode | "line" \ | "bars" \ | "roundBars" \ |
offset | offset | number | — | 並列(fixed/contain/fit)の親タイムグループ内での開始オフセット(秒)です。 |
target | target | string | "" | ビジュアライズする<ef-audio>/<ef-video>要素の ID です。 |
CSS パーツ
canvas— 描画用キャンバスです。このキャンバスはライト DOM の子要素であり、シャドウ DOM 要素ではありません。
発火するイベント
child-duration-changed({ duration: number })— ネストされたメディア要素の再生時間が判明したとき、または変更されたときに、最も近いコンテキスト提供祖先で発火します。