logo
实时音视频
房间能力
当前页

混流

2025-05-07

功能简介

概述

混流是把多路音视频流从云端合并成一路流的技术,也称合流。开发者只需要拉取合并后的流就能看到房间内所有成员的画面,听到房间内所有成员的声音,无需分别管理房间内的每一条流。

本篇文档主要介绍通过客户端发起混流的操作说明,如果你需要通过自己的服务端发起混流,请参考 服务端 API - 开始混流

混流方式分类

ZEGO 支持手动混流、自动混流和全自动混流三种方式,三种混流方式的区别如下:

混流方式手动混流自动混流全自动混流
含义自定义控制混流任务和混流内容,包括输入流、混流布局等。支持手动混视频流和音频流。指定房间,自动将房间内的所有音频流进行混流。只支持自动混音频流。每个房间都自动混音频流。只支持全自动混音频流。
应用场景合并多个视频画面和声音时可用,比如在线课堂中老师和学生画面的直播,娱乐场景中的跨房间连麦,特殊场景中需混合指定几条流等;设备不支持同时拉多条流或者设备性能较差的场景。将房间内所有音频流合为一条流时使用自动混流,比如语聊房、合唱。不想做任何开发,房间内所有音频流合为一条流时使用全自动混流,比如语聊房、合唱。
优势灵活性强,能够根据业务需要实现逻辑。降低了开发者接入的复杂程度,不需要管理指定房间音频流的生命周期。开发者接入复杂程度很低,不需要管理所有房间音频混流任务的生命周期以及音频流的生命周期。
发起方式用户客户端或用户服务端发起混流任务,用户客户端维护流的生命周期。用户客户端发起混流任务,ZEGO 服务端自动维护房间内流的生命周期(即输入流列表)。联系 ZEGO 技术支持开通全自动混流,ZEGO 服务端维护混流任务和房间内流的生命周期(即输入流列表)。

优点

  • 降低了开发实现上的复杂性。比如当有 N 个主播进行连麦,如果采用混流,观众端不必同时拉 N 路视频流,开发实现上省去了拉 N 路流并布局的步骤。
  • 降低了对设备的性能要求,减少设备的性能开销和网络带宽的负担。比如当连麦方过多时,观众端需要拉 N 路视频流,需要设备硬件上能支持同时拉 N 路流。
  • 转推多路 CDN 实现简单,只需要在混流配置时按需增加输出流。
  • 观众端需要回放多主播连麦视频时,仅需要在 CDN 上开启录制的配置。
  • 鉴黄时只需要观察一个画面,不必再同时查看多个画面。

示例源码下载

请参考 下载示例源码 获取源码。

相关源码请查看 “/ZegoExpressExample/Examples/Others/StreamMixing” 目录下的文件。

前提条件

在实现混流功能之前,请确保:

注意

混流功能不是默认开启的,使用前请在 ZEGO 控制台 自助开通(开通步骤请参考 项目管理 - 服务配置 中的“混流”),或联系 ZEGO 技术支持开通。

实现流程

混流的主要流程如下:

  1. 房间内的用户推 A 流和 B 流到 ZEGO 实时音视频云服务器上。
  2. ZEGO 实时音视频云服务器可以根据需要配置推混流或者推单独的 A 流和 B 流到 CDN 服务器。(采用 RTMP 协议)
  3. 拉流端根据需要从 CDN 服务器上拉混流,也可以拉单独的 A 流和 B 流(支持 RTMP、FLV、HLS 等协议)。

手动混流使用步骤

手动混流可自定义控制混流任务和混流内容,包括输入流、混流布局等,常用于多人互动直播和跨房间连麦场景。支持手动混视频流和音频流。

开发者可通过 SDK 或 ZEGO 服务端 API 实现手动混流功能,服务端相关接口请参考 开始混流停止混流

以下介绍如何使用 SDK 实现手动混流。

1 初始化并登录房间

可参考 快速开始 - 实现流程 的 “创建引擎” 和 “登录房间” 完成房间登录。

注意
  • 混流的前置条件为房间内需要有已存在的流。
  • 你可以混合房间内已存在的音视频流,无论这些流是你自己推送的还是其他用户推送的。

2 设置混流配置

ZegoMixerTask 是 SDK 中定义的混流任务配置对象,通过配置该对象可定制化手动混流任务。

struct ZegoMixerTask
{
    ZegoMixerTask(std::string taskID=""): taskID(taskID), watermark(nullptr){}
    // 混流任务ID 全局唯一
    std::string taskID;
    // 混流任务对象的输入列表
    std::vector<ZegoMixerInput> inputList;
    // 混流任务对象的输出列表
    std::vector<ZegoMixerOutput> outputList;
    // 混流任务对象的水印
    ZegoWatermark *watermark;
    // 混流任务对象的背景图片
    std::string backgroundImageURL;
    // 是否开启混流的声浪回调通知
    bool enableSoundLevel;
};

创建混流任务对象

新建一个混流任务对象,然后分别设置输入、输出等参数。

用户可同时发起多个混流任务,但需要为不同的任务指定一个全局唯一的 “taskID”。

ZegoMixerTask task("taskID");

设置混流视频配置

通过 ZegoMixerVideoConfig 设置混流视频相关配置,主要包括视频分辨率、视频帧率和码率。

说明

混流输出的最大帧率默认限制在 20 帧以内,如果需要输出更大帧率,请联系 ZEGO 技术支持进行配置。

ZegoMixerVideoConfig videoConfig;
task.videoConfig = videoConfig;

设置混流音频配置

通过 ZegoMixerAudioConfig 设置混流音频相关配置,主要包括音频码率、声道数、编码 ID。

ZegoMixerAudioConfig audioConfig;
task.audioConfig = audioConfig;

设置混流输入流

根据实际业务场景,定义输入的视频流 ZegoMixerInput 列表,设置其中每条视频流的 “layout” 参数来对每条输入流的画面进行布局,由 ZEGO 实时音视频云服务器将输入流进行混合,输出在一个画面中的混流。

注意
  • 默认支持最多输入 9 路流,如果需要输入更多路流,请联系 ZEGO 技术支持确认和配置。
  • 当混流输入流的 “contentType” 都设置为 “AUDIO” 时,SDK 内部不处理布局字段,此时无需关注 “layout” 参数。
  • 当混流输入流的 “contentType” 都设置为 “AUDIO” 时,SDK 内部会默认把分辨率设置为 1*1(即混流输出是纯音频)。如果您想要混流输出有视频画面或者背景图,则至少需要将一路输入流的 “contentType” 设置为 “VIDEO”。

输入流的布局以输出混流画面的左上角为坐标系原点,参考原点设置输入流的布局,即将 ZegoRect(left, top, width, height) 传入输入流的 “layout” 参数。此外,输入流的图层层次由输入流在输入流列表中的位置决定,在列表中的位置越后,表示图层层次越高。

Rect 参数说明如下:

参数描述
left对应输入流画面左上角的 x 坐标。
top 对应输入流画面左上角的 y 坐标。
width对应输入流画面的宽度。
height 对应输入流画面的高度。
注意

以上参数在不同的开发平台可能有所差异,具体请以各端的文档为准。

假设启动一个输出画面为 375×667 分辨率的混流任务,输入流为一条大小为 150×150,位于距左侧 50、距顶部 300 的混流,则需将 ZegoRect(50, 300, 150, 150) 传入输入流的 “layout” 参数。

那么这条输入流在最终的输出混流中的位置如下所示:

开发者可参考以下示例代码实现常见的混流布局:两个画面水平平铺、四个画面水平垂直平铺、一个大画面铺满和两个小画面悬浮。

以下布局示例皆以 360×640 分辨率进行说明。


// 填写第一条输入流配置,每条输入流需要设置 Stream ID(该参数中的值必须是输入流的实际 ID),输入流类型,布局等等
ZegoMixerInput input_1;
input_1.streamID = "stream-1";
input_1.contentType = ZEGO_MIXER_INPUT_CONTENT_TYPE_VIDEO;
input_1.layout = ZegoRect(0, 0, 180, 640);
input_1.renderMode = ZegoMixRenderMode::ZEGO_MIX_RENDER_MODE_FILL;

// 输入流的文字水印
input_1.label.font.type = ZegoFontType::ZEGO_FONT_TYPE_ALIBABA_SANS;
input_1.label.font.color = 123456;
input_1.label.font.size = 24;
input_1.label.font.transparency = 50;
input_1.label.text = "text watermark";
input_1.label.left = 0;
input_1.label.top = 0;

// 填写第二条输入流配置
ZegoMixerInput input_2;
input_2.streamID = "stream-2";
input_2.contentType = ZEGO_MIXER_INPUT_CONTENT_TYPE_VIDEO;
input_2.layout = ZegoRect(180, 0, 180, 640);
input_2.renderMode = ZegoMixRenderMode::ZEGO_MIX_RENDER_MODE_FILL;

// 输入流的文字水印
input_2.label.font.type = ZegoFontType::ZEGO_FONT_TYPE_ALIBABA_SANS;
input_2.label.font.color = 123456;
input_2.label.font.size = 24;
input_2.label.font.transparency = 50;
input_2.label.text = "text watermark";
input_2.label.left = 0;
input_2.label.top = 0;

// 设置混流输入
task.inputList = {input_1, input_2};

// 填写第一条输入流配置,每条输入流需要设置 Stream ID(该参数中的值必须是输入流的实际 ID),输入流类型,布局等等
ZegoMixerInput input_1;
input_1.streamID = "stream-1";
input_1.contentType = ZEGO_MIXER_INPUT_CONTENT_TYPE_VIDEO;
input_1.layout = ZegoRect(0, 0, 180, 320);
input_1.renderMode = ZegoMixRenderMode::ZEGO_MIX_RENDER_MODE_FILL;

// 输入流的文字水印
input_1.label.font.type = ZegoFontType::ZEGO_FONT_TYPE_ALIBABA_SANS;
input_1.label.font.color = 123456;
input_1.label.font.size = 24;
input_1.label.font.transparency = 50;
input_1.label.text = "text watermark";
input_1.label.left = 0;
input_1.label.top = 0;

// 填写第二条输入流配置
ZegoMixerInput input_2;
input_2.streamID = "stream-2";
input_2.contentType = ZEGO_MIXER_INPUT_CONTENT_TYPE_VIDEO;
input_2.layout = ZegoRect(180, 0, 180, 320);
input_2.renderMode = ZegoMixRenderMode::ZEGO_MIX_RENDER_MODE_FILL;

// 输入流的文字水印
input_2.label.font.type = ZegoFontType::ZEGO_FONT_TYPE_ALIBABA_SANS;
input_2.label.font.color = 123456;
input_2.label.font.size = 24;
input_2.label.font.transparency = 50;
input_2.label.text = "text watermark";
input_2.label.left = 0;
input_2.label.top = 0;

// 填写第三条输入流配置
ZegoMixerInput input_3;
input_3.streamID = "stream-3";
input_3.contentType = ZEGO_MIXER_INPUT_CONTENT_TYPE_VIDEO;
input_3.layout = ZegoRect(0, 320, 180, 320);
input_3.renderMode = ZegoMixRenderMode::ZEGO_MIX_RENDER_MODE_FILL;

// 输入流的文字水印
input_3.label.font.type = ZegoFontType::ZEGO_FONT_TYPE_ALIBABA_SANS;
input_3.label.font.color = 123456;
input_3.label.font.size = 24;
input_3.label.font.transparency = 50;
input_3.label.text = "text watermark";
input_3.label.left = 0;
input_3.label.top = 0;

// 填写第四条输入流配置
ZegoMixerInput input_4;
input_4.streamID = "stream-4";
input_4.contentType = ZEGO_MIXER_INPUT_CONTENT_TYPE_VIDEO;
input_4.layout = ZegoRect(180, 320, 180, 320);
input_4.renderMode = ZegoMixRenderMode::ZEGO_MIX_RENDER_MODE_FILL;

// 输入流的文字水印
input_4.label.font.type = ZegoFontType::ZEGO_FONT_TYPE_ALIBABA_SANS;
input_4.label.font.color = 123456;
input_4.label.font.size = 24;
input_4.label.font.transparency = 50;
input_4.label.text = "text watermark";
input_4.label.left = 0;
input_4.label.top = 0;

// 设置混流输入
task.inputList = {input_1, input_2, input_3, input_4};

输入流的图层层次由输入流在输入流列表中的位置决定,在列表中的位置越后,表示图层层次越高。如以下示例代码所示,第 2 条输入流的图层层次和第 3 条输入流的图层层次则比第 1 条输入流的层次要高,则第 2 条和第 3 条流悬浮第 1 条流的画面上。


// 填写第一条输入流配置,每条输入流需要设置 Stream ID(该参数中的值必须是输入流的实际 ID),输入流类型,布局等等
ZegoMixerInput input_1;
input_1.streamID = "stream-1";
input_1.contentType = ZEGO_MIXER_INPUT_CONTENT_TYPE_VIDEO;
input_1.layout = ZegoRect(0, 0, 360, 640);

// 填写第二条输入流配置
ZegoMixerInput input_2;
input_2.streamID = "stream-2";
input_2.contentType = ZEGO_MIXER_INPUT_CONTENT_TYPE_VIDEO;
input_2.layout = ZegoRect(230, 200, 110, 200);

// 填写第三条输入流配置
ZegoMixerInput input_3;
input_3.streamID = "stream-3";
input_3.contentType = ZEGO_MIXER_INPUT_CONTENT_TYPE_VIDEO;
input_3.layout = ZegoRect(230, 420, 110, 200);

// 设置混流输入
task.inputList = {input_1, input_2, input_3};

设置混流输出列表

通过 ZegoMixerOutput 设置混流输出列表,用户可以从列表中的输出目标拉取混流。 混流输出列表最多可设置 3 个。当输出目标为 URL 格式时,目前只支持 RTMP URL 格式:rtmp://xxxxxxxx,且不能传入两个相同的混流输出的地址。

ZegoMixerOutput mixerOutput;
// 输出流名为 "output-stream"
mixerOutput.target = "output-stream";
task.outputList = {mixerOutput};

(可选)设置混流图片水印

如果需要水印图片的 URL,请联系 ZEGO 技术支持获取。

以下代码演示设置一个 ZEGO 的图片水印放置于画面左上角:

ZegoWatermark watermark;
watermark.imageURL = "preset-id://zegowp.png";
watermark.layout = ZegoRect(0, 0, videoConfig.resolution.width / 2, videoConfig.resolution.height / 20);
task.watermark = &watermark;

(可选)设置混流背景图片

如果需要背景图片的 URL,请联系 ZEGO 技术支持获取。

task.backgroundImageURL = "preset-id://zegobg.png";

(可选)设置混流声浪回调

注意

在视频场景中,不建议打开声浪开关,否则web端拉HLS协议的流可能会出现兼容性问题。

可通过设置 enableSoundLevel 参数选择是否开启混流的声浪回调通知,开启后(取值为 “True”)用户拉混流时可通过 onMixerSoundLevelUpdate 回调收到每条单流的声浪信息。

task.enableSoundLevel = true;

(可选)设置高级配置

高级配置适用于一些定制化需求,例如:配置视频编码格式。

如果需要了解具体支持的配置项信息,请联系 ZEGO 技术支持。

说明

普通场景无需设置高级配置。

// 指定混流输出视频格式为 vp8 ,使用特定的推流协议才能生效。
task.advancedConfig.insert({"video_encode", "vp8"});

// 如果混流输出视频格式设为 vp8,请同步设置音频编码格式为 LOW3,设置方可生效。
ZegoMixerAudioConfig audioConfig = ZegoMixerAudioConfig();
audioConfig.codecID = ZEGO_AUDIO_CODEC_ID_LOW3;
task.audioConfig = audioConfig;

3 开始混流任务

完成了 ZegoMixerTask 混流任务对象的配置后,调用 startMixerTask 接口开始这个混流任务,并在回调中接收开始混流任务结果。

注意

如果需要 Web 端播放混流 CDN 资源,在使用 CDN 录制时,音频编码请选择 AAC-LC,由于部分浏览器(如 Google Chrome 和 Microsoft Edge)不兼容 HE-AAC 音频编码格式,会导致录制文件无法播放。

engine->startMixerTask(task, [=](ZegoMixerStartCallback result){
    if (result.errorCode == 0) {
        print("Start mixer task succeed");
    } else{
        printf("start mixer task failed: errorCode=%d", errorCode);
    }
});

4 更新混流任务的配置

当混流信息发生变更时,例如混流的输入流列表发生增减、调整混流视频输出码率等,修改该混流任务对象的参数,然后再调用一次 startMixerTask 接口即可更新配置。

注意

更新混流任务的配置时,“taskID” 不可更改。

/*
 * 下面代码演示进行混流任务途中添加一条输入流,左中右布局
 *
 * |--------------|-----------|------------|
 * |              |           |            |
 * |   stream-1   |  stream-2 |  stream-3  |
 * |              |           |            |
 * |--------------|-----------|------------|
 */

ZegoMixerInput inputStreamLeft;
inputStreamLeft.streamID = "stream-1";
inputStreamLeft.contentType = ZEGO_MIXER_INPUT_CONTENT_TYPE_VIDEO;
inputStreamLeft.layout = ZegoRect(0, 0, videoConfig.width/3, videoConfig.height);

ZegoMixerInput inputStreamCenter;
inputStreamCenter.streamID = "stream-2";
inputStreamCenter.contentType = ZEGO_MIXER_INPUT_CONTENT_TYPE_VIDEO;
inputStreamCenter.layout = ZegoRect(videoConfig.width/3, 0 , videoConfig.width/3, videoConfig.height);

ZegoMixerInput inputStreamRight;
inputStreamRight.streamID = "stream-3";
inputStreamRight.contentType = ZEGO_MIXER_INPUT_CONTENT_TYPE_VIDEO;
inputStreamRight.layout = ZegoRect(videoConfig.width*2/3, 0 , videoConfig.width/3, videoConfig.height);

// 重新设置混流对象的输入流列表
task.inputList = {inputStreamLeft, inputStreamCenter, inputStreamRight};

// 再调用一次启动混流任务接口,即可更新混流配置
engine->startMixerTask(task, [=](ZegoMixerStartCallback result){
    if (result.errorCode == 0) {
        print("Start mixer task succeed");
    } else{
        printf("start mixer task failed: errorCode=%d", errorCode);
    }
});

5 停止混流

调用 stopAutoMixerTask 接口停止混流。

// 传入之前创建的混流任务对象
engine->stopMixerTask(task, [=](int errorCode){
    if (errorCode == 0) {
        print("Stop mixer task succeed");
    } else{
        printf("Stop mixer task failed: errorCode=%d", errorCode);
    }
});

自动混流使用步骤

1 初始化并登录房间

请参考 快速开始 - 实现流程 的 “创建引擎” 和 “登录房间” 完成房间登录。

注意
  • 自动混流的前置条件为目标房间存在。
  • 发起自动混流的用户可以混房间内已有的其他用户推的流(只能混音频流),而自己不用登录房间或者在房间内推流。

2 设置混流配置

ZegoAutoMixerTask 是 SDK 中定义的自动混流任务配置对象,通过配置该对象可定制化自动混流任务。

struct ZegoAutoMixerTask
{
    // 自动混流任务的任务 ID
    std::string taskID;

    // 自动混流任务的房间 ID
    std::string roomID;

    // 自动混流任务的音频配置
    ZegoMixerAudioConfig audioConfig;

    // 自动混流任务的输出流列表
    std::vector<ZegoMixerOutput> outputList;

    // 是否开启自动混流的声浪回调通知
    bool enableSoundLevel;

    // 构造一个自动混流任务对象
    ZegoAutoMixerTask(): taskID(), roomID(), outputList(),audioConfig(),enableSoundLevel(false){
            }
};

创建自动混流任务对象

新建一个自动混流任务对象,然后分别设置输入、输出等参数。

  • 一个房间内只能存在一个自动混流任务 ID,即保证自动混流任务 ID 的唯一性,建议自动混流任务 ID 与房间 ID 关联,可直接使用房间 ID 作为自动混流任务 ID。
  • 需要自动混流的房间 ID,如果房间不存在则无法自动混流。
ZegoAutoMixerTask task;
task.taskID = "taskID1";
task.roomID = "roomID1";

(可选)设置自动混流音频配置

通过 ZegoMixerAudioConfig 设置自动混流音频相关配置,主要包括音频码率、声道数、编码 ID,以及多路音频流混音模式。

// 音频码率,单位为 kbps,默认为 48 kbps,开始混流任务后不能修改
task.audioConfig.bitrate = 48;
// 音频声道,默认为 Mono 单声道
task.audioConfig.channel = ZEGO_AUDIO_CHANNEL_MONO;
// 编码 ID,默认为 ZEGO_AUDIO_CODEC_ID_DEFAULT
task.audioConfig.codecID = ZEGO_AUDIO_CODEC_ID_DEFAULT;
// 多路音频流混音模式,默认为 ZEGO_AUDIO_MIX_MODE_RAW
task.audioConfig.mixMode = ZEGO_AUDIO_MIX_MODE_RAW;

通过 channel 参数可以修改音频声道,目前支持如下音频声道:

枚举值说明适用场景
ZEGO_AUDIO_CHANNEL_UNKNOWN未知。-
ZEGO_AUDIO_CHANNEL_MONO单声道。只有单声道的场景。
ZEGO_AUDIO_CHANNEL_STEREO双声道。有双声道的场景。

通过 codecID 参数可以修改编码 ID,目前支持如下编码 ID:

枚举值说明适用场景
ZEGO_AUDIO_CODEC_ID_DEFAULT默认值。根据调用 [createEngine] 时的 [scenario] 决定。
ZEGO_AUDIO_CODEC_ID_NORMAL码率范围 10 kbps ~ 128 kbps;支持双声道;延迟在 500ms 左右。与 Web SDK 互通时需要服务端转码;转推 CDN 时不需要服务端云转码。可用于 RTC 和 CDN 推流。
ZEGO_AUDIO_CODEC_ID_NORMAL2兼容性好,码率范围 16 kbps ~ 192 kbps;支持双声道;延迟 350ms 左右;相同码率下(较低码率),音质弱于 [Normal]。与 Web SDK 互通时需要服务端转码;转推 CDN 时不需要服务端云转码。可用于 RTC 和 CDN 推流。
ZEGO_AUDIO_CODEC_ID_NORMAL3不推荐使用。仅可用于 RTC 推流。
ZEGO_AUDIO_CODEC_ID_LOW不推荐使用。仅可用于 RTC 推流。
ZEGO_AUDIO_CODEC_ID_LOW2不推荐使用,最大码率为 16 kbps。仅可用于 RTC 推流。
ZEGO_AUDIO_CODEC_ID_LOW3码率范围 6 kbps ~ 192 kbps;支持双声道;延迟在 200ms 左右;相同码率下(较低码率),音质明显好于 [Normal] 与 [Normal2];CPU 开销较低。与 Web SDK 互通时不需要服务端云转码;转推 CDN 时需要服务端转码。仅可用于 RTC 推流。

通过 mixMode 参数可以修改多路音频流混音模式,目前支持如下多路音频流混音模式:

枚举值说明适用场景
ZEGO_AUDIO_MIX_MODE_RAW默认模式,无特殊行为。对音频无特殊需求的场景。
ZEGO_AUDIO_MIX_MODE_FOCUSED音频聚焦模式,可在多路音频流中突出某路流的声音。需要突出某路流的声音的场景。

设置自动混流输出列表

通过 ZegoMixerOutput 设置自动混流输出列表,用户可以从列表中的输出目标拉取混流。

ZegoMixerOutput mixerOutput;
// 输出流名为 "output-stream"
// 混流输出目标,URL 或者流 ID
mixerOutput.target = "output-stream";
task.outputList = {mixerOutput};

(可选)设置自动混流声浪回调

注意

在视频场景中,不建议打开声浪开关,否则web端拉HLS协议的流可能会出现兼容性问题。

可通过设置 enableSoundLevel 参数选择是否开启自动混流的声浪回调通知,开启后(取值为 “True”)用户拉混流时可通过 onAutoMixerSoundLevelUpdate 回调收到每条单流的声浪信息。

task.enableSoundLevel = true;

3 开始自动混流任务

完成了 ZegoAutoMixerTask 自动混流任务对象的配置后,调用 startAutoMixerTask 接口开始该自动混流任务,并在 ZegoMixerStartCallback 回调中接收开始自动混流任务结果。

engine->startAutoMixerTask(task,[=](ZegoMixerStartCallback result){
    if(result.errorCode == 0)
    {
        print("Start auto mixer task succeed");
    }
    else
    {
        printf("start auto mixer task failed: errorCode=%d", errorCode);
    }
});

4 停止自动混流

调用 stopAutoMixerTask 接口停止自动混流。

注意

在同一个房间内开启下一个自动混流任务前,请先调用 stopAutoMixerTask 接口结束上一次自动混流任务,以免造成当一个主播已经开启下一个自动混流任务与其他主播混流时,观众依然在一直拉上一个自动混流任务的输出流的情况。若用户未主动结束当前自动混流任务,该任务将在房间关闭后自动结束。

// 传入之前创建的混流任务对象
engine->stopAutoMixerTask(task, [=](int errorCode){
    if (errorCode == 0) {
        print("Stop auto mixer task succeed");
    } else{
        printf("Stop auto mixer task failed: errorCode=%d", errorCode);
    }
});

全自动混流使用步骤

通过 ZEGO 服务端的配置实现每个房间都自动混音频流,详情请联系 ZEGO 技术支持。

常见问题

  1. 能将混流推到第三方 CDN 吗?如何转推多路 CDN?

    若需要将混流推到第三方 CDN,可在 ZegoMixerOutput 的 “target” 参数填写 CDN 的 URL。

    填写的 URL 格式需要为 RTMP 格式:“rtmp://xxxxxxxx”。

    推多路 CDN 就创建 N 个输出流对象 ZegoMixerOutput 放入 ZegoMixerTask 中的 “outputList” 输出列表中。

  2. 如何设置混流中每条流的布局?

ZegoMixerInput 的 “layout” 参数使用示例:

  • 假设指定某条流的左上角坐标为 (50,300),右下角坐标为 (200,450),即 “layout” 参数为 “ZegoRect(50, 300, 200, 450)”。
  • 假设 ZegoMixerTask 的 “videoConfig” 参数中的分辨率 “width = 375; height = 667”。

那么这条流在最终的输出混流中的位置如下所示:

  1. 混流输入对象 ZegoMixerInput 的 “ZegoRect” 布局的比例与这条流本身的分辨率不相符时,画面将如何裁剪?

    SDK 会做等比缩放。假设一条输入流的分辨率为 “720 × 1280”,即比例为 “9:16”,同时这条流的 ZegoMixerInput 的 “layout” 参数为 “ZegoRect(0, 0, 100, 100)”,即比例为 “1:1” 时,画面将会显示这条流的中间部分,即上下部分被裁剪掉。

  2. 参与连麦的主播们想让各自的观众看到自己的视频在混流后的画面布局中位于大窗口,如何混流?

    主播们各自布局再各自发起混流。

    例如:主播 A 设置自己推的流 A 画面布局的宽高大于拉主播 B 的流 B 的布局宽高,然后发起一个混流任务输出一个流 “A_Mix”;主播 B 设置自己推的流 B 画面布局的宽高大于拉主播 A 的流 A 的布局宽高,然后发起混流输出一个流 “B_Mix”。

    即总共需要发起两个混流任务。

  3. 混流的两种方式:“单主播开始直播后就马上开始混流”和“当第二主播加入连麦的时候才开始混流”,这两种方式有什么区别?优劣势是什么?

    从单主播直播开始就启动混流的优点是实现简单,缺点是会多一些额外的混单流时间的 CDN 成本开销。

    从单主播直播开始仅推流,等第二路主播加入连麦时才启动混流。优点是节约成本;缺点是开发实现上会复杂一些,观众端需要先拉取单主播流,主播们连麦开启混流后需要停止拉单主播流,然后改为拉取混流。而上述从头开始混流的方式,观众端不需要做从拉单主播流再到拉混流的一个切换。

  4. 混流是否支持圆形或者方形的画面?

    不支持圆形,方形可通过布局实现。

  5. 在推纯音频混流并设置了背景图时,遇到背景图无法正常进行展示,如何处理?

    在这种情况下,客户需要根据自身业务需求,正确设置输出布局的宽和高,并联系 ZEGO 技术支持配置开启补黑帧。

2025-05-07

Previous

推流视频增强

Next

使用 CDN 直播