# 单流录制和合流录制 (/zh-CN/realtime-media/local-server-recording/build/configure-recording-output/recording-mode)

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

<_PlatformTabsGroup>
<_PlatformProcessedMarker groupMode="structured" canonicalPlatform="cpp" platform="cpp" />
## 功能简介 [#功能简介]

为支持不同的录制业务需求，本地服务端录制 SDK 支持单流和合流两种录制模式，其中：

- **单流录制**，指对频道内不同的主播发出的流，根据用户 ID 进行区分并分别录制，产生不同的录制文件。
- **合流录制**，指将频道内全部主播的音视频合流录制到一起，只生成一个录制文件。

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

开始前，请确保你已参考[快速开始](/zh-CN/realtime-media/local-server-recording/get-started/start-recording)集成了录制 SDK，并实现了极简的录制功能。

实现单流或合流录制的步骤，和快速开始中一致，不同的是参数的设置，以及不同录制模式下可以调用的 API。因此开始前请确保你了解实现基础录制功能所需要的步骤。

## 实现单流录制 [#实现单流录制]

单流录制完整的 API 时序如下图所示：

<DocsImage alt="单流录制时序图" src="https://web-cdn.agora.io/docs-portal/img/recording/individual-recording.svg" displayWidth="80%" />

其中，关键步骤和参数设置如下：

- 初始化录制实例时，将 `enable_mix` 参数设为 `false`，表示使用单流录制；
- 调用 `subscribe` 系列方法订阅你想要录制的用户；
- 加入频道，并接收远端用户加入频道的回调 `onUserJoined`，获取其中的 `uid` 参数用于后续设置；
- 根据需求，调用 [`setRecorderConfigByUid`](/zh-CN/api-reference/local-server-recording/cpp/iagoramediartcrecorder.cpp#setrecorderconfigbyuid) 设置单流录制的配置项；调用 [`enableAndUpdateUpdateVideoWatermarksByUid`](/zh-CN/api-reference/local-server-recording/cpp/iagoramediartcrecorder.cpp#enableandupdatevideowatermarksbyuid) 添加录制水印；
- 调用单流录制对应的 API 开始/结束单流录制：
  - [`startSingleRecordingByUid`](/zh-CN/api-reference/local-server-recording/cpp/iagoramediartcrecorder.cpp#startsinglerecordingbyuid)：开始单流录制
  - [`stopSingleRecordingByUid`](/zh-CN/api-reference/local-server-recording/cpp/iagoramediartcrecorder.cpp#stopsinglerecordingbyuid)：停止单流录制

示例代码如下：

```cpp
// ...
// highlight-start
// enable_mix 设为false，启用单流录制模式
recorder->initialize(service, false);
// highlight-end
// 设置音频订阅逻辑
recorder->subscribeAllAudio();
recorder->subscribeAllVideo(options);
// 加入频道
recorder->joinChannel(config.token.c_str(), config.ChannelName.c_str(), config.UserId.c_str());
// 在收到 onUserjoined 回调后，可以针对 uid 设置 recorder config
agora::media::MediaRecorderConfiguration config;
config.fps = config_.video.fps;
config.width = config_.video.width;
config.height = config_.video.height;
config.channel_num = config_.audio.numOfChannels;
config.sample_rate = config_.audio.sampleRate;
std::string curTime = getCurrentTimeAsString();
std::string storagePath = config_.recorderPath + std::string(uid) + "_" + curTime + ".mp4";
config.storagePath = storagePath.c_str();
config.streamType = static_cast<agora::media::MediaRecorderStreamType>(config_.recorderStreamType) ;
config.maxDurationMs = config_.maxDuration * 1000;
// highlight-start
recorder_->setRecorderConfigByUid(config, uid);
// 设置水印 
recorder_->enableAndUpdateVideoWatermarksByUid(watermarks, config_.waterMarks.size(), uid);
// 开始录制
recorder_->startSingleRecordingByUid(uid);
// ...
// 停止录制
recorder_->stopSingleRecordingByUid(uid);
// highlight-end
```

## 实现合流录制 [#实现合流录制]

合流录制完整 API 时序如下图所示：

<DocsImage alt="合流录制时序图" src="https://web-cdn.agora.io/docs-portal/img/recording/composite-recording.svg" displayWidth="65%" />

其中，关键步骤和参数设置如下：

- 初始化录制实例时，将 `enable_mix` 参数设为 `true`，表示使用合流录制；
- 调用 `subscribe` 系列方法订阅你想要录制的用户；
- 加入频道后，根据需求调用 [`setRecroderConfig`](/zh-CN/api-reference/local-server-recording/cpp/iagoramediartcrecorder.cpp#setrecorderconfig)、[`setVideoMixingLayout`](/zh-CN/api-reference/local-server-recording/cpp/legacy/classagora-1-1recording-1-1-i-recording-engine#setvideomixinglayout)、[`enableAndUpdateVideoWatermarks`](/zh-CN/api-reference/local-server-recording/cpp/iagoramediartcrecorder.cpp#enableandupdatevideowatermarks) 设置合流录制的配置项、合流布局、水印等；
- 调用合流录制对应的 API 开始/结束合流录制：
  - [`startRecording`](/zh-CN/api-reference/local-server-recording/cpp/iagoramediartcrecorder.cpp#startrecording)：开始合流录制
  - [`stopRecording`](/zh-CN/api-reference/local-server-recording/cpp/iagoramediartcrecorder.cpp#stoprecording)：停止合流录制

示例代码如下：

```cpp
// ...
// highlight-start
// enable_mix 设为 true，启用合流录制模式
recorder->initialize(service, true);
// highlight-end
// 设置订阅逻辑
recorder->subscribeAllAudio();
recorder->subscribeAllVideo();
// 加入频道
recorder->joinChannel(config.token.c_str(), config.ChannelName.c_str(), config.UserId.c_str());
// highlight-start
// 设置合流录制 config、水印 config、合流的渲染布局
recorder->setRecorderConfig(recorder_config);
recorder->enableAndUpdateVideoWatermarks(watermarks, config.waterMarks.size());
recorder->setVideoMixingLayout(layout);
// highlight-end
// 开始录制
recorder->startRecording();
// ...
// 停止录制
recorder->stopRecording();
```

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

如果你使用了单流录制模式，调用如下方法不生效：

- `setRecorderConfig`
- `enableAndUpdateVideoWatermarks`
- `setVideoMixingLayout`
- `startRecording`
- `stopRecording`

如果你使用了合流录制模式，调用如下方法不生效：

- `setRecorderConfigByUid`
- `enableAndUpdateVideoWatermarksByUid`
- `startRecordingByUid`
- `stopRecordingByUid`

## 参考信息 [#参考信息]

- [设置合流布局](/zh-CN/realtime-media/local-server-recording/build/configure-recording-output/set-layout)
- [录制 API 参考](/zh-CN/api-reference/local-server-recording/cpp/api-overview)
<_PlatformProcessedMarker close="true" />

<_PlatformProcessedMarker groupMode="structured" canonicalPlatform="cpp" platform="java" />
## 功能简介 [#功能简介-1]

为支持不同的录制业务需求，本地服务端录制 SDK 支持单流和合流两种录制模式，其中：

- **单流录制**，指对频道内不同的主播发出的流，根据用户 ID 进行区分并分别录制，产生不同的录制文件。
- **合流录制**，指将频道内全部主播的音视频合流录制到一起，只生成一个录制文件。

本文介绍如何使用录制 4.x SDK 分别实现单流录制和合流录制。

## 前提条件 [#前提条件-1]

开始前，请确保你已参考[快速开始](/zh-CN/realtime-media/local-server-recording/get-started/start-recording)集成了录制 SDK，并实现了极简的录制功能。

实现单流或合流录制的步骤，和快速开始中一致，不同的是参数的设置，以及不同录制模式下可以调用的 API。因此开始前请确保你了解实现基础录制功能所需要的步骤。

## 实现单流录制 [#实现单流录制-1]

单流录制完整的 API 时序如下图所示：

<DocsImage alt="单流录制时序图" src="https://web-cdn.agora.io/docs-portal/img/recording/individual-recording-java.svg" displayWidth="80%" />

其中，关键步骤和参数设置如下：

- 初始化录制实例时，将 `enableMix` 参数设为 `false`，表示使用单流录制；
- 调用 `subscribe` 系列方法订阅你想要录制的用户；
- 加入频道，并接收远端用户加入频道的回调 `onUserJoined`，获取其中的 `userId` 参数用于后续设置；
- 根据需求，调用 [`setRecorderConfigByUid`](/zh-CN/api-reference/local-server-recording/java/agoramediartcrecorder.java#setrecorderconfigbyuid) 设置单流录制的配置项；调用 [`enableAndUpdateVideoWatermarksByUid`](/zh-CN/api-reference/local-server-recording/java/agoramediartcrecorder.java#enableandupdatevideowatermarksbyuid) 添加录制水印；
- 调用单流录制对应的 API 开始/结束单流录制：
  - [`startSingleRecordingByUid`](/zh-CN/api-reference/local-server-recording/java/agoramediartcrecorder.java#startsinglerecordingbyuid)：开始单流录制
  - [`stopSingleRecordingByUid`](/zh-CN/api-reference/local-server-recording/java/agoramediartcrecorder.java#stopsinglerecordingbyuid)：停止单流录制

示例代码如下：

```java
// ...
// highlight-start
// enableMix 设为false，启用单流录制模式
agoraMediaRtcRecorder.initialize(agoraService, false);
// highlight-end
// 设置音频订阅逻辑
agoraMediaRtcRecorder.subscribeAllAudio();
VideoSubscriptionOptions options = new VideoSubscriptionOptions();
options.setEncodedFrameOnly(false);
options.setType(Constants.VideoStreamType.VIDEO_STREAM_HIGH);
agoraMediaRtcRecorder.subscribeAllVideo(options);
// 加入频道
agoraMediaRtcRecorder.joinChannel(recorderConfig.getToken(),
                recorderConfig.getChannelName(),
                recorderConfig.getUserId());
// 在收到 onUserJoined 回调后，可以针对 uid 设置 recorder config
MediaRecorderConfiguration config = new MediaRecorderConfiguration();
config.setFps(recorderConfig.getVideo().getFps());
config.setWidth(recorderConfig.getVideo().getWidth());
config.setHeight(recorderConfig.getVideo().getHeight());
config.setChannelNum(recorderConfig.getAudio().getNumOfChannels());
config.setSampleRate(recorderConfig.getAudio().getSampleRate());
String curTime = getCurrentTimeAsString();
String storagePath = recorderConfig.getRecorderPath() + uid + "_" + curTime + ".mp4";
config.setStoragePath(storagePath);
config.setStreamType(Constants.MediaRecorderStreamType.STREAM_TYPE_BOTH);
config.setMaxDurationMs(recorderConfig.getMaxDuration() * 1000);
// highlight-start
agoraMediaRtcRecorder.setRecorderConfigByUid(config, uid);
// 设置水印
agoraMediaRtcRecorder.enableAndUpdateVideoWatermarksByUid(watermarks, uid);
// 开始录制
agoraMediaRtcRecorder.startSingleRecordingByUid(uid);
// ...
// 停止录制
agoraMediaRtcRecorder.stopSingleRecordingByUid(uid);
// highlight-end
```

## 实现合流录制 [#实现合流录制-1]

合流录制完整 API 时序如下图所示：

<DocsImage alt="合流录制时序图" src="https://web-cdn.agora.io/docs-portal/img/recording/composite-recording-java.svg" displayWidth="65%" />

其中，关键步骤和参数设置如下：

- 初始化录制实例时，将 `enableMix` 参数设为 `true`，表示使用合流录制；
- 调用 `subscribe` 系列方法订阅你想要录制的用户；
- 加入频道后，根据需求调用 [`setRecorderConfig`](/zh-CN/api-reference/local-server-recording/java/agoramediartcrecorder.java#setrecorderconfig)、[`setVideoMixingLayout`](/zh-CN/api-reference/local-server-recording/java/legacy/classio-1-1agora-1-1recording-1-1-recording-s-d-k#setvideomixinglayout)、[`enableAndUpdateVideoWatermarks`](/zh-CN/api-reference/local-server-recording/java/agoramediartcrecorder.java#enableandupdatevideowatermarks) 设置合流录制的配置项、合流布局、水印等；
- 调用合流录制对应的 API 开始/结束合流录制：
  - [`startRecording`](/zh-CN/api-reference/local-server-recording/java/agoramediartcrecorder.java#startrecording)：开始合流录制
  - [`stopRecording`](/zh-CN/api-reference/local-server-recording/java/agoramediartcrecorder.java#stoprecording)：停止合流录制

示例代码如下：

```java
// ...
// highlight-start
// enableMix 设为 true，启用合流录制模式
agoraMediaRtcRecorder.initialize(agoraService, true);
// highlight-end
// 设置订阅逻辑
agoraMediaRtcRecorder.subscribeAllAudio();
VideoSubscriptionOptions options = new VideoSubscriptionOptions();
options.setEncodedFrameOnly(false);
options.setType(Constants.VideoStreamType.VIDEO_STREAM_HIGH);
agoraMediaRtcRecorder.subscribeAllVideo(options);
// 加入频道
agoraMediaRtcRecorder.joinChannel(recorderConfig.getToken(),
                recorderConfig.getChannelName(),
                recorderConfig.getUserId());
// highlight-start
// 设置合流录制 config、水印 config、合流的渲染布局
agoraMediaRtcRecorder.setRecorderConfig(recorderConfig);
agoraMediaRtcRecorder.enableAndUpdateVideoWatermarks(watermarks);
agoraMediaRtcRecorder.setVideoMixingLayout(layout);
// 开始录制
agoraMediaRtcRecorder.startRecording();
// ...
// 停止录制
agoraMediaRtcRecorder.stopRecording();
// highlight-end
```

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

如果你使用了单流录制模式，调用如下方法不生效：

- `setRecorderConfig`
- `enableAndUpdateVideoWatermarks`
- `setVideoMixingLayout`
- `startRecording`
- `stopRecording`

如果你使用了合流录制模式，调用如下方法不生效：

- `setRecorderConfigByUid`
- `enableAndUpdateVideoWatermarksByUid`
- `startSingleRecordingByUid`
- `stopSingleRecordingByUid`

## 参考信息 [#参考信息-1]

- [设置合流布局](/zh-CN/realtime-media/local-server-recording/build/configure-recording-output/set-layout)
- [录制 API 参考](/zh-CN/api-reference/local-server-recording/java/api-overview)
<_PlatformProcessedMarker close="true" />
</_PlatformTabsGroup>
