Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

Direct Creator Uploads

最終更新 Markdown で表示Agent セットアップ

Direct Creator Uploads を使うと、API トークンをクライアントに公開せず、エンドユーザーが Cloudflare Stream へ直接動画をアップロードできます。実装方法は 基本 POST リクエストtus プロトコル のいずれかです。次の図で、使う方法を判断します。

flowchart LR
accTitle: Direct Creator Uploads の判断フロー
accDescr: ファイルサイズと接続の安定性に応じて、基本 POST と tus プロトコルのどちらを使うかを決めるフローです。

A{"動画は 200 MB を超えますか?"}
A -->|はい| B["tus プロトコルを使う必要があります"]:::link
A -->|いいえ| C{"エンドユーザーの接続は安定していますか?"}
C -->|はい| D["基本 POST を推奨します"]:::link
C -->|いいえ| E["tus プロトコルは任意ですが、推奨します"]:::link

classDef link text-decoration:underline,color:#F38020

click B "#direct-creator-uploads-with-tus-protocol" "tus プロトコルの説明"
click D "#basic-post-request" "基本 POST の手順"
click E "#direct-creator-uploads-with-tus-protocol" "tus プロトコルの説明"

基本 POST リクエスト

エンドユーザーの動画が 200 MB 未満で、接続が安定している場合は、この方法を推奨します。接続が不安定な場合は、代わりに tus プロトコル を推奨します。

POST リクエストで Direct Creator Uploads を有効にする手順です。

ステップ 1: 一意で 1 回限りのアップロード URL を生成する

Direct upload API で、一意で 1 回限りのアップロード URL を生成します。

Generate uploadsh
curl https://api.cloudflare.com/client/v4/accounts/{account_id}/stream/direct_upload \
--header 'Authorization: Bearer <API_TOKEN>' \
 --data '{
    "maxDurationSeconds": 3600
 }'
{
	"result": {
		"uploadURL": "https://upload.videodelivery.net/f65014bc6ff5419ea86e7972a047ba22",
		"uid": "f65014bc6ff5419ea86e7972a047ba22"
	},
	"success": true,
	"errors": [],
	"messages": []
}

外部アプリケーションから REST API を使う方法と、TypeScript、Python、Go 向けの事前生成 SDK の詳細は、Stream の REST API と SDK リファレンス を参照してください。

export default {
	async fetch(request, env, ctx): Promise<Response> {
		const directUpload = await env.STREAM.createDirectUpload({
			maxDurationSeconds: 3600,
		});

		return new Response(JSON.stringify(directUpload));
	},
} satisfies ExportedHandler<{ STREAM: StreamBinding }>;
{
	"$schema": "node_modules/wrangler/config-schema.json",
	"name": "<ENTER_WORKER_NAME>",
	"main": "src/index.ts",
	"compatibility_date": "$today",
	"observability": {
		"enabled": true
	},
	"stream": {
		"binding": "STREAM"
	}
}

Workers Stream binding API リファレンス を参照してください。

ステップ 2: 1 回限りの URL へ動画をアップロードする

前のステップの uploadURL を使い、ユーザーは 200 MB までの動画ファイルをアップロードできます。次のリクエスト例を参照してください。

Upload a video to the unique one-time upload URLbash
curl --request POST \
  --form file=@/Users/mickie/Downloads/example_video.mp4 \
  https://upload.videodelivery.net/f65014bc6ff5419ea86e7972a047ba22

成功すると HTTP ステータス 200 が返ります。作成時に定義した制約を満たさない、または 200 MB を超える場合は、4xx が返ります。

tus プロトコルによる Direct Creator Uploads

動画が 200 MB を超える場合は、tus プロトコルが必須です。200 MB 未満でも、接続が不安定になり得る場合は、再開できるため tus プロトコルを推奨します。tus の要件、クライアント例、アップロードオプションの詳細は、再開可能な大容量ファイル(tus) を参照してください。

この 2 ステップの流れは、次の図のとおりです。

sequenceDiagram
accTitle: tus による Direct Creator Uploads のシーケンス図
accDescr: バックエンドが tus アップロード URL を発行し、エンドユーザーが Stream へ直接アップロードする 2 ステップの流れです。

participant U as エンドユーザー
participant B as バックエンド
participant S as Cloudflare Stream

U->>B: アップロードを開始する
B->>S: tus アップロード URL を要求する(認証あり)
S->>B: 1 回限りのアップロード URL を返す
B->>U: 1 回限りのアップロード URL を返す
U->>S: tus で動画を直接アップロードする

ステップ 1: バックエンドが一回限りのアップロード URL を発行する

次の例は、エンドユーザーに1 回限りのアップロード URL を返す Worker の作り方です。tus プロトコルのアップロードでは、バックエンドが Tus-ResumableUpload-LengthUpload-Metadata ヘッダーを渡す必要があります。1 回限りのアップロード URL はレスポンス本文ではなく、Location ヘッダーで返ります。

Example tus API endpointjavascript
export async function onRequest(context) {
	const { request, env } = context;
	const { CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_API_TOKEN } = env;
	const endpoint = `https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/stream?direct_user=true`;

	const response = await fetch(endpoint, {
		method: "POST",
		headers: {
			Authorization: `bearer ${CLOUDFLARE_API_TOKEN}`,
			"Tus-Resumable": "1.0.0",
			"Upload-Length": request.headers.get("Upload-Length"),
			"Upload-Metadata": request.headers.get("Upload-Metadata"),
		},
	});

	const destination = response.headers.get("Location");

	return new Response(null, {
		headers: {
			"Access-Control-Expose-Headers": "Location",
			"Access-Control-Allow-Headers": "*",
			"Access-Control-Allow-Origin": "*",
			Location: destination,
		},
	});
}

ステップ 2: エンドユーザーのクライアントが Stream へ直接アップロードする

tus クライアントから、バックエンドのエンドポイントを直接使います。ステップ 1 のバックエンドを uppy tus クライアントと組み合わせる完全な例は、次のとおりです。

Upload a video using the uppy tus clienthtml
<html>
	<head>
		<link
			href="https://releases.transloadit.com/uppy/v3.0.1/uppy.min.css"
			rel="stylesheet"
		/>
	</head>
	<body>
		<div id="drag-drop-area" style="height: 300px"></div>
		<div class="for-ProgressBar"></div>
		<button class="upload-button" style="font-size: 30px; margin: 20px">
			Upload
		</button>
		<div class="uploaded-files" style="margin-top: 50px">
			<ol></ol>
		</div>
		<script type="module">
			import {
				Uppy,
				Tus,
				DragDrop,
				ProgressBar,
			} from "https://releases.transloadit.com/uppy/v3.0.1/uppy.min.mjs";

			const uppy = new Uppy({ debug: true, autoProceed: true });

			const onUploadSuccess = (el) => (file, response) => {
				const li = document.createElement("li");
				const a = document.createElement("a");
				a.href = response.uploadURL;
				a.target = "_blank";
				a.appendChild(document.createTextNode(file.name));
				li.appendChild(a);

				document.querySelector(el).appendChild(li);
			};

			uppy
				.use(DragDrop, { target: "#drag-drop-area" })
				.use(Tus, {
					endpoint: "/api/get-upload-url",
					chunkSize: 150 * 1024 * 1024,
				})
				.use(ProgressBar, {
					target: ".for-ProgressBar",
					hideAfterFinish: false,
				})
				.on("upload-success", onUploadSuccess(".uploaded-files ol"));

			const uploadBtn = document.querySelector("button.upload-button");
			uploadBtn.addEventListener("click", () => uppy.upload());
		</script>
	</body>
</html>

tus の詳細とクライアントコード例は、再開可能な大容量ファイル(tus) を参照してください。

Upload-Metadata ヘッダーの構文

tus を使う場合も、basic upload の Direct Creator Upload と 同じ制約 を適用できます。そのためには、最初のリクエスト(上の例では Worker が行うリクエスト)の Upload-Metadata リクエストヘッダーに expirymaxDurationSeconds を含めます。実際のファイルアップロードを行う後続リクエストでは、Upload-Metadata の値は無視されます。

Upload-Metadata ヘッダーにはキーと値のペアを入れます。キーはテキスト、値は base64 でエンコードします。キーと値は等号ではなく、スペースで区切ります。複数のペアを連結するときは、余分なスペースなしのカンマを使います。

次の例では、Upload-Metadata ヘッダーが Stream に対し、最大再生時間 10 分、有効期限タイムスタンプより前のアップロードのみを受け付け、この動画を非公開にするよう指示しています。

'Upload-Metadata: maxDurationSeconds NjAw,requiresignedurls,expiry MjAyNC0wMi0yN1QwNzoyMDo1MFo='

NjAw は "600"(10 分)を base64 エンコードした値です。

MjAyNC0wMi0yN1QwNzoyMDo1MFo= は "2024-02-27T07:20:50Z"(RFC3339 形式のタイムスタンプ)を base64 エンコードした値です。

アップロードの進捗を追跡する

一意で 1 回限りのアップロード URL を作成したら、レスポンスの一意の識別子(uid)を保持し、ユーザーのアップロード進捗を追跡します。

進捗は次の方法で追跡できます。

役に立ちましたか?