将视频上传到 Stream 后,可以使用 HLS/DASH 进行流式传输。但是,对于某些用例,您可能希望下载 MP4 或 M4A 文件。 例如,对于离线观看,您可能希望下载 MP4 文件。而对于 AI 摘要等下游任务,如果只想提取音频,下载 M4A 文件可能更有用。
您可以按照以下步骤为每个视频启用 MP4 支持:
- 向
/downloads或/downloads/default端点发送 POST 请求以启用 MP4 支持。 - 保存端点响应提供的 MP4 URL。当下一步中 MP4 准备就绪时,此 MP4 URL 将可用。
- 轮询
/downloads端点,直到status字段设为ready,以通知您 MP4 何时可用。现在可以使用步骤 2 中的 MP4 URL。
视频上传并可供观看后,您可以向 /downloads 或 /downloads/default 端点发送 HTTP 请求以启用下载。
要获取视频可供观看的通知,请参阅使用 webhook。
curl -X POST \
-H "Authorization: Bearer <API_TOKEN>" \
https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/stream/<VIDEO_UID>/downloadsconst client = new Cloudflare({
apiEmail: process.env['CLOUDFLARE_EMAIL'],
apiKey: process.env['CLOUDFLARE_API_KEY'],
});
const download = await client.stream.downloads.create({
account_id: '<ACCOUNT_ID>',
identifier: '<VIDEO_UID>',
});响应包括下载类型、URL 和处理状态:
{
"result": {
"default": {
"status": "inprogress",
"url": "https://customer-<CODE>.cloudflarestream.com/<VIDEO_UID>/downloads/default.mp4",
"percentComplete": 75.0
}
},
"success": true,
"errors": [],
"messages": []
}请参阅完整的 Stream REST API 和 SDK 参考,了解如何从外部应用程序使用 REST API,以及适用于外部 TypeScript、Python 或 Go 应用的预生成 SDK。
export default {
async fetch(request, env) {
const videoHandle = env.STREAM.video("VIDEO_ID");
const downloads = await videoHandle.downloads.generate();
return Response.json(downloads);
},
};{
"$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 绑定 API 参考。
要为每个视频启用 M4A 支持,请按照与生成 MP4 下载类似的步骤,但向 /downloads/audio 端点发送 POST 请求。
curl -X POST \
-H "Authorization: Bearer <API_TOKEN>" \
https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/stream/<VIDEO_UID>/downloads/audioconst client = new Cloudflare({
apiEmail: process.env['CLOUDFLARE_EMAIL'],
apiKey: process.env['CLOUDFLARE_API_KEY'],
});
const download = await client.stream.downloads.audio.create({
account_id: '<ACCOUNT_ID>',
identifier: '<VIDEO_UID>',
});响应包括下载类型、URL 和处理状态:
{
"result": {
"audio": {
"status": "inprogress",
"url": "https://customer-<CODE>.cloudflarestream.com/<VIDEO_UID>/downloads/audio.m4a",
"percentComplete": 75.0
}
},
"success": true,
"errors": [],
"messages": []
}请参阅完整的 Stream REST API 和 SDK 参考,了解如何从外部应用程序使用 REST API,以及适用于外部 TypeScript、Python 或 Go 应用的预生成 SDK。
export default {
async fetch(request, env) {
const videoHandle = env.STREAM.video("VIDEO_ID");
const downloads = await videoHandle.downloads.generate("audio");
return Response.json(downloads);
},
};{
"$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 绑定 API 参考。
您可以向 downloads API 发送 GET HTTP 请求,查看视频的所有可用下载。
curl -X GET \
-H "Authorization: Bearer <API_TOKEN>" \
https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/stream/<VIDEO_UID>/downloadsconst client = new Cloudflare({
apiEmail: process.env['CLOUDFLARE_EMAIL'],
apiKey: process.env['CLOUDFLARE_API_KEY'],
});
const downloads = await client.stream.downloads.get({
account_id: '<ACCOUNT_ID>',
identifier: '<VIDEO_UID>',
});{
"result": {
"audio": {
"status": "ready",
"url": "https://customer-<CODE>.cloudflarestream.com/<VIDEO_UID>/downloads/audio.m4a",
"percentComplete": 100.0
}
"default": {
"status": "ready",
"url": "https://customer-<CODE>.cloudflarestream.com/<VIDEO_UID>/downloads/default.mp4",
"percentComplete": 100.0
}
},
"success": true,
"errors": [],
"messages": []
}请参阅完整的 Stream REST API 和 SDK 参考,了解如何从外部应用程序使用 REST API,以及适用于外部 TypeScript、Python 或 Go 应用的预生成 SDK。
export default {
async fetch(request, env) {
const videoHandle = env.STREAM.video("VIDEO_ID");
const downloads = await videoHandle.downloads.get();
return Response.json(downloads);
},
};{
"$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 绑定 API 参考。
您可以在 URL 末尾添加 filename 查询字符串参数来自定义可下载文件的名称。
在以下示例中,在 URL 末尾添加 ?filename=MY_VIDEO.mp4 会将文件名更改为 MY_VIDEO.mp4。
https://customer-<CODE>.cloudflarestream.com/<VIDEO_UID>/downloads/default.mp4?filename=MY_VIDEO.mp4
filename 最长 120 个字符,由 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_ 字符组成。扩展名(.mp4)会自动追加。
生成的 MP4 下载文件可通过 download API 响应中的链接检索。
curl -L https://customer-<CODE>.cloudflarestream.com/<VIDEO_UID>/downloads/default.mp4 > download.mp4您可以删除视频的下载。可用类型为 default 和 audio。省略时默认为 default。
curl -X DELETE \
-H "Authorization: Bearer <API_TOKEN>" \
https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/stream/<VIDEO_UID>/downloads/defaultconst client = new Cloudflare({
apiEmail: process.env['CLOUDFLARE_EMAIL'],
apiKey: process.env['CLOUDFLARE_API_KEY'],
});
await client.stream.downloads.default.delete({
account_id: '<ACCOUNT_ID>',
identifier: '<VIDEO_UID>',
});请参阅完整的 Stream REST API 和 SDK 参考,了解如何从外部应用程序使用 REST API,以及适用于外部 TypeScript、Python 或 Go 应用的预生成 SDK。
export default {
async fetch(request, env) {
const videoHandle = env.STREAM.video("VIDEO_ID");
await videoHandle.downloads.delete();
return new Response("Download deleted", { status: 200 });
},
};{
"$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 绑定 API 参考。
如果您的视频是公开的,MP4 也将公开可访问。如果您的视频是私有的且需要签名 URL 才能观看,MP4 将不可公开访问。要访问私有视频的 MP4,您可以生成签名 URL,方式与常规观看相同,但需额外设置名为 downloadable 的标志为 true。
您可以使用 Stream 绑定生成签名 token:
export default {
async fetch(request, env) {
const token = await env.STREAM.video("VIDEO_ID").generateToken();
return Response.json({ token });
},
};如果 token 中不存在 downloadable 标志,需要签名 URL 的视频的下载链接将无法使用。
有关对视频使用签名 URL 的更多详情,请参阅保护您的 Stream。
Token payload 示例
{
"sub": <VIDEO_UID>,
"kid": <KEY_ID>,
"exp": 1537460365,
"nbf": 1537453165,
"downloadable": true,
"accessRules": [
{
"type": "ip.geoip.country",
"action": "allow",
"country": [
"GB"
]
},
{
"type": "any",
"action": "block"
}
]
}MP4 下载的计费方式与视频流式传输相同。每次下载视频的 MP4 时,您将按视频时长计费。例如,如果您有一个 10 分钟的视频在当月被下载 100 次,下载将计为 1000 分钟的分发量。
启用 MP4 不会产生额外的存储费用。