# 实现单流录制 (/zh-CN/realtime-media/cloud-recording/build/recording-modes/individual-mode/set-individual)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

云端录制支持单流录制、合流录制和页面录制三种模式，其中[单流录制](/zh-CN/realtime-media/cloud-recording/reference/concepts#单流录制)模式指分别录制频道中每个用户 ID 的音频流和视频流，录制结束后每个用户 ID 会生成对应的音频文件和视频文件。

本文介绍如何使用云端录制的 RESTful API 并设置核心字段，进行单流录制并生成特定格式的文件。

:::info[信息]
本文内容适用于新单流录制。旧版单流录制文档请参阅[旧版实现单流录制](/zh-CN/realtime-media/cloud-recording/build/recording-modes/individual-mode/legacy-set-individual)。
:::

## 前提条件 [#前提条件]

开始前，请参考[使用 RESTful API 开始云端录制](/zh-CN/realtime-media/cloud-recording/get-started/quick-start)进行一次完整的录制流程体验。

## 实现步骤 [#实现步骤]

本节介绍如何在[申请录制服务器资源](/zh-CN/realtime-media/cloud-recording/get-started/quick-start/restful-api#申请录制服务器资源)后，实现单流音视频录制。

### 开始录制 [#开始录制]

调用 [`start`](/zh-CN/api-reference/api-ref/cloud-recording/start) 方法开始云端录制。

#### 请求示例 [#请求示例]

以下介绍开始单流音视频录制请求的关键配置，确保你进行正确设置以实现预期的录制效果。

1. 在调用 `start` 方法时，将 `mode` 参数设置为 `raw`，开启单流录制模式。
   :::warning[注意]
   录制模式的设置必须在开始录制的时候完成，不支持在录制开始后切换模式。
   :::

2. 设置 `recordingConfig` 和 `recordingFileConfig` 中的参数。不同 `streamTypes` 与 `recordingFileConfig.avFileType` 配置组合对应的录制文件生成关系如下。具体设置参见 [`streamTypes` 参数说明](/zh-CN/api-reference/api-ref/cloud-recording/start)。

<Tabs defaultValue="streamTypes-0" groupId="streamTypes" persist>
<TabsList>
  <TabsTrigger value="streamTypes-0">streamTypes = 0</TabsTrigger>
  <TabsTrigger value="streamTypes-1">streamTypes = 1</TabsTrigger>
  <TabsTrigger value="streamTypes-2">streamTypes = 2</TabsTrigger>
</TabsList>

<TabsContent value="streamTypes-0">

| 录制内容 | `recordingFileConfig.avFileType` 设置 | 最终输出效果 |
| --- | --- | --- |
| 仅录制音频 | `["hls"]` | 每个用户 ID 生成一个 HLS 文件，仅包含该用户的音频数据。 |
| 仅录制音频 | `["hls", "mp3"]` | [set-individual-html-0-2-2 details](#table-slot-set-individual-html-0-2-2) |
| 仅录制音频 | `["mp3"]` | 不支持。 |

<a id="table-slot-set-individual-html-0-2-2"></a>

**set-individual-html-0-2-2 details**

同时生成 2 份文件：

- 每个用户 ID 生成一个 HLS 文件，仅包含该用户的音频数据。
- 每个用户 ID 生成一个 MP3 文件。

</TabsContent>

<TabsContent value="streamTypes-1">

| 录制内容 | `recordingFileConfig.avFileType` 设置 | 最终输出效果 |
| --- | --- | --- |
| 仅录制视频 | `["hls"]` | 每个用户 ID 生成一个 HLS 文件或 DASH 文件（取决于源流视频编码器），每个切片内仅包含该用户的视频数据。 |
| 仅录制视频 | `["hls", "mp4"]` | [set-individual-html-1-2-2 details](#table-slot-set-individual-html-1-2-2) |
| 仅录制视频 | `["mp4"]` | 不支持。 |

<a id="table-slot-set-individual-html-1-2-2"></a>

**set-individual-html-1-2-2 details**

同时生成 2 份文件：

1. 每个用户 ID 生成一个 HLS 文件或 DASH 文件（取决于源流视频编码器），每个切片内仅包含该用户的视频数据。
2. 每个用户 ID 生成一个 MP4 文件。该功能有一些已知限制，详见[单流直接生成 MP4](#单流直接生成-mp4)。

</TabsContent>

<TabsContent value="streamTypes-2">

| 录制内容 | `recordingFileConfig.avFileType` 设置 | 最终输出效果 |
| --- | --- | --- |
| 同时录制音视频 | `["hls"]` | 每个用户 ID 生成一个 HLS 文件或 DASH 文件（取决于源流视频编码器），每个切片内同时包含该用户的音频及视频数据。 |
| 同时录制音视频 | `["hls", "mp4"]` | [set-individual-html-2-2-2 details](#table-slot-set-individual-html-2-2-2) |
| 同时录制音视频 | `["mp4"]` | 不支持。 |

<a id="table-slot-set-individual-html-2-2-2"></a>

**set-individual-html-2-2-2 details**

同时生成 2 份文件：

1. 每个用户 ID 生成一个 HLS 文件或 DASH 文件（取决于源流视频编码器），每个切片内同时包含该用户的音频及视频数据。
2. 每个用户 ID 生成一个 MP4 文件。该功能有一些已知限制，详见[单流直接生成 MP4](#单流直接生成-mp4)。

</TabsContent>
</Tabs>

:::info[信息]
- HLS 文件表示一个 M3U8 文件及多个 TS 文件，属于标准 HLS 协议，可直接播放。
- DASH 文件表示一个 MPD 文件及多个 WebM 文件，属于标准 DASH 协议，可直接播放。
:::

如需了解录制文件的命名规则、字段含义和切片规则，请参见[录制文件介绍](/zh-CN/realtime-media/cloud-recording/build/manage-recorded-files/introduce-recorded-files)。

3. 参照[快速开始](/zh-CN/realtime-media/cloud-recording/get-started/quick-start/restful-api#开始录制)配置 `storageConfig` 相关参数。

单流音视频录制的请求 Body 示例如下：

```shell
# [!code highlight:1]
curl --location --request POST 'https://api.sd-rtn.com/v1/apps/<your_app_id>/cloud_recording/resourceid/<resourceid>/mode/raw/start' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: <http_basic_auth>' \
--data '{
  "cname": "show",
  "uid": "123",
  "clientRequest": {
    "token": "<your_token>",
    "recordingConfig": {
      "channelType": 1,
      # [!code highlight:1]
      "streamTypes": 2,
      "videoStreamType": 0,
      "maxIdleTime": 30,
      "subscribeAudioUids": [
        "123",
        "456"
      ],
      "subscribeVideoUids": [
        "123",
        "456"
      ],
      "subscribeUidGroup": 0
    },
    "recordingFileConfig": {
      "avFileType": [
        "hls",
        "mp4"
      ]
    },
    # [!code highlight:8]
    "storageConfig": {
      "vendor": 2,
      "region": 3,
      "bucket": "<your_storage_bucket_name>",
      "accessKey": "<your_storage_access_key>",
      "secretKey": "<your_storage_secret_key>",
      "fileNamePrefix": [
        "quickstart",
      ]
    },
  }
}
```

### 单流直接生成 MP4 [#单流直接生成-mp4]

单流录制模式下，视频不做编解码。若想直接生成可播放的 MP4 文件，且尽量减少 MP4 切片数量，需要满足以下条件：

- 源流视频编码器必须是 H.264、H.265 或 AV1。若源流是 VP8 或 VP9，则不支持直接生成 MP4。
- 源流分辨率保持不变。

具体设置如下：

<Tabs defaultValue="native" groupId="mp4-config-platform" persist>
<TabsList>
  <TabsTrigger value="native">Native 端</TabsTrigger>
  <TabsTrigger value="web">Web 端</TabsTrigger>
</TabsList>

<TabsContent value="native">

调用 `SetVideoEncodeConfiguration`，将参数 [`orientationMode`](https://doc.shengwang.cn/api-ref/rtc/windows/API/enum_orientationmode) 设置为 `1` 或 `2`，固定为横屏或竖屏。

调用 `SetVideoEncodeConfiguration`，将参数 [`DEGRADATION_PREFERENCE`](https://doc.shengwang.cn/api-ref/rtc/windows/API/enum_degradationpreference) 设置为 `3` 或 `100`，保持分辨率不变或关闭 VQC。

</TabsContent>

<TabsContent value="web">

调用 `setOptimizationMode` API，将 [`OptimizationMode`](https://doc.shengwang.cn/api-ref/rtc/javascript/globals#optimizationmode) 设置为 `detail`，即清晰度优先，弱网情况下优先降低帧率，不降低分辨率。

</TabsContent>
</Tabs>

若主播源流无法满足上述要求，录制过程中分辨率发生变化，变化前后将生成不同的 MP4 切片文件，具体文件名可参考[录制文件组成及命名规则](/zh-CN/realtime-media/cloud-recording/build/manage-recorded-files/introduce-recorded-files)。

:::info[信息]
如果无法保证主播源流分辨率固定，也不接受生成多段 MP4 文件，或者主播源流是 VP8/VP9 编码，则可使用合流录制，在录制过程中实时转码，以最大限度保证 MP4 文件兼容性。
:::

#### 响应示例 [#响应示例]

```json
{
    "cname": "show",
    "uid": "123",
    "resourceId": "SGXETXXX",
    // [!code highlight:1]
    "sid": "04a85XXX"
}
```

你需要复制 `sid` 以备后用。

### 停止录制 [#停止录制]

录制完成后，调用 [`stop`](/zh-CN/api-reference/api-ref/cloud-recording/stop) 方法离开频道，停止录制。录制停止后如需再次录制，必须再调用 `acquire` 方法请求一个新的 Resource ID。

#### 请求示例 [#请求示例-1]

```shell
curl --location --request POST 'https://api.sd-rtn.com/v1/apps/<yourappid>/cloud_recording/resourceid/<resourceid>/sid/<sid>/mode/raw/stop' \
--header 'Content-Type: application/json' \
--data '{
  "cname": "show",
  "uid": "123",
  "clientRequest": {
    "async_stop": false
  }
}'
```

#### 响应示例 [#响应示例-1]

```json
{
  "resourceId": "SGXETXXX",
  "sid": "04a85XXX",
  "serverResponse": {
    "fileListMode": "json",
    "fileList": [
      {
        "fileName": "xxxxxxx",
        "isPlayable": true,
        "mixedAllUser": false,
        "sliceStartTime": xxxxxxxxxx,
        "trackType": "audio_and_video",
        "uid": "xxx"
      }
    ],
    // [!code highlight:1]
    "uploadingStatus": "uploaded"
  },
  "cname": "show",
  "uid": "123"
}
```

`uploadingStatus` 字段表示录制文件上传状态：

- `uploaded`：录制文件已上传至第三方云存储。
- `stranded`：v2 新增状态。业务逻辑需要针对该状态补充分支处理，并结合消息通知或查询结果处理未完成的文件上传。

## 开发注意事项 [#开发注意事项]

在进行单流录制过程中，你需要关注如下注意事项：

- 如果在录制过程中禁用视频轨道，则录制效果详见下表：

    | 发流端类型  | 禁用视频轨道的方法                                           | 录制效果             |
    | :---------- | :----------------------------------------------------------- | :------------------- |
    | Native 端 | 调用 [`muteLocalVideoStream`](/zh-CN/api-reference/rtc/android/publishnsubscribe#api_irtcengine_mutelocalvideostream)  或 [`disableVideo`](/zh-CN/api-reference/rtc/android/video/video-basic#api_irtcengine_disablevideo) 方法 |不继续生成视频切片文件，在本切片内用户画面显示最后一帧。       |
    | Web 端 | 调用 [`setEnabled`](/zh-CN/api-reference/rtc/web/interfaces/ilocalvideotrack#setenabled) 方法 | 不继续生成视频切片文件，在本切片内用户画面显示最后一帧。 |

## 相关文档 [#相关文档]

在单流录制过程中，你还可以参考如下文档：

- [设置订阅名单](/zh-CN/realtime-media/cloud-recording/reference/api-reference#订阅名单设置)
- [转换录制文件格式](/zh-CN/realtime-media/cloud-recording/build/manage-recorded-files/convert-format)
- [录制文件介绍](/zh-CN/realtime-media/cloud-recording/build/manage-recorded-files/introduce-recorded-files)

## API 参考 [#api-参考]

你可以参考以下方法了解字段详情：

- [`acquire`](/zh-CN/api-reference/api-ref/cloud-recording/acquire)
- [`start`](/zh-CN/api-reference/api-ref/cloud-recording/start)
- [`stop`](/zh-CN/api-reference/api-ref/cloud-recording/stop)

## 常见问题 [#常见问题]

- [应用崩溃后对云端录制有什么影响？](/zh-CN/reference/faq/integration/abnormal_exit)
- [如何选择云存储 bucket 区域及处理跨区上传问题？](/zh-CN/reference/faq/integration/bucket_region)
- [为什么无法通过浏览器调用云端录制 RESTful API？](/zh-CN/reference/faq/product/call_api_in_browser)
- [为什么第三方云储存中没有录制文件？](/zh-CN/reference/faq/integration/fail_to_upload)
- [如何获取 M3U8 文件地址？](/zh-CN/reference/faq/integration/acquire_file_directory)
- [云端录制如何处理服务器断网、进程被杀问题？](/zh-CN/reference/faq/integration/high_availability)
