绑定(binding) 将您的 Worker 连接到 Developer Platform 上的外部资源,如 Stream、R2 存储桶 或 KV 命名空间。
例如,在 Workers 中使用 Stream 时,您可以:
- 从 URL 上传视频并管理其生命周期
- 创建直接上传(direct upload),供客户端上传而无需暴露 API key
- 列出和搜索视频
- 管理视频的字幕和下载
- 创建和管理水印配置文件
Stream 绑定按 Worker 启用。
要将 Stream 绑定到 Worker,请在 Wrangler 配置文件末尾添加以下内容:
{
"stream": {
"binding": "STREAM"
}
}[stream]
binding = "STREAM"有关配置 Worker 的更多详细信息,请参阅 Wrangler 配置文档。
以下方法可直接在 env.STREAM 绑定上使用。
从 URL 上传视频。返回 Promise<StreamVideo>.
url(必需):要上传的视频 URL。params(可选):StreamUrlUploadParams对象,包含以下属性:allowedOrigins:允许显示视频的来源数组。creator:创作者标识符。meta:任意元数据对象。requireSignedURLs:是否需要 signed URL。scheduledDeletion:计划删除的 ISO 8601 时间戳。thumbnailTimestampPct:缩略图时间戳百分比(0.0 到 1.0)。watermarkId:要应用的水印配置文件 ID。
可能抛出:BadRequestError、QuotaReachedError、MaxFileSizeError、RateLimitedError、AlreadyUploadedError、InternalError。
创建基本直接上传 URL,供客户端上传而无需 API key。返回 Promise<StreamDirectUpload>,包含 uploadURL 和 id。
此方法目前不支持超过 200MB 的文件。 对于更大的直接上传,请参阅配置 TUS 端点的 API 请求。
params(必需):StreamDirectUploadCreateParams对象,包含以下属性:maxDurationSeconds(必需):上传视频的最大时长(秒)。expiry(可选):上传 URL 过期的 ISO 8601 时间戳。creator(可选):创作者标识符。meta(可选):任意元数据对象。allowedOrigins(可选):允许显示视频的来源数组。requireSignedURLs(可选):是否需要 signed URL。thumbnailTimestampPct(可选):缩略图时间戳百分比(0.0 到 1.0)。scheduledDeletion(可选):计划删除的 ISO 8601 时间戳。watermark(可选):要应用的水印配置文件 ID。
列出账户中的所有视频。返回 Promise<StreamVideo[]>.
params(可选):StreamVideosListParams对象,包含以下属性:limit:返回的最大视频数量。before:返回在此 ISO 8601 时间戳之前创建的视频。beforeComp:before的比较运算符 —eq、gt、gte、lt或lte。after:返回在此 ISO 8601 时间戳之后创建的视频。afterComp:after的比较运算符 —eq、gt、gte、lt或lte。
调用 env.STREAM.video(id) 返回限定于单个视频的处理句柄,包含以下方法。
获取完整视频详情。返回 Promise<StreamVideo>.
更新视频元数据。返回 Promise<StreamVideo>.
params(必需):StreamUpdateVideoParams对象,包含以下属性:allowedOrigins:允许显示视频的来源数组。creator:创作者标识符。maxDurationSeconds:最大时长(秒)。meta:任意元数据对象。requireSignedURLs:是否需要 signed URL。scheduledDeletion:计划删除的 ISO 8601 时间戳。thumbnailTimestampPct:缩略图时间戳百分比(0.0 到 1.0)。
删除视频及其副本。返回 Promise<void>.
为视频创建 signed URL token。返回 Promise<string>.
视频下载操作的命名空间。
generate(downloadType?):生成下载。downloadType为StreamDownloadType的default或audio。默认为default。返回Promise<StreamDownloadGetResponse>。get():列出现有下载。返回Promise<StreamDownloadGetResponse>。delete(downloadType?):删除下载。downloadType为default或audio。
视频字幕操作的命名空间。
upload(language, input):上传 BCP 47 语言标签的字幕文件。input为ReadableStream。返回Promise<StreamCaption>。generate(language):为 BCP 47 语言标签通过 AI 生成字幕。返回Promise<StreamCaption>。list(language?):列出字幕,可按语言筛选。返回Promise<StreamCaption[]>。delete(language):删除指定语言的字幕。返回Promise<void>。
以下方法可在 env.STREAM.watermarks 命名空间上使用。
创建水印配置文件。接受 ReadableStream 或 URL 字符串。返回 Promise<StreamWatermark>。
input(必需):水印图像的ReadableStream或 URL 字符串。params(可选):StreamWatermarkCreateParams对象,包含以下属性:name:水印配置文件名称。opacity:水印透明度(0.0 到 1.0)。padding:水印周围相对于视频分辨率的内边距比例。scale:水印相对于视频分辨率的缩放比例。position:水印位置 —upperRight、upperLeft、lowerLeft、lowerRight或center。
列出所有水印配置文件。返回 Promise<StreamWatermark[]>。
获取单个水印配置文件。返回 Promise<StreamWatermark>。
watermarkId(必需):水印配置文件的 ID。
删除水印配置文件。返回 Promise<void>。
watermarkId(必需):水印配置文件的 ID。
export default {
async fetch(request, env) {
const video = await env.STREAM.upload("https://example.com/video.mp4", {
creator: "user-123",
meta: { category: "tutorial" },
allowedOrigins: ["example.com"],
});
return Response.json(video);
},
};export default {
async fetch(request, env) {
const video = await env.STREAM.upload("https://example.com/video.mp4", {
creator: "user-123",
meta: { category: "tutorial" },
allowedOrigins: ["example.com"],
});
return Response.json(video);
},
};export default {
async fetch(request, env) {
const directUpload = await env.STREAM.createDirectUpload({
maxDurationSeconds: 300,
creator: "user-123",
meta: { source: "browser-upload" },
});
return Response.json(directUpload);
},
};export default {
async fetch(request, env) {
const directUpload = await env.STREAM.createDirectUpload({
maxDurationSeconds: 300,
creator: "user-123",
meta: { source: "browser-upload" },
});
return Response.json(directUpload);
},
};export default {
async fetch(request, env) {
const videos = await env.STREAM.videos.list({
limit: 10,
after: "2025-01-01T00:00:00Z",
});
return Response.json(videos);
},
};export default {
async fetch(request, env) {
const videos = await env.STREAM.videos.list({
limit: 10,
after: "2025-01-01T00:00:00Z",
});
return Response.json(videos);
},
};export default {
async fetch(request, env) {
const videoDetails = await env.STREAM.video("VIDEO_ID").details();
return Response.json(videoDetails);
},
};export default {
async fetch(request, env) {
const videoDetails = await env.STREAM.video("VIDEO_ID").details();
return Response.json(videoDetails);
},
};export default {
async fetch(request, env) {
const videoDetails = await env.STREAM.video("VIDEO_ID").update({
meta: { category: "updated-tutorial" },
allowedOrigins: ["example.com", "*.example.com"],
});
return Response.json(videoDetails);
},
};export default {
async fetch(request, env) {
const videoDetails = await env.STREAM.video("VIDEO_ID").update({
meta: { category: "updated-tutorial" },
allowedOrigins: ["example.com", "*.example.com"],
});
return Response.json(videoDetails);
},
};export default {
async fetch(request, env) {
await env.STREAM.video("VIDEO_ID").delete();
return new Response("Video deleted", { status: 200 });
},
};export default {
async fetch(request, env) {
await env.STREAM.video("VIDEO_ID").delete();
return new Response("Video deleted", { status: 200 });
},
};export default {
async fetch(request, env) {
const token = await env.STREAM.video("VIDEO_ID").generateToken();
return Response.json({ token });
},
};export default {
async fetch(request, env) {
const token = await env.STREAM.video("VIDEO_ID").generateToken();
return Response.json({ token });
},
};export default {
async fetch(request, env) {
const captionResponse = await fetch("https://example.com/captions-en.vtt");
const caption = await env.STREAM.video("VIDEO_ID").captions.upload(
"en",
captionResponse.body,
);
return Response.json(caption);
},
};export default {
async fetch(request, env) {
const captionResponse = await fetch("https://example.com/captions-en.vtt");
const caption = await env.STREAM.video("VIDEO_ID").captions.upload(
"en",
captionResponse.body,
);
return Response.json(caption);
},
};export default {
async fetch(request, env) {
const caption = await env.STREAM.video("VIDEO_ID").captions.generate("en");
return Response.json(caption);
},
};export default {
async fetch(request, env) {
const caption = await env.STREAM.video("VIDEO_ID").captions.generate("en");
return Response.json(caption);
},
};export default {
async fetch(request, env) {
const video = env.STREAM.video("VIDEO_ID");
const captions = await video.captions.list();
await video.captions.delete("en");
return Response.json(captions);
},
};export default {
async fetch(request, env) {
const video = env.STREAM.video("VIDEO_ID");
const captions = await video.captions.list();
await video.captions.delete("en");
return Response.json(captions);
},
};export default {
async fetch(request, env) {
const video = env.STREAM.video("VIDEO_ID");
const downloads = await video.downloads.generate();
const audioDownloads = await video.downloads.generate("audio");
const allDownloads = await video.downloads.get();
return Response.json({ downloads, audioDownloads, allDownloads });
},
};export default {
async fetch(request, env) {
const video = env.STREAM.video("VIDEO_ID");
const downloads = await video.downloads.generate();
const audioDownloads = await video.downloads.generate("audio");
const allDownloads = await video.downloads.get();
return Response.json({ downloads, audioDownloads, allDownloads });
},
};export default {
async fetch(request, env) {
const watermark = await env.STREAM.watermarks.generate(
"https://example.com/watermark.png",
{
name: "My Watermark",
opacity: 0.5,
position: "lowerRight",
padding: 0.05,
scale: 0.1,
},
);
return Response.json(watermark);
},
};export default {
async fetch(request, env) {
const watermark = await env.STREAM.watermarks.generate(
"https://example.com/watermark.png",
{
name: "My Watermark",
opacity: 0.5,
position: "lowerRight",
padding: 0.05,
scale: 0.1,
},
);
return Response.json(watermark);
},
};export default {
async fetch(request, env) {
const watermarks = await env.STREAM.watermarks.list();
const watermark = await env.STREAM.watermarks.get("WATERMARK_ID");
await env.STREAM.watermarks.delete("WATERMARK_ID");
return Response.json({ watermarks, watermark });
},
};export default {
async fetch(request, env) {
const watermarks = await env.STREAM.watermarks.list();
const watermark = await env.STREAM.watermarks.get("WATERMARK_ID");
await env.STREAM.watermarks.delete("WATERMARK_ID");
return Response.json({ watermarks, watermark });
},
};StreamVideo 由检索或创建视频的操作返回。包含视频的完整元数据。
idstring- 视频的唯一标识符。
creatorstring | null- 用户定义的媒体创作者标识符。
thumbnailstring- 视频的缩略图 URL。
thumbnailTimestampPctnumber- 缩略图时间戳百分比。
readyToStreamboolean- 指示视频是否可供流式传输。
readyToStreamAtstring | null- 视频变为可流式传输的日期和时间。
statusStreamVideoStatus- 处理状态信息。请参阅 StreamVideoStatus。
metaRecord<string, string>- 用户可修改的键值存储。
createdstring- 视频创建的日期和时间。
modifiedstring- 视频最后修改的日期和时间。
scheduledDeletionstring | null- 视频将被删除的日期和时间。
sizenumber- 视频大小(字节)。
previewstringoptional- 视频的预览 URL。
allowedOriginsArray<string>- 允许显示视频的来源。
requireSignedURLsboolean | null- 指示是否需要 signed URL。
uploadedstring | null- 视频上传的日期和时间。
uploadExpirystring | null- 上传 URL 过期的日期和时间。
maxSizeBytesnumber | null- 直接上传的最大大小(字节)。
maxDurationSecondsnumber | null- 直接上传的最大时长(秒)。
durationnumber- 视频时长(秒)。
-1表示未知。
- 视频时长(秒)。
inputStreamVideoInput- 原始上传的输入元数据。请参阅 StreamVideoInput。
hlsPlaybackUrlstring- 视频的 HLS 播放 URL。
dashPlaybackUrlstring- 视频的 DASH 播放 URL。
watermarkStreamWatermark | null- 应用于视频的水印(如有)。请参阅 StreamWatermark。
liveInputIdstring | nulloptional- 与视频关联的 live input ID(如有)。
clippedFromIdstring | null- 如果这是剪辑,则为源视频 ID。
publicDetailsStreamPublicDetails | null- 与视频关联的公开详情。请参阅 StreamPublicDetails。
视频的处理状态信息。
statestring- 当前处理状态。
stepstringoptional- 当前处理步骤。
pctCompletestringoptional- 完成百分比(字符串)。
errorReasonCodestring- 错误原因代码(如适用)。
errorReasonTextstring- 错误原因文本(如适用)。
原始上传的输入元数据。
widthnumber- 输入宽度(像素)。
heightnumber- 输入高度(像素)。
与视频关联的公开详情。
titlestring | null- 视频的公开标题。
share_linkstring | null- 公开分享链接。
channel_linkstring | null- 公开频道链接。
logostring | null- 公开 logo URL。
由 createDirectUpload() 返回。包含直接上传的上传 URL 和视频标识符。
uploadURLstring- 未经身份验证的上传可用于单次 multipart 请求的 URL。
idstring- Cloudflare 生成的媒体项唯一标识符。
watermarkStreamWatermark | null- 应用于上传的水印配置文件。请参阅 StreamWatermark。
scheduledDeletionstring | null- 计划删除时间(如有)。
表示视频的字幕轨道。
generatedbooleanoptional- 字幕是否通过 AI 生成。
labelstring- 向用户显示的原生语言标签。
languagestring- BCP 47 格式的语言标签。
status'ready' | 'inprogress' | 'error'optional- 生成字幕的状态。
具有下载类型键的对象。每个键均为可选,仅在该下载类型已创建时存在。
defaultStreamDownloadoptional- 默认视频下载。仅在该下载类型已创建时存在。请参阅 StreamDownload。
audioStreamDownloadoptional- 纯音频下载。仅在该下载类型已创建时存在。请参阅 StreamDownload。
表示视频的生成下载。
percentCompletenumber- 以 0 到 100 之间的百分比表示进度。
statusStreamDownloadStatus- 生成下载的状态。
urlstringoptional- 访问生成下载的 URL。
表示水印配置文件。
idstring- 水印配置文件的唯一标识符。
namestring- 水印配置文件的简短描述。
opacitynumber- 图像的透明度。
0.0使图像完全透明,1.0使图像完全不透明。请注意,如果图像本身已是半透明,将其设为1.0不会使其完全不透明。
- 图像的透明度。
paddingnumber- 相邻边缘(由 position 决定)与视频和图像之间的空白。
0.0表示无内边距,1.0表示内边距为完整视频宽度或长度。
- 相邻边缘(由 position 决定)与视频和图像之间的空白。
scalenumber- 图像相对于视频整体大小的大小。
0.0表示不缩放,1.0表示填满整个视频。
- 图像相对于视频整体大小的大小。
positionStreamWatermarkPosition- 图像位置。请参阅 StreamWatermarkPosition。
sizenumber- 图像大小(字节)。
heightnumber- 图像高度(像素)。
widthnumber- 图像宽度(像素)。
createdstring- 水印配置文件创建的日期和时间。
downloadedFromstring | null- 下载图像的源 URL。如果水印配置文件通过直接上传创建,此字段为
null。
- 下载图像的源 URL。如果水印配置文件通过直接上传创建,此字段为
水印在视频上的位置。
'upperRight' | 'upperLeft' | 'lowerLeft' | 'lowerRight' | 'center'
upperRight— 视频右上角。upperLeft— 视频左上角。lowerLeft— 视频左下角。lowerRight— 视频右下角。center— 视频中心。请注意center忽略padding参数。
生成下载的状态。
'ready' | 'inprogress' | 'error'
ready— 下载已就绪。inprogress— 下载正在生成。error— 生成过程中发生错误。
要生成的下载类型。
'default' | 'audio'
default— 视频下载。audio— 纯音频下载。
从 URL 上传视频的参数。
allowedOriginsArray<string>optional- 列出允许显示视频的来源。在数组中输入 allowed origin 域名,使用
*表示通配符子域名。空数组允许在任何来源观看视频。
- 列出允许显示视频的来源。在数组中输入 allowed origin 域名,使用
creatorstringoptional- 用户定义的媒体创作者标识符。
metaRecord<string, string>optional- 用户可修改的键值存储,用于引用其他记录系统以管理视频。
requireSignedURLsbooleanoptional- 指示是否可以使用 ID 访问视频。设为
true时,必须使用签名密钥生成 signed token 才能观看视频。
- 指示是否可以使用 ID 访问视频。设为
scheduledDeletionstring | nulloptional- 指示视频将被删除的日期和时间。省略该字段表示无更改,包含
null值可移除现有计划删除。如指定,必须至少为上传时间起 30 天后。
- 指示视频将被删除的日期和时间。省略该字段表示无更改,包含
thumbnailTimestampPctnumberoptional- 缩略图时间戳,计算为视频时长的百分比。要将秒级时间戳转换为百分比,将所需时间戳除以视频总时长。如未设置此值,默认缩略图取自视频 0 秒处。
watermarkIdstringoptional- 水印配置文件的标识符。
创建直接上传的参数。
maxDurationSecondsnumber- 视频上传的最大时长(秒)。
expirystringoptional- 上传后不再接受视频的日期和时间。
creatorstringoptional- 用户定义的媒体创作者标识符。
metaRecord<string, string>optional- 用户可修改的键值存储,用于引用其他记录系统以管理视频。
allowedOriginsArray<string>optional- 列出允许显示视频的来源。
requireSignedURLsbooleanoptional- 指示是否可以使用 ID 访问视频。设为
true时,必须使用签名密钥生成 signed token 才能观看视频。
- 指示是否可以使用 ID 访问视频。设为
thumbnailTimestampPctnumberoptional- 缩略图时间戳,计算为视频时长的百分比。
scheduledDeletionstring | nulloptional- 视频将被删除的日期和时间。包含
null可移除计划删除。
- 视频将被删除的日期和时间。包含
watermarkStreamDirectUploadWatermarkoptional- 要应用的水印配置文件。请参阅 StreamDirectUploadWatermark。
直接上传的水印配置。
idstring- 水印配置文件的唯一标识符。
更新视频的参数。
allowedOriginsArray<string>optional- 列出允许显示视频的来源。在数组中输入 allowed origin 域名,使用
*表示通配符子域名。空数组允许在任何来源观看视频。
- 列出允许显示视频的来源。在数组中输入 allowed origin 域名,使用
creatorstringoptional- 用户定义的媒体创作者标识符。
maxDurationSecondsnumberoptional- 视频上传的最大时长(秒)。可为尚未上传的视频设置以限制其时长。超过指定时长的上传将在处理过程中失败。
-1表示值未知。
- 视频上传的最大时长(秒)。可为尚未上传的视频设置以限制其时长。超过指定时长的上传将在处理过程中失败。
metaRecord<string, string>optional- 用户可修改的键值存储,用于引用其他记录系统以管理视频。
requireSignedURLsbooleanoptional- 指示是否可以使用 ID 访问视频。设为
true时,必须使用签名密钥生成 signed token 才能观看视频。
- 指示是否可以使用 ID 访问视频。设为
scheduledDeletionstring | nulloptional- 指示视频将被删除的日期和时间。省略该字段表示无更改,包含
null值可移除现有计划删除。如指定,必须至少为上传时间起 30 天后。
- 指示视频将被删除的日期和时间。省略该字段表示无更改,包含
thumbnailTimestampPctnumberoptional- 缩略图时间戳,计算为视频时长的百分比。要将秒级时间戳转换为百分比,将所需时间戳除以视频总时长。如未设置此值,默认缩略图取自视频 0 秒处。
列出视频的参数。
limitnumberoptional- 返回的最大视频数量。
beforestringoptional- 返回在此时间戳(RFC3339/RFC3339Nano)之前创建的视频。
beforeCompStreamPaginationComparisonoptionalbefore字段的比较运算符。默认为lt。请参阅 StreamPaginationComparison。
afterstringoptional- 返回在此时间戳(RFC3339/RFC3339Nano)之后创建的视频。
afterCompStreamPaginationComparisonoptionalafter字段的比较运算符。默认为gte。请参阅 StreamPaginationComparison。
分页查询的比较运算符。
'eq' | 'gt' | 'gte' | 'lt' | 'lte'
eq— 等于gt— 大于gte— 大于或等于lt— 小于lte— 小于或等于
创建水印配置文件的参数。
namestringoptional- 水印配置文件的简短描述。
opacitynumberoptional- 图像的透明度。
0.0使图像完全透明,1.0使图像完全不透明。请注意,如果图像本身已是半透明,将其设为1.0不会使其完全不透明。
- 图像的透明度。
paddingnumberoptional- 相邻边缘(由 position 决定)与视频和图像之间的空白。
0.0表示无内边距,1.0表示内边距为完整视频宽度或长度。
- 相邻边缘(由 position 决定)与视频和图像之间的空白。
scalenumberoptional- 图像相对于视频整体大小的大小。
0.0表示不缩放,1.0表示填满整个视频。
- 图像相对于视频整体大小的大小。
positionStreamWatermarkPositionoptional- 图像位置。请参阅 StreamWatermarkPosition。
错误抛出 StreamError,它扩展标准 Error 接口并提供额外信息:
code:数字错误代码。statusCode:HTTP 状态代码。message:错误描述。stack:可选堆栈跟踪。
可能抛出以下错误子类型:
| 错误类型 | 描述 |
|---|---|
InternalError |
发生内部服务器错误。 |
BadRequestError |
请求格式错误或包含无效参数。 |
NotFoundError |
未找到请求的资源。 |
ForbiddenError |
请求未授权。 |
RateLimitedError |
请求被速率限制。 |
QuotaReachedError |
账户已达到视频配额。 |
MaxFileSizeError |
上传文件超过允许的最大大小。 |
InvalidURLError |
提供的 URL 无效或无法访问。 |
AlreadyUploadedError |
视频已上传。 |
TooManyWatermarksError |
账户已达到水印配置文件限制。 |
使用 try...catch 块处理错误:
export default {
async fetch(request, env) {
try {
const videoDetails = await env.STREAM.upload(
"https://example.com/video.mp4",
);
return Response.json(videoDetails);
} catch (e) {
if (e instanceof Error) {
return new Response(`Stream error: ${e.message}`, { status: 500 });
}
throw e;
}
},
};export default {
async fetch(request, env) {
try {
const videoDetails = await env.STREAM.upload("https://example.com/video.mp4");
return Response.json(videoDetails);
} catch (e) {
if (e instanceof Error) {
return new Response(`Stream error: ${e.message}`, { status: 500 });
}
throw e;
}
},
};