← Cloudflare Stream / stream / edit-videos
Применение водяных знаков
Вы можете добавлять водяные знаки к видео, загруженным через Stream API.
Чтобы добавлять водяные знаки на видео, сначала создайте профиль водяного знака. Профиль водяного знака описывает изображение, которое будет использоваться как водяной знак, и его положение. После создания профиля вы сможете указывать его как параметр при загрузке видео.
быстрый старт
Профиль водяного знака поддерживает множество настраиваемых параметров. Однако в большинстве случаев параметры по умолчанию отлично подходят. Подробнее см. раздел «Profiles» ниже.
Шаг 1: Создайте профиль
curl -X POST -H 'Authorization: Bearer <API_TOKEN>' \
-F file=@/Users/rchen/cloudflare.png \
https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/stream/watermarksconst client = new Cloudflare({
apiEmail: process.env['CLOUDFLARE_EMAIL'],
apiKey: process.env['CLOUDFLARE_API_KEY'],
});
const watermark = await client.stream.watermarks.create({
account_id: '<ACCOUNT_ID>',
file: '@/path/to/image.png',
name: 'marketing videos',
});Ознакомьтесь с полным Stream Справочник REST API и SDK для получения сведений об использовании REST API из внешних приложений: для TypeScript, Python и Go предусмотрены готовые SDK.
export default {
async fetch(request, env, ctx): Promise<Response> {
const response = await fetch("https://example.com/cloudflare.png");
const readableStream = response.body!;
const watermark = await env.STREAM.watermarks.generate(readableStream, {
name: "marketing videos",
});
return new Response(JSON.stringify({ watermark }));
},
} satisfies ExportedHandler<{ STREAM: StreamBinding }>;{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "<ENTER_WORKER_NAME>",
"main": "src/index.ts",
"compatibility_date": "$today",
"observability": {
"enabled": true
},
"stream": {
"binding": "STREAM"
}
}Ознакомьтесь с полным Справочник API привязки Workers Stream.
Шаг 2: Укажите UID профиля при загрузке
tus-upload --chunk-size 5242880 \
--header Authentication 'Bearer <API_TOKEN>' \
--metadata watermark <WATERMARK_UID> \
/Users/rchen/cat.mp4 https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/streamconst client = new Cloudflare({
apiEmail: process.env['CLOUDFLARE_EMAIL'],
apiKey: process.env['CLOUDFLARE_API_KEY'],
});
const video = await client.stream.copy.create({
account_id: '<ACCOUNT_ID>',
url: 'https://example.com/video.mp4',
watermark: { uid: '<WATERMARK_UID>' },
});Ознакомьтесь с полным Stream Справочник REST API и SDK для получения сведений об использовании REST API из внешних приложений: для TypeScript, Python и Go предусмотрены готовые SDK.
export default {
async fetch(request, env, ctx): Promise<Response> {
const video = await env.STREAM.upload(
"https://example.com/video.mp4",
{ watermarkId: "<WATERMARK_UID>" },
);
return new Response(JSON.stringify({ video }));
},
} satisfies ExportedHandler<{ STREAM: StreamBinding }>;{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "<ENTER_WORKER_NAME>",
"main": "src/index.ts",
"compatibility_date": "$today",
"observability": {
"enabled": true
},
"stream": {
"binding": "STREAM"
}
}Ознакомьтесь с полным Справочник API привязки Workers Stream.
Шаг 3: Готово
Профили
Чтобы создавать, просматривать список, удалять профили или получать о них информацию, вам потребуется ваш API-токен Cloudflare ↗.
Необязательные параметры
-
nameстрока по умолчанию: пустая строка- Краткое описание профиля. Например, «маркетинговые видео».
-
opacityfloat по умолчанию: 1.0- Прозрачность водяного знака. Значение 0.0 означает полную прозрачность, а значение 1.0 означает полную непрозрачность. Обратите внимание, что если водяной знак уже полупрозрачен, установка значения 1.0 не сделает его полностью непрозрачным.
-
paddingfloat по умолчанию: 0.05-
Отступ между смежными краями видео и водяного знака (определяется параметром position). Значение 0.0 означает отсутствие отступа, а 1.0 соответствует отступу на всю ширину или длину видео.
-
Stream следит за тем, чтобы водяной знак оставался примерно на одной и той же позиции на видео с разными размерами.
-
-
scalefloat по умолчанию: 0.15-
Размер водяного знака относительно общего размера видео. Этот параметр автоматически подстраивается под горизонтальные и вертикальные видео. Значение 0.0 означает отсутствие масштабирования (используется исходный размер водяного знака), а значение 1.0 заполняет всё видео.
-
Алгоритм следит за тем, чтобы водяной знак выглядел примерно одного размера на видео с разными пропорциями кадра.
-
-
positionстрока (enum) по умолчанию: "upperRight"-
Расположение водяного знака. Допустимые значения:
upperRight,upperLeft,lowerLeft,lowerRight, а такжеcenter.
-
Создание профиля водяного знака
Сценарий использования 1: прямая загрузка локального файла изображения
Чтобы загрузить изображение напрямую, отправьте запрос POST с помощью multipart/form-data в качестве content-type и указать файл в file ключ. Все остальные поля необязательны.
curl -X POST -H "Authorization: Bearer <API_TOKEN>" \
-F file=@{path-to-image-locally} \
-F name='marketing videos' \
-F opacity=1.0 \
-F padding=0.05 \
-F scale=0.15 \
-F position=upperRight \
https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/stream/watermarksconst client = new Cloudflare({
apiEmail: process.env['CLOUDFLARE_EMAIL'],
apiKey: process.env['CLOUDFLARE_API_KEY'],
});
const watermark = await client.stream.watermarks.create({
account_id: '<ACCOUNT_ID>',
file: '@/path/to/image.png',
name: 'marketing videos',
opacity: 1.0,
padding: 0.05,
scale: 0.15,
position: 'upperRight',
});Ознакомьтесь с полным Stream Справочник REST API и SDK для получения сведений об использовании REST API из внешних приложений: для TypeScript, Python и Go предусмотрены готовые SDK.
export default {
async fetch(request, env, ctx): Promise<Response> {
const response = await fetch("https://example.com/cloudflare.png");
const readableStream = response.body!;
const watermark = await env.STREAM.watermarks.generate(readableStream, {
name: "marketing videos",
opacity: 1.0,
padding: 0.05,
scale: 0.15,
position: "upperRight",
});
return new Response(JSON.stringify({ watermark }));
},
} satisfies ExportedHandler<{ STREAM: StreamBinding }>;{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "<ENTER_WORKER_NAME>",
"main": "src/index.ts",
"compatibility_date": "$today",
"observability": {
"enabled": true
},
"stream": {
"binding": "STREAM"
}
}Ознакомьтесь с полным Справочник API привязки Workers Stream.
Сценарий использования 2: передача URL-адреса изображения
Чтобы указать URL для загрузки, отправьте запрос POST с помощью application/json в качестве content-type и указать расположение файла с помощью url ключ. Все остальные поля необязательны.
export default {
async fetch(request, env, ctx): Promise<Response> {
const watermark = await env.STREAM.watermarks.generate(
"https://example.com/logo.png",
{
name: "marketing videos",
opacity: 1.0,
padding: 0.05,
scale: 0.15,
position: "upperRight",
},
);
return new Response(JSON.stringify({ watermark }));
},
} satisfies ExportedHandler<{ STREAM: StreamBinding }>;{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "<ENTER_WORKER_NAME>",
"main": "src/index.ts",
"compatibility_date": "$today",
"observability": {
"enabled": true
},
"stream": {
"binding": "STREAM"
}
}Ознакомьтесь с полным Справочник API привязки Workers Stream.
curl -X POST -H "Authorization: Bearer <API_TOKEN>" \
-H 'Content-Type: application/json' \
-d '{
"url": "{url-to-image}",
"name": "marketing videos",
"opacity": 1.0,
"padding": 0.05,
"scale": 0.15,
"position": "upperRight"
}' \
https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/stream/watermarksconst client = new Cloudflare({
apiEmail: process.env['CLOUDFLARE_EMAIL'],
apiKey: process.env['CLOUDFLARE_API_KEY'],
});
// The TypeScript SDK does not support URL-based watermark creation.
// Use the file-based approach instead:
const watermark = await client.stream.watermarks.create({
account_id: '<ACCOUNT_ID>',
file: '@/path/to/image.png',
name: 'marketing videos',
opacity: 1.0,
padding: 0.05,
scale: 0.15,
position: 'upperRight',
});Ознакомьтесь с полным Stream Справочник REST API и SDK для получения сведений об использовании REST API из внешних приложений: для TypeScript, Python и Go предусмотрены готовые SDK.
Пример ответа при создании профиля водяного знака
{
"result": {
"uid": "d6373709b7681caa6c48ef2d8c73690d",
"size": 11248,
"height": 240,
"width": 720,
"created": "2020-07-29T00:16:55.719265Z",
"downloadedFrom": null,
"name": "marketing videos",
"opacity": 1.0,
"padding": 0.05,
"scale": 0.15,
"position": "upperRight"
},
"success": true,
"errors": [],
"messages": []
}downloadedFrom будет заполнено, если профиль был создан путём загрузки по URL.
Использование профиля водяного знака в видео
После создания профиля водяного знака вы можете использовать его при загрузке видео для нанесения знака.
Простая загрузка
К сожалению, Stream пока не позволяет указывать профиль водяного знака при загрузке через Basic Uploads.
Загрузка видео по ссылке
export default {
async fetch(request, env, ctx): Promise<Response> {
const video = await env.STREAM.upload(
"https://example.com/video.mp4",
{ watermarkId: "<WATERMARK_UID>" },
);
return new Response(JSON.stringify({ video }));
},
} satisfies ExportedHandler<{ STREAM: StreamBinding }>;{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "<ENTER_WORKER_NAME>",
"main": "src/index.ts",
"compatibility_date": "$today",
"observability": {
"enabled": true
},
"stream": {
"binding": "STREAM"
}
}Ознакомьтесь с полным Справочник API привязки Workers Stream.
curl -X POST -H "Authorization: Bearer <API_TOKEN>" \
-H 'Content-Type: application/json' \
-d '{
"url": "{url-to-video}",
"watermark": {
"uid": "<WATERMARK_UID>"
}
}' \
https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/stream/copyconst client = new Cloudflare({
apiEmail: process.env['CLOUDFLARE_EMAIL'],
apiKey: process.env['CLOUDFLARE_API_KEY'],
});
const video = await client.stream.copy.create({
account_id: '<ACCOUNT_ID>',
url: 'https://example.com/video.mp4',
watermark: { uid: '<WATERMARK_UID>' },
});Ознакомьтесь с полным Stream Справочник REST API и SDK для получения сведений об использовании REST API из внешних приложений: для TypeScript, Python и Go предусмотрены готовые SDK.
Пример ответа при загрузке видео по ссылке
{
"result": {
"uid": "8d3a5b80e7437047a0fb2761e0f7a645",
"thumbnail": "https://customer-f33zs165nr7gyfy4.cloudflarestream.com/6b9e68b07dfee8cc2d116e4c51d6a957/thumbnails/thumbnail.jpg",
"playback": {
"hls": "https://customer-f33zs165nr7gyfy4.cloudflarestream.com/6b9e68b07dfee8cc2d116e4c51d6a957/manifest/video.m3u8",
"dash": "https://customer-f33zs165nr7gyfy4.cloudflarestream.com/6b9e68b07dfee8cc2d116e4c51d6a957/manifest/video.mpd"
},
"watermark": {
"uid": "d6373709b7681caa6c48ef2d8c73690d",
"size": 11248,
"height": 240,
"width": 720,
"created": "2020-07-29T00:16:55.719265Z",
"downloadedFrom": null,
"name": "marketing videos",
"opacity": 1.0,
"padding": 0.05,
"scale": 0.15,
"position": "upperRight"
}
}Загрузка видео с помощью tus
tus-upload --chunk-size 5242880 \
--header Authentication 'Bearer <API_TOKEN>' \
--metadata watermark <WATERMARK_UID> \
<PATH_TO_VIDEO> https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/streamDirect Creator Uploads
Видео, загруженное по сгенерированному уникальному одноразовому URL, будет помечено водяным знаком согласно указанному профилю.
export default {
async fetch(request, env, ctx): Promise<Response> {
const directUpload = await env.STREAM.createDirectUpload({
maxDurationSeconds: 3600,
watermark: { id: "<WATERMARK_UID>" },
});
return new Response(JSON.stringify({ directUpload }));
},
} satisfies ExportedHandler<{ STREAM: StreamBinding }>;{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "<ENTER_WORKER_NAME>",
"main": "src/index.ts",
"compatibility_date": "$today",
"observability": {
"enabled": true
},
"stream": {
"binding": "STREAM"
}
}Ознакомьтесь с полным Справочник API привязки Workers Stream.
curl -X POST -H "Authorization: Bearer <API_TOKEN>" \
-H 'Content-Type: application/json' \
-d '{
"maxDurationSeconds": 3600,
"watermark": {
"uid": "<WATERMARK_UID>"
}
}' \
https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/stream/direct_uploadconst client = new Cloudflare({
apiEmail: process.env['CLOUDFLARE_EMAIL'],
apiKey: process.env['CLOUDFLARE_API_KEY'],
});
const directUpload = await client.stream.directUpload.create({
account_id: '<ACCOUNT_ID>',
maxDurationSeconds: 3600,
watermark: { uid: '<WATERMARK_UID>' },
});Ознакомьтесь с полным Stream Справочник REST API и SDK для получения сведений об использовании REST API из внешних приложений: для TypeScript, Python и Go предусмотрены готовые SDK.
Пример ответа при прямой загрузке пользователем
{
"result": {
"uploadURL": "https://upload.videodelivery.net/c32d98dd671e4046a33183cd5b93682b",
"uid": "c32d98dd671e4046a33183cd5b93682b",
"watermark": {
"uid": "d6373709b7681caa6c48ef2d8c73690d",
"size": 11248,
"height": 240,
"width": 720,
"created": "2020-07-29T00:16:55.719265Z",
"downloadedFrom": null,
"name": "marketing videos",
"opacity": 1.0,
"padding": 0.05,
"scale": 0.15,
"position": "upperRight"
}
},
"success": true,
"errors": [],
"messages": []
}watermark будет null если водяной знак не был указан.
Получение профиля водяного знака
Чтобы просмотреть созданный вами профиль водяного знака:
export default {
async fetch(request, env, ctx): Promise<Response> {
const watermark = await env.STREAM.watermarks.get("<WATERMARK_UID>");
return new Response(JSON.stringify({ watermark }));
},
} satisfies ExportedHandler<{ STREAM: StreamBinding }>;{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "<ENTER_WORKER_NAME>",
"main": "src/index.ts",
"compatibility_date": "$today",
"observability": {
"enabled": true
},
"stream": {
"binding": "STREAM"
}
}Ознакомьтесь с полным Справочник API привязки Workers Stream.
curl -H "Authorization: Bearer <API_TOKEN>" \
https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/stream/watermarks/<WATERMARK_UID>const client = new Cloudflare({
apiEmail: process.env['CLOUDFLARE_EMAIL'],
apiKey: process.env['CLOUDFLARE_API_KEY'],
});
const watermark = await client.stream.watermarks.get(
'<WATERMARK_UID>',
{ account_id: '<ACCOUNT_ID>' },
);Ознакомьтесь с полным Stream Справочник REST API и SDK для получения сведений об использовании REST API из внешних приложений: для TypeScript, Python и Go предусмотрены готовые SDK.
Пример ответа при получении профиля водяного знака
{
"result": {
"uid": "d6373709b7681caa6c48ef2d8c73690d",
"size": 11248,
"height": 240,
"width": 720,
"created": "2020-07-29T00:16:55.719265Z",
"downloadedFrom": null,
"name": "marketing videos",
"opacity": 1.0,
"padding": 0.05,
"scale": 0.15,
"position": "center"
},
"success": true,
"errors": [],
"messages": []
}Список профилей водяных знаков
Чтобы просмотреть список созданных вами профилей водяных знаков:
export default {
async fetch(request, env, ctx): Promise<Response> {
const watermarks = await env.STREAM.watermarks.list();
return new Response(JSON.stringify({ watermarks }));
},
} satisfies ExportedHandler<{ STREAM: StreamBinding }>;{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "<ENTER_WORKER_NAME>",
"main": "src/index.ts",
"compatibility_date": "$today",
"observability": {
"enabled": true
},
"stream": {
"binding": "STREAM"
}
}Ознакомьтесь с полным Справочник API привязки Workers Stream.
curl -H "Authorization: Bearer <API_TOKEN>" \
https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/stream/watermarks/const client = new Cloudflare({
apiEmail: process.env['CLOUDFLARE_EMAIL'],
apiKey: process.env['CLOUDFLARE_API_KEY'],
});
const watermarks = await client.stream.watermarks.list({
account_id: '<ACCOUNT_ID>',
});Ознакомьтесь с полным Stream Справочник REST API и SDK для получения сведений об использовании REST API из внешних приложений: для TypeScript, Python и Go предусмотрены готовые SDK.
Пример ответа при получении списка профилей водяных знаков
{
"result": [
{
"uid": "9de16afa676d64faaa7c6c4d5047e637",
"size": 207710,
"height": 626,
"width": 1108,
"created": "2020-07-29T00:23:35.918472Z",
"downloadedFrom": null,
"name": "marketing videos",
"opacity": 1.0,
"padding": 0.05,
"scale": 0.15,
"position": "upperLeft"
},
{
"uid": "9c50cff5ab16c4aec0bcb03c44e28119",
"size": 207710,
"height": 626,
"width": 1108,
"created": "2020-07-29T00:16:46.735377Z",
"downloadedFrom": "https://company.com/logo.png",
"name": "internal training videos",
"opacity": 1.0,
"padding": 0.05,
"scale": 0.15,
"position": "center"
}
],
"success": true,
"errors": [],
"messages": []
}Удаление профиля водяного знака
Чтобы удалить созданный вами профиль водяного знака:
export default {
async fetch(request, env, ctx): Promise<Response> {
await env.STREAM.watermarks.delete("<WATERMARK_UID>");
return new Response(JSON.stringify({ success: true }));
},
} satisfies ExportedHandler<{ STREAM: StreamBinding }>;{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "<ENTER_WORKER_NAME>",
"main": "src/index.ts",
"compatibility_date": "$today",
"observability": {
"enabled": true
},
"stream": {
"binding": "STREAM"
}
}Ознакомьтесь с полным Справочник API привязки Workers Stream.
curl -X DELETE -H 'Authorization: Bearer <API_TOKEN>' \
https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/stream/watermarks/<WATERMARK_UID>const client = new Cloudflare({
apiEmail: process.env['CLOUDFLARE_EMAIL'],
apiKey: process.env['CLOUDFLARE_API_KEY'],
});
await client.stream.watermarks.delete(
'<WATERMARK_UID>',
{ account_id: '<ACCOUNT_ID>' },
);Ознакомьтесь с полным Stream Справочник REST API и SDK для получения сведений об использовании REST API из внешних приложений: для TypeScript, Python и Go предусмотрены готовые SDK.
Если операция выполнена успешно, будет возвращен ответ об успешном выполнении:
{
"result": "",
"success": true,
"errors": [],
"messages": []
}Ограничения
- После создания профиля водяного знака изменить его параметры нельзя. Если нужно отредактировать профиль, удалите его и создайте новый.
- После наложения водяного знака на видео изменить его можно только повторной загрузкой видео с другим профилем.
- После наложения водяного знака на видео удаление профиля водяного знака не удалит сам знак с видео.
- Максимальный размер файла составляет 2 МиБ (2097152 байт), поддерживаются только файлы PNG.