> This page is for Camera to Cloud.

> 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 的设备进行通信，会怎么样？ 某些集成可能希望代表此类设备执行操作，例如一个录音机代表麦克风进行上传，或者一个相机代表附件上的按钮进行实时评论。





通过理解设备的通道，可以满足这些请求。 如果您的集成不需要管理次设备，则可以跳过本指南。





## 我需要准备什么？

如果您还未阅读[实施 C2C：设置](./implementing-c2c-setting-up)指南，请先快速浏览一下再继续操作！ 您需要用到在[设备身份验证和授权指南](./how-to-authorization-management-hardware)中收到的 `access_token`。

您还需要一个应能够通过您的主要设备连接到 Frame.io 的次设备的设备型号 ID 列表。





## 什么是通道？

我们在[架构概述](./integration-architecture)中简要探讨了通道。 每个项目设备至少有一个通道，虽然我们之前通常将这两者视为同一事物，但现在我们需要将这两个概念区分开。 让我们深入探讨一下。

项目设备具有与 Frame.io 直接通信的能力。 通道则负责收集数据，供项目设备进行通信。 在大多数情况下，项目设备与它的第一个通道是同一事物。 以相机为例：从概念上讲，项目设备代表相机的网卡，它直接向 Frame.io 发送数据，而通道则代表相机的 CMOS 传感器，负责采集视频数据，再通过网卡（即项目设备）发送出去。





最重要的是，项目设备通过 OauthApp 向 Frame 进行身份验证，而通道则不需要。 通道使用其主项目设备的身份验证信息。





我们的模型允许一个项目设备拥有多个通道，这些通道可能是物理设备的一部分，也可能不是。 通道可以是各种硬件，通过 TCP/IP、蓝牙、SDI 等方式与主要设备进行通信。项目设备充当路由器，将这些数据发送到 Frame.io。 这些数据如何从各个通道提供给项目设备，这由您（集成方）决定。





设想一台录音机作为项目设备连接到 Frame.io，它带有多个麦克风，每个麦克风都作为独立的通道连接。 录音机可以通过其主要通道发送混音文件，并通过其次设备的通道发送各个麦克风的独立音轨。 您如何使用通道以及每个通道代表什么，完全由您决定！ 通道不需要进行身份验证，设备可以随时添加或移除它们。





由于通道可以属于独立的物理次设备，因此每个通道都会关联一个设备型号，就像任何其他硬件或软件集成一样。 这使 Frame.io 能够显示次设备的型号（该型号可能与主机设备不同），并允许集成针对每个次设备单独定义其行为。 必须提前定义哪些设备型号可以作为通道添加到给定的集成中。





您可能希望将新通道连接到您的 C2C 设备，原因有以下几点：



* 支持根据“通道 + 设备型号”为集成提供多种配置。 这包括固定的资产文件夹结构、令牌化文件夹路径、文件扩展名路由等。设想一个 DIT 工作站，它使用不同的通道来上传可编辑的代理文件或 Camera Raw 文件。
* 让 Frame.io 中的用户能够看到您的次设备。
* 通道可以配置有人工输入（即按钮），您可以配置这些按钮，用于实现实时记录功能。




让我们深入了解如何使用 C2C API 来管理通道。





## 列出通道

可通过 [identity 端点](./how-to-heartbeats-connection-info-and-status#fetching-connection-information)的 channels 字段来获取现有通道列表。 让我们看一下响应负载的 `&quot;channels&quot;` 字段：

```json
{
    "_type": "project_device",
    ...
    "channels": [
        {
            "_type": "project_device_channel",
            "actor_id": null,
            "asset_type": "video",
            "device_id": "98e9367a-b26b-4c60-8e64-da83dfd9540b",
            "external_index": 0,
            "id": "5919e9bc-7fc2-4629-97e5-852ce27cfa1a",
            "inserted_at": "2023-07-14T19:11:43.217565Z",
            "name": "Test Host Device",
            "project_device_id": "bf30fc66-f126-4336-bdfc-75d3e659b95a",
            "project_id": "1eb3587f-6bca-4e8d-a2f6-e7413d82c1ad",
            "real_time_logging_capable": false,
            "status": "online",
            "updated_at": "2023-07-14T19:11:43.217565Z"
        },
        {
            "_type": "project_device_channel",
            "actor_id": null,
            "asset_type": "video",
            "device_id": "057b33c4-9f92-4eeb-a3d5-2fd0f4932292",
            "external_index": 0,
            "id": "0b17e1e3-588c-4365-be51-5cf097c8f004",
            "inserted_at": "2023-07-14T19:11:43.217565Z",
            "name": "Test Client Device 01234",
            "project_device_id": "bf30fc66-f126-4336-bdfc-75d3e659b95a",
            "project_id": "1eb3587f-6bca-4e8d-a2f6-e7413d82c1ad",
            "real_time_logging_capable": false,
            "status": "offline",
            "updated_at": "2023-07-14T19:11:43.217565Z"
        }
    ],
    ...
    "device_id": "98e9367a-b26b-4c60-8e64-da83dfd9540b",
    ...
    "id": "bf30fc66-f126-4336-bdfc-75d3e659b95am"
}
```

请注意，第一个通道的 `device_id` 与我们整个项目设备的 `device_id` 相匹配。

## 连接通道





我们可以通过以下请求连接新通道：





```shell
curl -X POST https://api.frame.io/v2/devices/channels/connect \
    --header 'Authorization: Bearer [access_token]' \
    --header 'Content-Type: application/json' \
    --header 'x-client-version: 2.0.0' \
    --data-binary @- <<'__JSON__'{
            "client_id": [client_id],
            "device_model_id": [device_model_id]
        }
__JSON__
    | python -m json.tool
```





我们会收到如下响应：





```json
{
   "_type": "project_device_channel",
   "actor_id": null,
   "asset_type": "video",
   "device_id": "057b33c4-9f92-4eeb-a3d5-2fd0f4932292",
   "external_index": 0,
   "id": "0b17e1e3-588c-4365-be51-5cf097c8f004",
   "inserted_at": "2023-07-14T19:11:43.217565Z",
   "name": "Test Client Device 01234",
   "project_device_id": "bf30fc66-f126-4336-bdfc-75d3e659b95a",
   "project_id": "1eb3587f-6bca-4e8d-a2f6-e7413d82c1ad",
   "real_time_logging_capable": true,
   "status": "offline",
   "updated_at": "2023-07-14T19:11:43.217565Z"
}
```

此响应与 [identity](./how-to-heartbeats-connection-info-and-status#fetching-connection-information) 端点返回的 channels 字段一致。

client_id 用于控制唯一性，因此它必须是一个稳定的值，例如序列号。




device_model_id 用于告知 Frame.io 该通道所代表的底层硬件设备类型，例如某个特定型号的麦克风。 这些将由您的合作伙伴经理设置。





如果该通道已被声明，您会收到一个 409 错误，错误标题为“已存在”。





当使用与之前曾连接后又断开过的通道相同的标识符来创建通道时，该通道之前的所有用户配置都会被恢复。





## 断开通道连接





通道通过 Frame.io 定义的 id 来断开连接。 而不是通过 client_id 或 device_model_id。





```shell
curl -X POST https://api.frame.io/v2/devices/channels/:channel_id/disconnect \
    --header 'Authorization: Bearer [access_token]' \
    --header 'x-client-version: 2.0.0' \
    | python -m json.tool
```

该操作会返回一个负载为空的 `204` 响应。

删除不存在的通道时，您将收到 404 错误。 您不能断开主设备的第一个主要通道。





## 断开所有次设备通道的连接





您可以通过以下调用断开某个项目设备上当前所有次设备通道的连接：





```shell
curl -X POST https://api.frame.io/v2/devices/channels/disconnect \
    --header 'Authorization: Bearer [access_token]' \
    --header 'x-client-version: 2.0.0' \
    | python -m json.tool
```

该操作会返回一个负载为空的 `204` 响应。 此调用始终会成功，即使该项目设备没有任何客户端设备通道。 我们现在可以使用 [identity](./how-to-heartbeats-connection-info-and-status#fetching-connection-information) 端点列出所有通道；仅保留主机设备的主要通道。

## 通道管理流程





我们不建议项目设备在内部自行管理通道状态，以避免因在不理想的时机发生电源循环而导致数据完整性问题。 例如：



* 在处理“通道连接”调用后，但在返回的 `id` 可以提交到数据存储库之前关闭电源
* 在设备关闭时，从主机设备插拔次设备。




相反，建议所有主机设备在首次启动时执行以下步骤：



* 调用“批量断开通道连接”端点，以清除所有现有的次设备通道
* 针对当前已连接的每个次设备，调用“通道连接”端点

初始设置完成后，主机设备必须在断开次设备连接时调用“断开通道连接”端点，并在添加新的次设备时调用“通道连接”端点。 主机设备不得在每次有新设备连接时都清除所有次设备。

主机设备在管理设备时必须正确处理网络状况不佳的情况，并在重新建立网络连接后正确添加/移除当前已连接的设备。





## 下一步





如果您还没有联系我们的团队，我们鼓励您这样做，然后继续阅读下一份指南。 我们期待收到您的回复！