> This page is for С камеры в облако.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://next.developer.frame.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://next.developer.frame.io/_mcp/server.

# Практическое руководство: добавление (базовое)

## Введение





Мы достигли важного этапа в нашем процессе интеграции: добавление ресурсов в Frame.io. Это руководство поможет вам пройти через базовый процесс добавления.





## Требования

Если вы еще не сделали этого, просмотрите руководство [Реализация C2C: настройка](./implementing-c2c-setting-up) перед продолжением. Вам понадобится `access_token`, полученный [в процессе аутентификации и авторизации](./implementing-c2c-authentication-and-authorization). Для этого руководства мы используем образец тестового ресурса, доступный по [этой ссылке Frame.io](https://f.io/Rq1q5CzB). Загрузите этот файл, чтобы следовать нашим примерам, поскольку это позволит вам сопоставить значения в наших образцах команд.

## Шаг 1. Создание ресурса

Добавим [наш образец файла](https://f.io/Rq1q5CzB), который, как мы предполагаем, создан 10 секунд назад. Сначала нам нужно создать ссылку на ресурс в Frame.io:

```shell
{
curl -X POST https://api.frame.io/v2/devices/assets \
    --header 'Authorization: Bearer [access_token]' \
    --header 'Content-Type: application/json' \
    --header 'x-client-version: 2.0.0' \
    --data-binary @- <<'__JSON__' 
        {
            "name": "C2C_TEST_CLIP.mp4", 
            "filetype": "video/mp4", 
            "filesize": 21136250,
            "offset": 10
        }
__JSON__
} | python -m json.tool
```




<Info title="Спецификация конечной точки API-интерфейса">
  Документацию для `/v2/devices/assets` можно [найти здесь](/camera-to-cloud/api-reference/device-asset-create). Хотя устаревшая конечная точка `/v2/assets` все еще функционирует, для новых интеграций мы рекомендуем использовать `/v2/devices/assets`.
</Info>

<Info title="Кодирование JSON">
  В отличие от конечных точек аутентификации, которые мы использовали ранее, эта конечная точка принимает кодирование `application/json`, а не `form/multipart`. Она также принимает `application/x-www-form-urlencoded`.
</Info>

<Info title="Синтаксис команды">
  В этом примере используется [heredoc](https://linuxize.com/post/bash-heredoc/) для предоставления `curl` полезной нагрузки JSON в удобном для чтения многострочном формате. Параметр `--data-binary @-` указывает `curl` читать необработанные данные из stdin. Подробнее об этом методе [здесь](https://unix.stackexchange.com/questions/88490/how-do-you-use-output-redirection-in-combination-with-here-documents-and-cat).
</Info>


Рассмотрим параметры полезной нагрузки JSON:

`имя`: отображаемое имя ресурса в Frame.io. Оно не должно совпадать с именем файла на диске. `filetype`: тип файла [MIME](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types). Большинство языков программирования предоставляют утилиты для определения типа MIME (примеры: [Go](https://golangcode.com/get-the-content-type-of-file/), [Python](https://docs.python.org/3/library/mimetypes.html)). `filesize`: размер файла в байтах. Размер нашего образца файла приблизительно 21,1 МБ. `offset`: количество секунд с момента создания файла. По умолчанию 0, если не указано. Этот параметр должен быть предоставлен, поскольку он помогает определить, следует ли отклонить файлы из-за приостановки устройства. Мы рассмотрим это более подробно в [расширенном руководстве по добавлению](./how-to-advanced-uploads).

Ответ будет выглядеть примерно так (некоторые поля опущены):





```json
{
    "_type": "file",
    ...
    "id": "9a280f99-8f4f-46b0-a4b4-ec4c2f95138e",
    ...
    "upload_urls": [
        "https://frameio-uploads-production.s3-accelerate.amazonaws.com/parts/[part_01_path]",
        "https://frameio-uploads-production.s3-accelerate.amazonaws.com/parts/[part_02_path]"
    ],
    ...
}
```





На данном этапе мы только уведомили Frame.io о нашем намерении добавить файл; никакие фактические данные файла не были переданы. Если вы проверите папку вашего устройства в проекте, то увидите заполнитель ресурса в состоянии «добавление».

Поле `upload_urls` содержит URL-адреса, по которым мы будем добавлять фрагменты нашего файла. Для нашего тестового файла мы должны получить два URL-адреса добавления.

## Шаг 2. Разделение файла на фрагменты





Ответ содержал несколько URL-адресов добавления. При добавлении в Frame.io мы разделяем файлы на фрагменты и добавляем их отдельно, что дает несколько преимуществ:




* **Улучшенная надежность**: если один фрагмент не добавляется, нам не нужно перезапускать весь процесс добавления.
* **Более быстрые операции добавления**: мы можем добавлять несколько фрагментов параллельно (рассматривается в [руководстве по расширенным добавлениям](./how-to-advanced-uploads))




Чтобы определить оптимальный размер фрагмента, используйте эту формулу:





**`Python`**

```python title="Python"
# We use math.ceil() to ensure we get the upper bound in the division
chunk_size = math.ceil(float(file.size) / float(len(response.upload_urls)))
```





Для нашего образца файла расчет выглядит так:





**`Python`**

```python title="Python"
math.ceil(21136250 / 2)
# 10568125
```

Это означает, что каждый фрагмент должен быть 10 568 125 байтов. Размеры фрагментов обычно составляют около 25 МБ, точные расчеты рассматриваются в [руководстве по расширенным операциям добавления](./how-to-advanced-uploads).
<Info title="Размер последнего фрагмента">
  Поскольку размеры файлов редко делятся нацело, конечный фрагмент может быть меньше вычисленного `chunk_size`. Реализация должна учитывать это при чтении фрагментов файла.
</Info>
 Для этой демонстрации мы будем использовать команды [head](https://man7.org/linux/man-pages/man1/head.1.html) и [tail](https://man7.org/linux/man-pages/man1/tail.1.html), чтобы извлекать фрагменты файла.

## Шаг 3. Добавление фрагментов





Добавление первого фрагмента:





```shell
head -c 10568125 ~/Downloads/C2C_TEST_CLIP.mp4 | \
curl -X PUT https://frameio-uploads-production.s3-accelerate.amazonaws.com/parts/[part_01_path] \
        --include \
        --header 'content-type: video/mp4' \
        --header 'x-amz-acl: private' \
        --data-binary @-
```




<Info title="Синтаксис команды">
  Параметр `--data-binary @-` указывает `curl` использовать необработанные данные из stdin, которые поступают от команды `head`.
</Info>


Запрос требует следующих заголовков:

`content-type`: то же значение типа MIME, которое использовалось при создании ресурса `x-amz-acl`. Для разрешений AWS S3 всегда задавайте значение `частный`

Если добавление выполнено, возвращается:





```text
HTTP/1.1 100 Continue

HTTP/1.1 200 OK
...
```





Таким же способом добавьте второй фрагмент:





```shell
tail -c 10568125 ~/Downloads/C2C_TEST_CLIP.mp4 | \
curl -X PUT https://frameio-uploads-production.s3-accelerate.amazonaws.com/parts/[part_02_path] \
        --include \
        --header 'content-type: video/mp4' \
        --header 'x-amz-acl: private' \
        --data-binary @-
```





После выполнения обеих операций добавления ваш ресурс должен воспроизводиться в Frame.io! 🎉




<Warning title="Ошибки добавления">
  При добавлении фрагментов вы отправляете данные напрямую в AWS S3, а не в API-интерфейсе Frame.io. Ответы об ошибках будут следовать форматам AWS S3, а не стандартным ошибкам Frame.io. Мы рассмотрим обработку ошибок S3 в [руководстве по обработке ошибок](/camera-to-cloud/how-to-handle-errors).
</Warning>

<Info title="Порядок фрагментов">
  


Хотя концептуально проще добавлять фрагменты последовательно, на самом деле их можно добавлять в любом порядке. Система соберет их правильно независимо от последовательности добавления.



</Info>


## Объединение





Вот упрощенный пример псевдокода на Python для полного процесса добавления:





**`Python`**

```python title="Python"
file = open("~/Downloads/C2C_TEST_CLIP.mp4")
mimetype = mimetypes.for_file("~/Downloads/C2C_TEST_CLIP.mp4")[0]
created_at = time.ctime(file.stat.ST_CTIME)

asset = c2c.asset_create(
    name="C2C_TEST_CLIP.mp4", 
    filetype=mimetype, 
    filesize=file.size,
    offset=datetime.now() - created_at,
    channel=0,
)

chunk_size = math.ceil(float(file.size) / float(len(asset.upload_urls)))

for chunk_url in asset.upload_urls:
   chunk = file.read(bytes=chunk_size)
   c2c.upload_chunk(chunk, chunk_url, mimetype)
```

Этот пример показывает базовый поток без обработки ошибок или параллельных операций добавления, которые будут рассмотрены в руководствах по [обработке ошибок](/camera-to-cloud/how-to-handle-errors) и [расширенным добавлениям](./how-to-advanced-uploads).

## Дальнейшие шаги

Поздравляем с добавлением первого ресурса в Frame.io! В [руководстве по расширенным операциям добавления](./how-to-advanced-uploads) будут более сложные техники и требования для готовых к использованию реализаций. Мы рекомендуем обращаться к нашей команде с любыми вопросами и переходить к [руководству по добавлению в реальном времени](./how-to-upload-realtime), чтобы узнать о добавлении ресурсов такими, какими они созданы.