跳转到内容
搜索文档

下载视频或音频

最后更新 查看 MarkdownAgent 设置

将视频上传到 Stream 后,可以使用 HLS/DASH 进行流式传输。但是,对于某些用例,您可能希望下载 MP4 或 M4A 文件。 例如,对于离线观看,您可能希望下载 MP4 文件。而对于 AI 摘要等下游任务,如果只想提取音频,下载 M4A 文件可能更有用。

生成可下载的 MP4 文件

您可以按照以下步骤为每个视频启用 MP4 支持:

  1. /downloads/downloads/default 端点发送 POST 请求以启用 MP4 支持。
  2. 保存端点响应提供的 MP4 URL。当下一步中 MP4 准备就绪时,此 MP4 URL 将可用。
  3. 轮询 /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>/downloads
const 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 文件

要为每个视频启用 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/audio
const 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>/downloads
const 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>',
});
响应json
{
	"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

删除下载

您可以删除视频的下载。可用类型为 defaultaudio。省略时默认为 default

curl -X DELETE \
-H "Authorization: Bearer <API_TOKEN>" \
https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/stream/<VIDEO_UID>/downloads/default
const 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 下载的计费方式与视频流式传输相同。每次下载视频的 MP4 时,您将按视频时长计费。例如,如果您有一个 10 分钟的视频在当月被下载 100 次,下载将计为 1000 分钟的分发量。

启用 MP4 不会产生额外的存储费用。

这篇文档对您有帮助吗?