跳转到内容
搜索文档

绑定 Workers API

最后更新 查看 MarkdownAgent 设置

绑定(binding) 将您的 Worker 连接到 Developer Platform 上的外部资源,如 Media Transformations、R2 存储桶 或 KV 命名空间。

您可以将 Media Transformations API 绑定到 Worker,以转换、调整大小和从视频中提取内容,而无需通过 URL 访问它们。

例如,在 Workers 中使用 Media Transformations 时,您可以:

  • 转换存储在私有 R2 存储桶或其他受保护源中的视频
  • 优化视频并将输出直接存储回 R2,而无需提供给浏览器
  • 从视频中提取静态帧和 spritesheet,并使用 Workers AI 进行分类或描述
  • 从视频文件中提取音轨,使用 Workers AI 进行动态转录

设置

Media 绑定按 Worker 启用。

绑定(binding) 可在 Cloudflare 仪表板中为 Worker 配置,或在项目目录的 Wrangler 配置文件中配置。

要将 Media Transformations 绑定到 Worker,请在 Wrangler 配置文件末尾添加以下内容:

{
  "$schema": "./node_modules/wrangler/config-schema.json",
  "media": {
    "binding": "MEDIA"
  }
}
[media]
binding = "MEDIA" # available in your Worker on env.MEDIA

在 Worker 代码中,您可以使用 env.MEDIA.input() 构建可操作视频(作为 ReadableStream 传递)的对象来与此绑定交互。

方法

Media Transformations 绑定类似于 Images 绑定,但方法链顺序固定,且 input() 的结果不能跨多个转换重用。

.input()

Media 绑定的起点,接受原始内容。

  • 接受包含视频字节的 ReadableStream<Uint8Array>。

.transform()(可选)

定义如何通过对视频调整大小或裁剪来转换输入。此方法为可选——如果不需要调整大小或裁剪,可以直接在 .input() 的结果上调用 .output()。

  • 接受以下参数(均为可选):
    • width:目标宽度(像素,10-2000)。
    • height:目标高度(像素,10-2000)。
    • fit:如何将视频调整大小以适应指定尺寸。
      • contain:保持宽高比,将视频缩放以完全包含在输出尺寸内。
      • cover:保持宽高比,将视频缩放以完全覆盖输出尺寸并进行居中裁剪。
      • scale-down:与 contain 相同,但仅缩小。不放大。
  • 请参阅 转换视频选项 了解更多详情。

.output()

定义从视频中提取什么以及输出如何格式化。请参阅 源视频要求 和 限制 了解输入和输出约束。

  • 接受以下参数:
    • mode:要生成的输出类型。
      • video:输出 H.264/AAC 优化的 MP4 文件。
      • frame:输出静态图像(JPEG 或 PNG)。
      • spritesheet:输出包含多帧的 JPEG。
      • audio:输出 AAC 编码的 M4A 文件。
    • time:提取的起始时间戳(例如 "2s"、"1m")。默认值:"0s"。
    • duration:video、audio 或 spritesheet 模式的输出时长(例如 "5s")。
    • imageCount:spritesheet 中包含的帧数。
    • format:frame 模式(jpg、png)或 audio 模式(m4a)的输出格式。
    • audio:在 video 模式中是否包含音频的布尔值。默认值:true。

结果方法

配置输出后,有三种方法可用于接收结果。这些方法返回 Promise,必须 await:

  • .response():返回 Promise<Response>——转换后的媒体作为 HTTP Response 对象,可直接返回给客户端或存储到缓存。
  • .media():返回 Promise<ReadableStream<Uint8Array>>——转换后的媒体作为字节流。
  • .contentType():返回 Promise<string>——输出的 MIME 类型(例如 video/mp4、image/jpeg、audio/mp4)。

示例

生成优化的视频片段

调整视频大小并提取 5 秒片段:

export default {
	async fetch(request, env) {
		const video = await env.R2_BUCKET.get("input.mp4");

		const result = env.MEDIA.input(video.body)
			.transform({ width: 480, height: 270 })
			.output({ mode: "video", time: "0s", duration: "5s" });

		return await result.response();
	},
};

提取静态帧

提取单帧作为 JPEG 缩略图:

export default {
	async fetch(request, env) {
		const video = await env.R2_BUCKET.get("input.mp4");

		const result = env.MEDIA.input(video.body)
			.transform({ width: 640, height: 360 })
			.output({ mode: "frame", time: "2s", format: "jpg" });

		return await result.response();
	},
};

使用 Media Transformations 和 Workers AI 识别内容

从视频中提取帧(静态图像),然后使用 Workers AI 上的 UForm-Gen 等模型生成标题。

export default {
	async fetch(request, env) {
		// First, load the video file from a source like R2 (or a fetch)

		// Loading from R2
		const video = await env.R2_BUCKET.get("input.mp4");

		// Or using a fetch:
		// const video = await fetch('https://example.com/video.mp4');

		// Isolate a frame (still image)
		const frame = await env.MEDIA.input(video.body)
			.transform({ width: 720 })
			.output({
				mode: 'frame',
				time: '3s',
			})
			.response();

		// Set up the payload for Workers AI
		const payload = {
			image: [...new Uint8Array(await frame.arrayBuffer())],
			prompt: "Generate a caption for this image",
			max_tokens: 512,
		};
		const response = await env.AI.run(
			"@cf/unum/uform-gen2-qwen-500m",
			payload
		);
		return new Response(JSON.stringify(response));
	}
}

提取音频

从视频中提取音轨为 M4A 文件。此示例演示跳过 .transform(),因为不需要调整大小:

export default {
	async fetch(request, env) {
		const video = await env.R2_BUCKET.get("input.mp4");

		const result = env.MEDIA.input(video.body).output({
			mode: "audio",
			time: "0s",
			duration: "30s",
		});

		return await result.response();
	},
};

使用 Media Transformations 和 Workers AI 转录音频

提取音频,然后使用 Workers AI 上的 Whisper 进行转录。

export default {
	async fetch(request, env) {
		// First, load the video file from a source like R2 (or a fetch)

		// Loading from R2
		const video = await env.R2_BUCKET.get("input.mp4");

		// Or using a fetch:
		// const video = await fetch('https://example.com/video.mp4');

		// Extract audio using the media transformations binding:
		const audio = await env.MEDIA.input(video.body)
			.transform()
			.output({
				mode: 'audio',
				})
			.response();

		// Prepare and run Workers AI inference
		const payload = {
			audio: [...new Uint8Array(await audio.arrayBuffer())],
		};
		const response = await env.AI.run(
			"@cf/openai/whisper",
			payload
		);

		// response will have props {text, word_count, vtt, words}
		return new Response(
			JSON.stringify(response, null, 2),
			{
				headers: {'Content-Type': 'application/json'}
			}
		);
	}
}

将转换后的输出存储到 R2

转换视频并将结果直接存储到 R2:

export default {
	async fetch(request, env) {
		const video = await env.R2_BUCKET.get("input.mp4");

		const result = env.MEDIA.input(video.body)
			.transform({ width: 480, height: 270, fit: "contain" })
			.output({ mode: "video", time: "0s", duration: "10s", audio: false });

		// Store the transformed video directly in R2
		await env.R2_BUCKET.put("output-480p.mp4", await result.media(), {
			httpMetadata: { contentType: await result.contentType() },
		});

		return new Response("Video transformed and stored", { status: 200 });
	},
};

错误处理

错误可能在方法链的不同点抛出:

  • .input() 可能抛出与账户限制(免费层或订阅)或服务中断相关的错误。
  • .output() 可能抛出与转换操作本身相关的错误,例如无效参数或不支持的输入格式。

错误抛出 MediaError,它扩展标准 Error 接口并提供额外信息:

  • code:数字错误代码。
  • message:错误描述。
  • stack:可选堆栈跟踪。

使用 try...catch 块处理错误:

export default {
	async fetch(request, env) {
		const video = await env.R2_BUCKET.get("input.mp4");

		try {
			const result = env.MEDIA.input(video.body)
				.transform({ width: 480, height: 270 })
				.output({ mode: "video", time: "0s", duration: "5s" });

			return await result.response();
		} catch (e) {
			if (e instanceof Error && "code" in e) {
				// Handle MediaError
				return new Response(`Transformation failed: ${e.message}`, {
					status: 500,
				});
			}
			throw e;
		}
	},
};

缓存

与通过 URL 的转换不同,Media 绑定的响应 不会 自动缓存。Workers 让您直接与 Cache API 交互以自定义缓存行为。您可以在脚本中实现逻辑,将转换存储到 Cloudflare 缓存或 R2 存储。

计费

请参阅 Stream 的 定价 信息了解费用。通过绑定执行的转换按每次操作计费,而非基于请求唯一性。为获得最佳成本和性能优化,请缓存或存储输出以供重用。

本地开发

Media Transformations API 通过 Wrangler(Workers 命令行界面)在本地开发中以 远程模式 可用。转换操作将使用远程资源执行,超出包含的免费层后将产生用量费用。

要在本地开发中启用,请在绑定配置中添加 remote:

{
  "$schema": "./node_modules/wrangler/config-schema.json",
  "media": {
    "binding": "MEDIA",
    "remote": true
  }
}
[media]
binding = "MEDIA" # available in your Worker on env.MEDIA
remote = true

然后运行:

npx wrangler dev

这篇文档对您有帮助吗?