mcpField
E
editframe-api

editframe-api

github.com/editframeクリエイティブ・メディア19134 回インストール2 週間前に更新
リポジトリ

editframe-api について

Editframeのクラウド動画APIやローカルプロジェクトを扱う開発者向けのJavaScript/TypeScriptクライアントとCLIです。レンダリング、メディア処理、インストール済みランタイム経由のローカル書き出しに対応します。

主な機能

  1. 01レンダリングの作成と進捗確認
  2. 02動画・画像・字幕ファイルのアップロード
  3. 03パイプラインによる音声文字起こし
  4. 04メディアアクセス用URLの署名
  5. 05エディターを開いてローカル書き出しを送信

活用シーン

  1. 01Editframeのコンポジションから動画をレンダリング
  2. 02メディア素材のアップロードと処理
  3. 03パイプラインで音声アノテーションを生成
  4. 04ローカルプロジェクトの書き出しを送信・確認

MCP 対応

CLIの`mcp`コマンドは、MCP stdio経由でエージェントをローカルbridgeに接続します。Editframeのエージェントパッケージにはホスト設定が含まれます。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/editframe/skills --skill editframe-api

インストール後、Claude Code で/editframe-apiを入力して読み込まれたか確認します。

詳細

Editframe API と CLI

@editframe/api は、Editframe のクラウド動画 API 用 JavaScript/TypeScript クライアントです。Editframe のコンポジションから動画をレンダリングしたり、メディアファイルをアップロードして処理したり、音声を書き起こすパイプラインを実行したり、CDN リソースへの認証済みブラウザーアクセスを管理したりできます。

editframe CLI は、インストール済みの Editframe ランタイム用の薄いクライアントです。ブラウザーエディターを開き、ローカルプロジェクトのエクスポートをリクエストします。CLI を参照してください。

クイックスタート

import { Client, createRender, getRenderProgress, downloadRender } from "@editframe/api";

const client = new Client(process.env.EDITFRAME_API_KEY);

const render = await createRender(client, {
  html: `<ef-timegroup mode="contain" class="w-[1920px] h-[1080px]">
    <ef-video src="https://assets.editframe.com/bars-n-tone.mp4"></ef-video>
  </ef-timegroup>`,
  width: 1920,
  height: 1080,
  fps: 30,
});

for await (const event of await getRenderProgress(client, render.id)) {
  if (event.type === "progress") console.log(`Progress: ${(event.data.progress * 100).toFixed(0)}%`);
}

const response = await downloadRender(client, render.id);
const buffer = await response.arrayBuffer();

クライアントと認証

import { Client } from "@editframe/api";

const client = new Client(process.env.EDITFRAME_API_KEY);      // server-side: Bearer token
const client = new Client();                                    // browser: session cookie (credentials: "include")
const client = new Client(apiKey, "https://staging.editframe.com"); // optional second arg overrides the host (default https://editframe.com)

API キーの形式は ef_<secret>_<keyid> です。クライアントはこの形式をローカルで検証します。Editframe ダッシュボードの「API → API Keys」からキーを取得してください。エラーの動作は SDK 関数によって異なります。拒否されたリクエストと、ドキュメントに記載されている結果の状態を処理してください。

API キーをクライアントサイドのコードで絶対に公開しないでください。 認証が必要なメディアをブラウザーで再生する場合は、代わりにURL 署名を使用してください。キーはサーバーに保持します。ブラウザーには、有効期間が短く、スコープが限定されたトークンのみを渡します。

@editframe/api では、createImageFile、createCaptionFile、createISOBMFFFile など、型ごとの古いリソースも引き続きエクスポートされます。これらは統一された createFile/type: "video"|"image"|"caption" API の使用が推奨されており、@deprecated です。新しいコードでは使用しないでください。廃止された書き起こし関数については、書き起こしを参照してください。

統一ファイル API

動画、画像、キャプションのすべてのファイル形式で、同じエンドポイント一式を使用します。type フィールドによって、エンドポイントの動作が決まります。

種類形式最大サイズ処理
videoMP4、MOV、WebM、MKV1GBISOBMFF に自動変換(フレーム単位の正確なシークとアダプティブストリーミングに対応)
imageJPEG、PNG、WebP、SVG16MBすぐに利用可能
captionVTT、SRT2MBすぐに利用可能

ステータスのライフサイクル:created → uploading → processing → ready(画像/キャプションでは processing をスキップ)、または → failed です。

import { Client, createFile, uploadFile, getFileProcessingProgress } from "@editframe/api";
import { createReadStream } from "node:fs";
import { stat } from "node:fs/promises";
import { Readable } from "node:stream";

const client = new Client(process.env.EDITFRAME_API_KEY);
const fileStats = await stat("video.mp4");

const file = await createFile(client, { filename: "video.mp4", type: "video", byte_size: fileStats.size });

for await (const event of uploadFile(client, { id: file.id, byte_size: fileStats.size, type: "video" }, Readable.toWeb(createReadStream("video.mp4")))) {
  if (event.type === "progress") console.log(`Upload: ${(event.progress * 100).toFixed(1)}%`);
}

for await (const event of await getFileProcessingProgress(client, file.id)) {
  if (event.type === "complete") break;
}

uploadFile は Web の ReadableStream を受け取ります。上記のように、Node のストリームは Readable.toWeb で変換してください。ブラウザーファイルでは、file.stream() から互換性のあるストリームを取得できます。

Node ヘルパーはファイルレコードを作成し、遅延アップロードイテレーターを返します。ファイルのバイト列をアップロードするには、このイテレーターを消費します。

import { Client, upload, getFileProcessingProgress } from "@editframe/api/node";

const client = new Client(process.env.EDITFRAME_API_KEY);
const { file, uploadIterator } = await upload(client, "video.mp4");
for await (const event of uploadIterator) {
  console.log(`Upload: ${(event.progress * 100).toFixed(1)}%`);
}
for await (const event of await getFileProcessingProgress(client, file.id)) {
  if (event.type === "complete") break;
}

アップロードの完了とメディア処理の完了は、それぞれ別の状態です。

アップロードする前に、既存のファイルを確認してください。lookupFileByMd5(client, md5) を呼び出します。一致するファイルがない場合は null が返されます。

file-id を使って、コンポジション内でファイルを使用します。

<ef-configuration api-host="https://editframe.com">
  <ef-video file-id="uuid-of-processed-video"></ef-video>
  <ef-image file-id="uuid-of-uploaded-image" class="w-24 h-24"></ef-image>
</ef-configuration>

createFile は、安定した UUID を file-id として割り当てます。アップロード、処理、再生を通じて同じ値が維持されます。

保持期間(expires_at)

createFile と createRender は、どちらも省略可能な expires_at を受け取ります。これは ISO 8601 形式の日付で、指定できるのは未来 30 日以内までです。永続的に保持する場合は省略してください。無効な入力には、invalid_datetime、must_be_future、exceeds_max_retention のいずれかとともに 400 が返されます。getFileDetail と getRenderInfo は expires_at を返します。null は永続的な保持を意味します。リモート URL からのレンダー取り込み(以下を参照)では、固定された設定変更不可の 1 時間 TTL が使用されます。これはこのフィールドとは無関係です。

レンダリング

const render = await createRender(client, {
  html: `<ef-timegroup mode="contain" class="w-[1920px] h-[1080px]"><ef-video src="..."></ef-video></ef-timegroup>`,
  width: 1920,
  height: 1080,
  fps: 30,          // default 30
  output: { container: "mp4", video: { codec: "h264" }, audio: { codec: "aac" } }, // default shown
});

出力コンテナ:mp4(video.codec: "h264"、audio.codec: "aac")、jpeg(quality 1~100、デフォルトは80)、png(compression 1~100、デフォルトは80、transparency はブール値)、webp(quality 1~100、デフォルトは80、compression 0~6、デフォルトは4、transparency はブール値)。

createRender では、以下の高度なオプションも指定できます。

  • サーバー設定によって実行バックエンドが選択されます。SDK の backend フィールドで現在のサーバーフラグを上書きすることはできません。
  • work_slice_ms:レンダリングをこの長さ(ミリ秒)のフラグメントに分割します。デフォルトは "cpu" では4000、"gpu" では15000です。最大値は60000です。
  • strategy:今後のレンダリング戦略用に予約されています。現在は "v1" のみで、これがデフォルトです。
  • duration_ms:検出されたレンダリング時間をミリ秒単位で上書きします。
  • metadata:任意の Record<string, string> です。getRenderInfo とレンダリング Webhook は、この値をそのまま返します。

コンポジションの ef-video、ef-audio、ef-image 要素では、https:// の src 値を直接使用できます。Editframe はレンダリング前にこれらをダウンロードして取り込み、有効期限は約1時間の一時的な expires_at になります。これは createFile で登録するファイルとは異なります。

以前のレンダリングを再利用する場合は、明示的に lookupRenderByMd5 を呼び出してください。createRender はこの検索を実行しません。

出力設定や安定したアセットのバージョンを含む、レンダリング入力全体からハッシュを生成してください。HTML だけをハッシュすると、これらの違いが反映されません。

再利用する前に、レンダリングの完了状態、出力設定、保持期間を確認してください。ハッシュが一致しても、結果を利用できるとは限りません。

getRenderProgress は { type: "progress", data: { progress } } を返します。progress は0から1までの値で、その後 { type: "complete" } を返します。レンダリングに失敗するとエラーをスローします。deleteRender は行と GCS の出力および中間ファイルをすぐに削除します。レンダリングが queued、rendering、recovering のいずれかの状態で実行中の場合は失敗します。

自分でレンダリングした動画を登録するには、html を省略してファイルを直接アップロードします。

import { createReadStream } from "node:fs";
import { Readable } from "node:stream";

const render = await createRender(client, { width: 1920, height: 1080, fps: 30 });
await uploadRender(client, render.id, Readable.toWeb(createReadStream("my-video.mp4")));

文字起こし

ファイルを文字起こしするには、transcribe ステップを含むパイプライン実行を開始します。パイプラインを参照してください。このステップは speech.segment と speech.word のアノテーションを書き込みます。getPipelineRunOutputs(client, runId, namespace) で読み取れます。

従来の文字起こし機能は廃止されています。transcribeFile、transcribeISOBMFFFile、createTranscription は @deprecated です。これらのエンドポイントは、エラー transcription_retired とともに 410 Gone を返します。使用しないでください。

getFileTranscription は、従来の文字起こしの状態(id、status、completed_at、failed_at、work_slice_ms)を引き続き報告します。文字起こしのセグメントは返しません。従来の文字起こしがないファイルの場合は null を返します。

ef-captions には、captions-src、captions-script、または captions.captionsData からキャプションデータを渡す必要があります。target は、参照先の ef-video/ef-audio 要素のローカル時間にキャプションのタイミングを同期するだけです。文字起こしデータは取得しません。composition スキルの ef-captions リファレンスを参照してください。

URL 署名

ブラウザーが Editframe ホストのメディアを直接再生する場合は、<ef-video src="https://editframe.com/api/v1/transcode/..."> のように、URL 署名を使用してください。createRender/downloadRender を通じて、すべてのレンダリングと再生がサーバー側で行われる場合は不要です。

サーバーで API キーを保持し、createURLToken を呼び出すエンドポイントを公開します。

祖先の ef-configuration に HTML 属性 signing-url を設定してください。JavaScript プロパティ名は signingURL です。

トークンを発行する前に、呼び出し元を認証し、要求されたメディアへのアクセス権を確認してください。

ブラウザーは { url } をそのエンドポイントに送信し、返されたトークンをメディアリクエストに付加します。

トークンの有効期間は約 1 時間です。ブラウザーは URL ごとに各トークンをキャッシュします。トランスコードまたは HLS エンドポイントでは、マニフェストとすべてのセグメントを 1 つのトークンで扱えます。

// Inside your authenticated application router, authorize access to the requested media URL.
import { Client, createURLToken } from "@editframe/api";
const client = new Client(process.env.EDITFRAME_API_KEY);
app.post("/sign-url", async (req, res) => res.json({ token: await createURLToken(client, req.body.url) }));

<ef-configuration api-host="https://editframe.com" signing-url="/sign-url">
  <ef-video src="https://editframe.com/api/v1/transcode/manifest.m3u8?url=..."></ef-video>
</ef-configuration>

API キーの代わりに editframe.com のセッション Cookie を使う場合は、Authorization ヘッダーを付けず、credentials: "include" を指定して POST /ef-sign-url を使用してください。これは同等の匿名トークンフローです。多くのアプリでは、上記の API キーを使うサーバールートを使用します。

CLI

editframe CLI は、インストール済みの Editframe ランタイム用の薄いクライアントです。ブリッジ、エディター、レンダリング依存関係はバンドルされません。まず https://editframe.com/agent からランタイムをインストールしてください。

npm install -D @editframe/cli   # already included in the html/react scaffolds

各ローカルコマンドには --project とブリッジが必要です。--bridge、--component、EDITFRAME_BRIDGE_PATH、または EDITFRAME_COMPONENT_ROOT でブリッジを選択してください。各コマンドは JSON を出力します。

export EDITFRAME_BRIDGE_PATH=/absolute/editframe-bridge
npx editframe start --project .
npx editframe open --project .           # prints an editor URL; keep it private
npx editframe compositions --project .
npx editframe context --project . --composition COMPOSITION_ID

context は、現在のリビジョン ID と、サポートされているエクスポート設定を返します。エクスポートするには、新しい operation_id、その revision_id、およびサポートされている設定を含むリクエストファイルを作成します。

{
  "operation_id": "export-demo-001",
  "revision_id": "REPLACE_WITH_CURRENT_REVISION_ID",
  "execution_target": "local",
  "settings": { "container": "mp4", "video_codec": "h264", "audio_codec": "aac", "width": 1280, "height": 720, "fps": 30 }
}
npx editframe export --project . --composition COMPOSITION_ID --input export.json
npx editframe job --project . --job JOB_ID
  • ローカルエクスポート中は、ブラウザーエディターを開いたままにしてください。エディターがレンダラーです。
  • CLI はジョブを送信して確認します。動画ファイルは書き出しません。ファイルはエディターから取得してください。
  • operation_id は、同じ内容の再試行に限り再利用してください。新しいリビジョンまたは新しい設定には、新しい operation_id が必要です。
  • command は、リビジョン管理されたコンポジション編集を 1 件適用します。--input ファイルには、operation_id、base_revision_id、kind、label が必要です。リビジョンの競合が発生したら、もう一度 context を読み込み、新しい operation_id を使用してください。
  • mcp は、MCP stdio を介してエージェントをローカルブリッジに接続します。ネイティブエージェントのパッケージには、https://editframe.com/agent のホスト設定が含まれています。

有効化されたホスト型ランタイムでは、--project とブリッジを --endpoint および --project-id に置き換えてください。環境変数に EDITFRAME_TOKEN を設定します。以前の CLI の EF_TOKEN 変数は、ランタイムへのログインには使用できません。

このファイル末尾の生成済みテーブルには、@editframe/cli パーサーの各オプションとコマンドが記載されています。

以前のコマンド

次のコマンド名は、現在 CLI_MIGRATION_REQUIRED エラーになります。

以前のコマンド現在の方法
preview、dev、dev-serverstart と open、または Vite および Next.js アダプターを使用してください。dev-server スキルを参照してください。
renderexport を使用するか、ブラウザーエディターからエクスポートしてください
auth、cloud-render、sync@editframe/api の createRender と統合ファイル API を使用してください
webhookAPI キーの Webhook URL を変更してください。webhooks スキルを参照してください。
check、process、process-file、transcribeCLI での代替手段はありません。ブラウザーエディターを使用してください。アプリのビルドでは @editframe/build-adapter を使用します。

パイプライン

Editframe は、各組織でパイプラインを有効にします。パイプラインを利用するには、https://editframe.com/factory#contact で Editframe にフッテージについてお知らせください。パイプラインのない組織では、すべてのパイプラインルートが 404 を返します。

パイプライン関数は @editframe/api/pipelines からインポートしてください。このエントリーポイントは実験的なもので、メジャーバージョンの変更を伴わずに変更される場合があります。このファイル末尾の関数インデックスには記載されていません。

パイプラインは、不変のバージョンを持つ、名前付きのステップグラフです。1 回の実行では、1 つのバージョンを通じて 1 つの video ファイルを処理します。ステップは、needs に指定されたステップが完了した後に開始されます。各ステップは、ファイル上の名前空間に出力を書き込みます。

import { Client, createPipeline, createPipelineRun, getPipelineRun, isPipelineRunTerminal } from "@editframe/api/pipelines";

const client = new Client(process.env.EDITFRAME_API_KEY);
const pipeline = await createPipeline(client, {
  name: "speech-check",
  definition: {
    steps: {
      probe: { type: "probe" },
      transcript: { type: "transcribe", needs: ["probe"] },
      has_speech: { type: "filter", needs: ["transcript"], when: { path: "transcript.metadata.word_count", op: "gt", value: 0 } },
      publish: { type: "publish", needs: ["has_speech"] },
    },
  },
});
const { run } = await createPipelineRun(client, { pipeline_id: pipeline.id, file_id: fileId }, { idempotencyKey: `speech-check:${fileId}` });
let current = await getPipelineRun(client, run.id);
while (!isPipelineRunTerminal(current)) {
  await new Promise((resolve) => setTimeout(resolve, 5000));
  current = await getPipelineRun(client, run.id);
}
定義

定義は、1~64 個のステップを持つ { steps: { <key>: step } } です。ステップキーと名前空間は ^[a-z][a-z0-9_]{0,62}$ に一致します。不明なフィールドがある場合、422 エラーになります。

ステップのフィールドルール
type必須です。以下のいずれかのタイプを指定します。
needs先に完了する必要があるステップのキーです。最大 16 個です。デフォルトは [] です。循環は許可されません。
namespace一意である必要があります。デフォルトはステップキーです。
granularity{ mode: "file" }(デフォルト)、または { mode: "segment", window_ms: 1000–3600000, overlap_ms: 0 to window_ms/2 }
withタイプのオプションです。
whenfilter では必須です。他のタイプでは指定できません。
タイプwith(デフォルト)出力
probe指定できませんメタデータ duration_ms、width、height、has_video、has_audio、source、tracks
transcribe指定できませんspeech.segment および speech.word アノテーション。メタデータ word_count、segment_count、truncated など。
sample_framesevery_ms 100–600000(1000)最初のビデオトラックの JPEG フレーム
detect_scenesthreshold 0.01–1(0.3)scene.cut アノテーション。メタデータ cut_count。
endpointendpoint_id(必須)、max_concurrency 1–1024(8)サービスの出力
filter指定できません出力なし。ステップは成功するか、スキップされます。
reviewinstructions 1~2000 文字、expires_after_ms 60000~2592000000(604800000)、on_expiry fail/approve/reject(fail)判定と修正済みアノテーション
redact_renderkinds:1~32 個のアノテーション種別(必須)、captions ブール値(false)、title:{ text: 1~120 文字, duration_ms: 1000~15000(4000) }メタデータ render_id、status、output_url、output_file_id、および各種件数
publishformats:hls および/または dash(["hls"])メタデータ file_id、source_url、hls_url、dash_url

次のルールに従ってください。

  • segment の粒度は、transcribe、sample_frames、detect_scenes、endpoint にのみ使用してください。
  • アップロードの完了前にセグメントステップを開始するには、そのステップの needs をすべてセグメントステップにしてください。ファイルステップはファイル全体の準備が完了するまで待機します。
  • ウィンドウはフラグメントの境界から開始します。ウィンドウは window_ms より長くなる場合があります。セグメントアノテーションは、そのウィンドウ内に収める必要があります。
  • publish は入力ファイルの再生 URL を返します。publish が redact_render ステップに依存する場合は、ぼかし処理済みファイルを再生します。ぼかし処理が skipped の場合は、入力ファイルを再生します。file_id は再生するファイルを示します。publish ステップが直接または間接的に依存できる redact_render ステップは 1 つだけです。複数ある場合、needs で not_allowed エラーになります。
  • redact_render は、keyframes を含むアノテーションをぼかし、含まないアノテーションをミュートします。レンダリング分数を消費する通常のレンダリングを作成します。その後、そのレンダリングを新しいファイル(output_file_id)として組織に追加します。このステップは、そのファイルの準備が完了すると成功します。レンダリングまたはファイルに失敗しても、自動的には再試行されません。実行を再試行すると、再度レンダリングされます。
  • captions: true の場合、redact_render は transcribe ステップの文字起こしから字幕を焼き込みます。このステップは、直接または間接的に、1 つの transcribe ステップにのみ依存する必要があります。transcribe ステップがない場合、with.captions で not_upstream エラーになります。複数ある場合は not_allowed エラーになります。ミュートされた単語は字幕に表示されません。代わりに ▇▇▇ が表示されます。
  • title が指定されている場合、redact_render は動画の上部に title.text を表示します。タイトルは duration_ms の時点でフェードアウトします。Editframe はテキストの先頭と末尾の空白を削除します。
  • 字幕またはタイトルを含む redact_render ステップは、ぼかす対象が何もない場合も常にレンダリングします。そのメタデータには caption_count と title_applied も含まれます。
  • Editframe は定義を正規化し、sha256: ダイジェストを記録します。同等の定義は同じダイジェストになります。
フィルター

フィルターは when を評価します。述語が true の場合、フィルターは成功します。述語が false の場合、フィルターとそれ以降のすべてのステップがスキップされます。

  • 葉は { path, op, value } です。path は <namespace>.metadata.<field>... または <namespace>.annotations... です。数値のセグメントは配列項目を選択します。
  • op は exists、non_empty、eq、ne、gt、gte、lt、lte、in(スカラー値を1~64個指定)または contains です。
  • 葉は { all: [...] }、{ any: [...] }(子要素は1~16個)および { not: predicate } で組み合わせます。最大深度は4です。
  • path に値がない場合、すべての葉は false になります。これには ne も含まれます。
  • フィルターが読み取れるのは、直接的または間接的に必要とするステップの名前空間のみです。それ以外のパスは not_upstream になります。
  • セグメントステップの場合、フィルターはすべてのウィンドウの注釈を読み取ります。各メタデータフィールドについては、そのフィールドを設定した最後のウィンドウの値を読み取ります。

最終ステップとは、ほかのステップから必要とされていないステップです。最終ステップが1つ以上成功すると、実行は succeeded で終了します。フィルターまたはレビューによって、すべてのブランチが最終ステップに到達する前に停止した場合、実行は filtered で終了します。相互に補完する2つのフィルターがある場合、選択されたブランチが完了すると、実行は succeeded で終了します。Editframe は、両方のブランチを必要とするステップを常にスキップします。

レビュー

レビューのステップではレビュータスクが開かれ、waiting_review の状態で待機します。

  • approvePipelineReview(client, id, { metadata_patch }) はステップを成功させます。パッチは { annotations, reviewed_kinds? } です。パッチ内の各 kind は、後続のステップでその kind の以前の注釈を置き換えます。注釈なしで reviewed_kinds に含まれる kind は、後続のステップでその kind が削除されます。
  • rejectPipelineReview(client, id, { reason }) はステップとそれ以降のステップをスキップします。reason の文字数は最大2000文字です。
  • 有効期限が切れたとき、on_expiry: "approve" はステップを成功させ、"reject" はスキップし、"fail" は実行を失敗させます。実行を再試行すると、新しいレビュータスクが開きます。
  • 2回目の判断が最初の判断と異なる場合は 409 review_conflict を返します。期限後の判断は 409 review_expired または 409 review_not_pending を返します。同じ判断を再度行った場合は、記録済みの判断を返します。
  • getPipelineReview は、実行の steps の順序で input_namespaces を返します。それぞれを getPipelineRunOutputs(client, review.run_id, namespace) で読み取ります。
エンドポイントの手順

createPipelineEndpoint(client, { url, headers, timeout_ms, callback_timeout_ms, max_concurrency }) でサービスを登録します。

  • url には HTTPS を使用し、パブリックアドレスに解決される必要があります。headers は最大 16 個設定できます。
  • デフォルト値:timeout_ms は 30000(1000~600000)、callback_timeout_ms は 3600000(1000~2592000000)、max_concurrency は 8(1~1024、すべての実行を対象)。
  • レスポンスには signing_secret(whsec_...)が一度だけ含まれます。すぐに保存してください。
  • 制限を変更するには、updatePipelineEndpoint(client, id, { timeout_ms, callback_timeout_ms, max_concurrency }) を使用します。変更する制限のみを送信してください。範囲は同じです。変更後に送信されたリクエストには新しい制限が適用されます。
  • ボディが空の場合、または値が範囲外の場合は 422 invalid_request が返されます。アーカイブ済みのエンドポイントの場合は 409 endpoint_archived が返されます。
  • URL、ヘッダー、署名シークレットは変更できません。変更するには、新しいエンドポイントと新しいパイプラインバージョンを作成してから、古いエンドポイントをアーカイブします。
  • バージョンでアーカイブ済みのエンドポイントを指定している実行は、endpoint_not_found で失敗します。

Editframe は Standard Webhooks ヘッダーを含む署名付きの POST を送信します。ボディには file、window(ファイルステップの場合は null)、media の URL、metadata(名前空間ごとに必要なステップの出力)、idempotency_key、callback が含まれます。メディア URL に API キーは不要で、media.expires_at に期限切れになります(最長 4 時間後)。

import { postPipelineCallback, verifyPipelineEndpointRequest } from "@editframe/api/pipelines";

// Pass the raw body bytes. Re-serialized JSON does not verify.
const request = await verifyPipelineEndpointRequest({ secret: process.env.EDITFRAME_ENDPOINT_SECRET!, headers: req.headers, body: rawBody });
// Option 1: answer 200 with { metadata, annotations }.
// Option 2: answer 202, and then post the result:
await postPipelineCallback(request.callback.url, { status: "succeeded", output: { metadata: {}, annotations: [] } });
  • 202 以外の 2xx レスポンスは出力を返します。ボディが空の場合は、空の出力が返されます。
  • 408、429、5xx レスポンス、タイムアウト、または接続エラーが発生すると、再試行が開始されます。最大 1 時間の Retry-After で遅延時間を指定できます。
  • リダイレクトまたはその他の 4xx レスポンスの場合、ステップは再試行されずに失敗します。
  • 202 の後、期限前に { status: "heartbeat" } を投稿すると、期限が callback_timeout_ms だけ延長されます。
  • 失敗を報告するには、{ status: "failed", error: { message, code?, retryable } } を投稿します。
  • 待機していない試行へのコールバックは 409 step_not_waiting を返します。

出力は { metadata?, annotations? } で、最大 1 MiB、注釈は最大 10,000 件です。注釈には kind、start_ms、end_ms が含まれます。また、label、text、confidence(0~1)、track_id、keyframes を含めることもできます。キーフレームは、正規化された 0~1 のフレーム座標で表される { t_ms, x, y, w, h } です。

実行、グループ、出力
  • createPipelineRun(client, { pipeline_id, version?, group_id?, file_id, external_id?, metadata? }, { idempotencyKey }) は { run, created } を返します。ファイルのタイプは video である必要があります。デフォルトのバージョンは最新です。
  • 同一のリクエストに限り、idempotencyKey を再利用できます。異なるボディを送信すると 409 idempotency_conflict が返されます。
  • metadata は文字列のマップです。キーは最大 32 個で、それぞれ 1~256 バイト、値はそれぞれ最大 1024 バイト、コンパクトな JSON で最大 8192 バイトです。実行の作成後に変更することはできません。ステップが書き込むファイルのメタデータとは異なります。
  • listPipelineRuns(client, { status, pipeline_id, file_id, group_id, metadata }) は、実行を新しい順に返します。metadata フィルターを指定すると、すべてのエントリーに一致する実行のみが返されます。
  • パイプライン、バージョン、エンドポイント、実行、グループには created_by と created_via があります。created_by は { type: "api_key" | "user", id } で、リクエストを送信した API キー、またはダッシュボードを使用したか API キーなしでリクエストを送信したユーザーを表します。created_via は "api" または "dashboard" です。Editframe が作成者を記録していない場合、どちらも null です。

グループには、1 つのパイプラインバージョンの実行がまとめられます。グループを使用すると、一連の実行を追跡し、同時に実行する実行数を制限し、すべての実行が完了したときにイベントを 1 つ受け取ることができます。

  • createPipelineGroup(client, { pipeline_id, version?, runs?, close?, max_in_flight?, external_id?, metadata? }, { idempotencyKey }) は { group, created } を返します。runs には、異なるファイルを対象とする 0~1000 件のエントリーを指定します:{ file_id, external_id?, metadata? }。実行はグループのメタデータを継承しません。
  • max_in_flight は 1~100000 で、デフォルトは 100 です。その他の実行は pending のままになり、古いものから順に開始されます。
  • 上限を変更するには、updatePipelineGroup(client, id, { max_in_flight }) または editframe pipelines groups update GROUP_ID --max-in-flight N を使用します。グループのすべてのステータスで変更できます。上限を引き上げると、待機中の実行がすぐに開始されます。引き下げても、実行中の実行は継続します。
  • Editframe は、クローズのたび、および max_in_flight の変更のたびに、それを行った API キーまたはユーザーを記録します。ダッシュボードでこの変更履歴を確認できます。現在の値と同じ値への変更は記録されません。
  • 後から実行を追加するには、group_id を指定して createPipelineRun を呼び出します。実行はグループのバージョンを使用します。グループと pipeline_id または version が異なる場合、404 group_not_found、409 group_closed、409 group_version_mismatch が返されます。
  • グループのステータスは、open(実行を受け付ける)、closed(実行を受け付けず、一部の実行が未完了)、completed(クローズ済みで、すべての実行が完了)です。
  • open のグループは完了しません。最後の実行後に closePipelineGroup(client, id) を呼び出すか、グループ作成時に close: true を指定してください。すべての実行が完了したグループは、クローズすると完了します。
  • completed のグループ内の実行を再試行すると、グループは再び closed になります。completion_count は完了回数をカウントします。
  • listPipelineGroups(client, { status, pipeline_id, metadata }) と getPipelineGroup(client, id) は、実行数を含むグループを返します。
  • getPipelineGroupReport(client, id) は、ステータスごとの実行数、queue_wait_ms と run_duration_ms(p50、p95、max)、入力の media_minutes、エラーコードの頻度上位 5 件を含む step_failures、および usage を返します。

実行とステップ:

  • 実行ステータスは、pending、running、succeeded、failed、filtered、cancelled です。filtered は、フィルターまたはレビューによって、すべてのブランチが最終ステップの前に停止したことを意味します。これはエラーではありません。停止したブランチがあっても、最終ステップが成功すれば、実行は succeeded で終了します。
  • ステップステータスは、pending、ready、running、waiting_external、waiting_review、succeeded、failed、skipped、cancelled です。
  • getPipelineRun は、深さ、次にステップキーの順で steps を返します。needs を持たないステップの深さは 0 です。別のステップの深さは、その needs に含まれるステップの深さの最大値に 1 を加えた値です。つまり、各ステップは依存するステップの後に実行されます。
  • 各ステップまたはウィンドウの試行回数は 3 回です。再試行の待機時間は 10 秒から始まり、最大 10 分まで倍増します。
  • transcribe、sample_frames、または detect_scenes の試行は、たとえばワーカーのメモリ不足などでデコーダーが停止すると、decoder_killed で失敗します。この失敗により再試行が開始されます。ステップでデコードできないファイルは decode_failed で失敗し、再試行は開始されません。
  • 成功、失敗、または filtered で終了した実行に対して cancelPipelineRun を呼び出すと、409 run_not_cancellable が返されます。
  • retryPipelineRun は、failed と cancelled の実行にのみ使用できます。それ以外の実行では 409 run_not_retryable が返されます。成功したステップの出力は保持されます。
  • getPipelineRunOutputs(client, runId, namespace) は、セグメントステップの各ウィンドウにつき 1 ページの出力を返します。
  • getFilePipelineMetadata(client, fileId, namespace) は、あらゆる実行によるファイル上の最新の出力を返します。
  • リクエストが失敗すると、status、code、issues([{ path, code }])を含む PipelineApiError がスローされます。

アップロード完了前に実行を開始するには、@editframe/api/pipelines/upload の uploadFragmented を使用してアップロードします。onCreated で実行を開始してください。セグメントステップは、メディアが届くたびに各ウィンドウを処理します。

import { uploadFragmented } from "@editframe/api/pipelines/upload";

await uploadFragmented(client, "dashcam.mp4", {
  onCreated: async (file) => {
    await createPipelineRun(client, { pipeline_id: pipelineId, file_id: file.id }, { idempotencyKey: `upload:${file.id}` });
  },
});

パイプラインの Webhook トピックについては、webhooks スキルを参照してください。

パイプラインを一時停止する

新しい作業を停止し、実行履歴を保持するには、パイプラインを一時停止します。一時停止はパイプラインのすべてのバージョンに適用されます。

import { pausePipeline, resumePipeline } from "@editframe/api/pipelines";

const paused = await pausePipeline(client, pipelineId); // paused.paused_at is the time of the pause.
await resumePipeline(client, pipelineId); // paused_at is null again.
  • 一時停止中のパイプラインでも、新しいバージョン、実行、グループを受け付けます。新しい実行は pending のままになります。
  • パイプラインを再開するまで、実行、ステップ、試行、セグメントウィンドウは開始されません。
  • 一時停止前に開始した試行は続行されます。Editframe はそれらのエンドポイントコールバックとレビュー判断を記録します。
  • 開始されなかったステップには期限が設定されないため、一時停止によってタイムアウトが発生することはありません。
  • 実行をキャンセルして再試行できます。再試行された実行は、パイプラインを再開するまで pending のままになります。
  • パイプラインを再開すると、待機中の実行とステップがすぐに開始されます。
  • 2 回目の一時停止や再開を行っても、状態は変わらず、記録も残りません。アーカイブ済みのパイプラインは 409 pipeline_archived を返します。
  • Editframe は、各一時停止と再開を、実行した API キーまたはユーザーとともに記録します。この変更履歴はダッシュボードに表示されます。
  • 一時停止と再開では、ウェブフックは送信されません。開始されなかった実行では、使用量も記録されません。
  • listPipelines(client, { paused: true }) は、一時停止中のパイプラインのみを返します。
パイプライン CLI

editframe pipelines はクラウド API を直接呼び出します。API キーは EDITFRAME_TOKEN から読み取ります。--project、--bridge、その他のランタイムオプションは使用しません。

export EDITFRAME_TOKEN="$EDITFRAME_API_KEY"
npx editframe pipelines create speech-check --definition speech-check.json
npx editframe pipelines runs create PIPELINE_ID FILE_ID --watch
npx editframe pipelines upload dashcam.mp4 --run PIPELINE_ID --watch
npx editframe pipelines reviews approve REVIEW_ID --patch corrections.json
npx editframe pipelines pause PIPELINE_ID
npx editframe pipelines resume PIPELINE_ID
  • --watch は、実行が失敗またはキャンセルされた場合、終了ステータス 1 で終了します。
  • --json は、API レスポンスを JSON 形式で出力します。
  • すべてのコマンドについては、npx editframe pipelines --help を実行してください。

フィードバックを送信する

問題や改善点について、Editframe にフィードバックを送信します。

  • Editframe または Editframe のスキルが問題を引き起こした場合は、回避策を見つけてタスクを続行してください。その後、問題と回避策を報告します。
  • 現在のタスクだけでなく、ほかのタスクにも役立つ改善点を見つけた場合は、提案を送信してください。たとえば、より明確な指示、不足している例、より適切なデフォルト、新機能を提案できます。

問題や提案が異なる場合は、それぞれ個別に報告してください。報告に失敗しても、タスクを続行してください。

const headers: Record<string, string> = { "Content-Type": "application/json" };
if (process.env.EDITFRAME_API_KEY) headers.Authorization = `Bearer ${process.env.EDITFRAME_API_KEY}`;

const response = await fetch("https://editframe.com/api/v1/feedback", {
  method: "POST",
  headers,
  body: JSON.stringify({
    category: "feature_request",
    skill: "editframe-api",
    summary: "Add a function that cancels a render",
    details: "A render started with the wrong input. No function stops it, so the render uses time and quota.",
    workaround: "I let the render finish and ignored the output.",
    context: { render_id: render.id, package: "@editframe/api" },
  }),
});

本文は application/json として送信します。

フィールド必須上限内容
categoryはい—以下のカテゴリのいずれか
summaryはい200 文字問題または提案の内容を示す 1 行の説明
detailsはい10,000 文字問題の場合:手順、期待される結果、実際の結果、エラーメッセージ。提案の場合:変更内容とそのメリット。
workaroundいいえ10,000 文字問題に対して使用した回避策
skillいいえ100 文字使用したスキル。例:composition
contextいいえ20 件文字列値のみ。例:render_id、file_id、パッケージのバージョン。キーは 1~64 文字です。値は最大 1,000 文字です。
カテゴリ用途
bugEditframe がドキュメントの説明どおりに動作しない場合。
documentationスキルまたはドキュメントに誤りがある、不明瞭である、または不完全な場合。
feature_request必要な機能が Editframe にない場合。
performance処理が遅い、またはリソースを使いすぎる場合。
otherワークフローや API の設計に関する内容など、その他すべての問題や提案。

リクエスト本文の上限は 256 KiB です。不明なフィールドがあるとエラーになります。

Authorization ヘッダーは省略可能です。有効な API キーを指定した報告では、組織が特定されます。キーを指定しない報告は匿名になります。報告にシークレット、API キー、個人データを含めないでください。

ステータス本文対応
201{ "id", "created_at" }対応は不要です。Editframe が報告を受け取りました。
400{ "error": "invalid_json" | "invalid_feedback", "message" }message に従って報告を修正し、再送信してください。
401UnauthorizedAPI キーが無効です。Authorization ヘッダーを付けずに、報告を再送信してください。
413{ "error": "payload_too_large", "message" }報告を短くしてください。
415{ "error": "unsupported_media_type", "message" }Content-Type: application/json を設定してください。
429{ "error": "rate_limited", "message" }Retry-After の間隔が経過するまで、追加の報告を送信しないでください。
503{ "error": "unavailable", "message" }Retry-After の間隔が経過してから、報告をもう一度送信してください。

関数一覧

キャプションファイル
  • createCaptionFile(client: Client, payload: CreateCaptionFilePayload) — キャプションファイルを作成します
  • lookupCaptionFileByMd5(client: Client, md5: string)
  • uploadCaptionFile(client: Client, fileId: string, fileStream: ReadableStream, fileSize: number)
ファイル
  • createFile(client: Client, payload: CreateFilePayload)
  • createFileTrack(client: Client, fileId: string, payload: CreateISOBMFFTrackPayload)
  • deleteFile(client: Client, id: string)
  • getFileDetail(client: Client, id: string)
  • getFileProcessingProgress(client: Client, id: string)
  • getFileTranscription(client: Client, id: string)
  • lookupFileByMd5(client: Client, md5: string)
  • transcribeFile(client: Client, id: string, options?: { trackId?: number }) — 使用しないでください。このエンドポイントは 410 Gone を返します。ファイルを文字起こしするには、transcribe ステップを含むパイプライン実行を開始してください。
  • uploadFile(client: Client, uploadDetails: { id: string; byte_size: number; type: FileType }, fileStream: ReadableStream)
  • uploadFileIndex(client: Client, fileId: string, fileStream: ReadableStream, fileSize: number)
  • uploadFileTrack(client: Client, fileId: string, trackId: number, byteSize: number, fileStream: ReadableStream)
画像ファイル
  • createImageFile(client: Client, payload: CreateImageFilePayload)
  • getImageFileMetadata(client: Client, id: string)
  • lookupImageFileByMd5(client: Client, md5: string)
  • uploadImageFile(client: Client, uploadDetails: { id: string; byte_size: number; }, fileStream: ReadableStream, chunkSizeBytes?: number)
ISOBMFF ファイル
  • createISOBMFFFile(client: Client, payload: CreateISOBMFFFilePayload)
  • getISOBMFFFileTranscription(client: Client, id: string)
  • lookupISOBMFFFileByMd5(client: Client, md5: string)
  • transcribeISOBMFFFile(client: Client, id: string, payload?: TranscribeISOBMFFFilePayload) — 使用しないでください。このエンドポイントは 410 Gone を返します。ファイルを文字起こしするには、transcribe ステップを含むパイプライン実行を開始してください。
  • uploadFragmentIndex(client: Client, fileId: string, fileStream: ReadableStream, fileSize: number)
ISOBMFF トラック
  • createISOBMFFTrack(client: Client, payload: CreateISOBMFFTrackPayload)
  • uploadISOBMFFTrack(client: Client, fileId: string, trackId: number, fileStream: ReadableStream, trackSize: number)
Node
  • createImageFileFromPath(client: Client, path: string)
  • createUnprocessedFileFromPath(client: Client, path: string)
  • upload(client: Client, filePath: string)
  • uploadUnprocessedFile(client: Client, uploadDetails: UnprocessedFileUploadDetails, path: string)
ISOBMFF の処理
  • getIsobmffProcessInfo(client: Client, id: string)
  • getIsobmffProcessProgress(client: Client, id: string)
レンダリング
  • createRender(client: Client, payload: CreateRenderPayload)
  • defaultWorkSliceMs()
  • deleteRender(client: Client, id: string)
  • downloadRender(client: Client, id: string)
  • getRenderInfo(client: Client, id: string)
  • getRenderProgress(client: Client, id: string)
  • lookupRenderByMd5(client: Client, md5: string)
  • uploadRender(client: Client, renderId: string, fileStream: ReadableStream)
文字起こし
  • createTranscription(client: Client, payload: CreateTranscriptionPayload) — 使用しないでください。このエンドポイントは 410 Gone を返します。ファイルを文字起こしするには、transcribe ステップを含むパイプライン実行を開始してください。
  • getTranscriptionInfo(client: Client, id: string)
  • getTranscriptionProgress(client: Client, id: string)
未処理ファイル
  • createUnprocessedFile(client: Client, payload: CreateUnprocessedFilePayload)
  • lookupUnprocessedFileByMd5(client: Client, md5: string)
  • processIsobmffFile(client: Client, id: string)
  • uploadUnprocessedReadableStream(client: Client, uploadDetails: UnprocessedFileUploadDetails, fileStream: ReadableStream)
URL トークン
  • createURLToken(client: Client, url: string)

CLI コマンド

グローバルオプション:

オプションデフォルト説明
-h, --help—使用方法を表示します
--version—CLI のバージョンを表示します
--project <value>—ローカルプロジェクトの絶対パス
--bridge <value>—インストール済みのブリッジ実行ファイル
--component <value>—インストール済みの署名済みコンポーネントディレクトリ
--registry <value>—ローカルブリッジレジストリディレクトリ
--editor <value>—検証済みのエディターアセットディレクトリ
--editor-version <value>—検証済みのエディターバージョン
--compiler-pack <value>—検証済みのコンパイラパックファイル
--compiler-pack-sha256 <value>—期待されるコンパイラパックの SHA-256
--endpoint <value>—ホスト型ランタイム API エンドポイント
--project-id <value>—ホスト型プロジェクト識別子
--composition <value>—コンポジション識別子
--input <value>—明示的な操作識別子とリビジョンを含む JSON リクエストファイル
--job <value>—ジョブ識別子
-o, --output <value>—render が書き込む MP4 ファイル(デフォルトは output.mp4)
コマンド目的
editframe command明示的なリビジョン付きコンポジションコマンドを適用します
editframe compositions選択したプロジェクト内のコンポジションを一覧表示します
editframe contextコンポジションのリビジョンと編集コンテキストを読み取ります
editframe export選択したコンポジションのエクスポートをリクエストします
editframe jobプロジェクトのジョブを 1 件読み取ります
editframe jobsプロジェクトのジョブを一覧表示します
editframe mcpMCP stdio 経由でエージェントをローカルブリッジに接続します
editframe openローカルのブラウザーエディターを開きます
editframe pipelinesクラウドパイプライン、実行、グループ、レビューを管理します
editframe projectsアクセス可能なプロジェクトを一覧表示します
editframe renderローカルランタイムとヘッドレス Chrome を使用してコンポジションを MP4 にレンダリングします
editframe startプロジェクト用にインストール済みのローカルブリッジを起動します
editframe statusローカルブリッジのステータスを表示します
editframe stopプロジェクトのローカルブリッジを停止します

コメント