跳转到内容
搜索文档

绑定 Workers API

最后更新 查看 MarkdownAgent 设置

绑定(binding) 将您的 Worker 连接到 Developer Platform 上的外部资源,如 Media TransformationsR2 存储桶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"
    • durationvideoaudiospritesheet 模式的输出时长(例如 "5s")。
    • imageCount:spritesheet 中包含的帧数。
    • formatframe 模式(jpgpng)或 audio 模式(m4a)的输出格式。
    • audio:在 video 模式中是否包含音频的布尔值。默认值:true

结果方法

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

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

这篇文档对您有帮助吗?