互动视频
  • iOS : Objective-C
  • Android
  • macOS
  • Windows
  • Linux
  • Web
  • 小程序
  • Electron
  • 概述
  • 限制说明
  • SDK 下载
  • 快速开始
  • 常用功能
  • 推拉流进阶
  • 视频进阶
  • 音频进阶
  • 其他功能
  • 废弃接口
  • API 文档
  • 常见错误码
  • 常见问题
  • AI教育
  • KTV 合唱
  • 视频直播
  • 视频通话
  • 游戏直播
  • 直播答题
  • 娃娃机
  • 文档中心
  • 互动视频
  • 常用功能
  • 多路混流

多路混流

更新时间:2022-08-18 14:29

1 功能简介

混流是把多路音视频流混合成单流的技术。

1.1 常用场景

  1. 当设备不支持同时拉 N 路流时使用混流。
  2. 在直播时有大量的观看直播的观众,同时需要直播观众的画面以达到整体互动效果时使用混流,能省去客户端界面上的拉 N 路流并布局的步骤。
  3. 需要多个视频画面合成一个视频时使用混流,比如教育类,直播老师和学生的画面。

1.2 优点

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

1.3 使用说明

主播端和观众端均可主动触发混流。SDK 既支持音视频混流,也支持纯音频混流。如需查看后台混流文档,请参考:后台混流接口

开发者在拉流 / 推流成功后开始混流,即需要保证混流使用的单条输入流是存在的;比如主播 A 与观众 B 成功连麦后,成功拉取到观众 B 的画面时开始混主播流和观众 B 的流,也可以根据需求,在其他合适时机进行混流。

注意: 由于主播端和观众端均可主动触发混流,文档中描述的操作方均为主播端观众端。开发者在实际使用中请注意区分接口调用方

2 系统架构图

使用混流功能时,SDK 将流推到 Zego 服务器上,Zego 服务器将指定流混成一路流后再推到 CDN 上,观众从 CDN 上拉混流观看。

3 使用步骤

相关功能的 Demo 源码,请联系 ZEGO 技术支持获取。

本文主要以主播端推流成功后混流为例,其他场景下设置混流的步骤类似,不再赘述。

使用混流功能的主要流程如下:

  1. 推流/拉流成功。
  2. 设置混流配置。
  3. 开始混流。
  4. 拉流观看。(获取到混流配置更新通知时广播混流信息通知房间的观众拉流观看,可根据实际需要决定是否采用此提议)
  5. 停止混流。

3.1 前置条件

主播端混流的前置条件为推流成功,请参考:快速集成-推流

注意: 推混流,请指定推流 API (startPublishing:title:flag:startPublishing:title:flag:extraInfo:) 中的 flag 为 ZEGO_MIX_STREAM

3.2 设置混流配置

推流成功后,开始设置混流配置。

3.2.1 设置混流配置的回调

@interface ZegoStreamMixer : NSObject

/**
 设置混流配置更新的回调,当 [ZegoStreamMixer -mixStreamEx:mixStreamID:] 调用成功后,会进行此回调。
 */
- (void)setMixStreamExDelegate:(id<ZegoMixStreamExDelegate>)delegate;

/**
 设置拉取混流时带上音量信息的回调。拉流端可据此实现音浪功能。
 */
- (void)setSoundLevelInMixedStreamDelegate:(id<ZegoLiveSoundLevelInMixedStreamDelegate>)delegate;

@end

3.2.2 指定混流配置参数

ZegoMixStreamConfig 是 SDK 中定义的混流配置参数,其中包含输入流布局、输出流等信息。

注意: ZegoMixStreamConfig 中的 outputFpsoutputBitrateoutputResolutioninputStreamListoutputList 参数都必须指定值。

3.2.2.1 混流音视频数据

  1. 创建 ZegoMixStreamConfig 对象实例。
  2. 设置 ZegoMixStreamConfig 对象的 outputFpsoutputBitrateoutputResolution inputStreamListoutputList 参数值,参数的详细描述以及更多的配置信息请查看 混流配置参数说明,输入流布局示例请查看 布局代码示例。

3.2.2.2 混流纯音频数据

如果开发者想混流纯音频数据ZegoMixStreamConfig 的部分参数配置需要特殊处理。

  1. 创建 ZegoMixStreamConfig 对象实例。
  2. 设置输入流 ZegoMixStreamInfo 对象的参数值,streamID,top = 0,left = 0,bottom = 1,right = 1,参数的详细描述请查看 输入流类型说明。
  3. 设置 ZegoMixStreamConfig 对象的参数值,inputStreamListoutputList,outputFps = 1,outputBitrate = 1,outputResolution = {1,1},参数的详细描述请查看 混流配置参数说明。

3.3 开始混流

App 组装 ZegoMixStreamConfig 成功后,调用 ZegoStreamMixer 对象的 -mixStreamEx:mixStreamID: 将混流配置发送至 Zego 混流服务器。混流API详细说明请查看 开始混流API。

注意:

  1. 当混流信息发生变更(例如,混流的输入流列表发生增减、调整混流视频输出码率等),开发者仍然需要在合适的时机调用本接口,更新 Zego 混流服务器上的混流配置。
  2. 若混流失败,相关错误码请查看 混流常见错误码。

3.4 实现混流配置更新通知

混流请求发送成功后,调用者可在此回调中获取混流配置的结果及混流 ID。

  1. 实现 ZegoMixStreamExDelegate-onMixStreamExConfigUpdate:mixStream:streamInfo:回调方法。
  2. 根据实际需要处理 ZegoMixStreamResultEx 类型的混流结果信息,比如将混流流名、rtmp、flv 等拉流链接广播给房间观众。此回调中参数的详细描述请查看 混流配置更新通知API。

3.5 停止混流

停止混流也是调用 -mixStreamEx:mixStreamID: 实现。将ZegoMixStreamConfiginputStreamList置为空列表,outputList设置为和开始或更新混流的一致。然后调用 -mixStreamEx:mixStreamID: 即可更新 Zego 混流服务器上的混流配置 config,达到停止混流效果。若停止混流失败,请查看 混流常见错误码。

注意: 开始混流和停止混流使用的mixStreamID需要保持一致。

ZegoMixStreamConfig *emptyConfig = [ZegoMixStreamConfig new];
emptyConfig.inputStreamList = [NSMutableArray array];

// outputCDNUrl 为前面进行混流配置的输出地址
if (outputCDNUrl.length > 0) {
   ZegoMixStreamOutput *o = [ZegoMixStreamOutput new];
   o.target = outputCDNUrl;
   o.isUrl = YES;
   emptyConfig.outputList = [NSMutableArray arrayWithObject:o];
}

[_zegoStreamMixer mixStreamEx:emptyConfig mixStreamID:mixStreamID];

3.6 获取混流前每条流的音量

注意: 此功能根据需要使用。

由于混流会将多条流混成一条流,之前各条流的音量信息也会因此消失,如果要获取混流前各条流的音量信息,就需要做一些额外的设置。

3.6.1 修改混流配置

推流方,在混流配置中增加了两项设置:

  1. 设置 ZegoMixStreamConfig 中的 withSoundLevel=true
  2. 设置 ZegoMixStreamInfo 中的 soundLevelID参数。

3.6.2 设置音量信息回调

拉流方,初始化 ZegoStreamMixer 实例,然后设置带音量信息的回调。

self.zgStreamMixer = [[ZegoStreamMixer alloc] init];
[self.zgStreamMixer setSoundLevelInMixedStreamDelegate:self];

3.6.3 获取音量信息

拉流方实现 ZegoLiveSoundLevelInMixedStreamDelegate-onSoundLevelInMixedStream: 回调方法。可以处理 该回调中带回的 soundLevelList 参数,参数中带有音量信息 soundLevel 和混流配置时设置的流标记信息 soundLevelID。此回调中参数的详细描述请查看 混流音量回调API。

注意: -onSoundLevelInMixedStream: 这个回调是高频的同步回调,不要在回调中处理业务逻辑。

4 接口说明

以下部分是混流 API 的详细说明,例如 API 中参数的含义,使用值范围等。

4.1 混流配置回调API

@interface ZegoStreamMixer : NSObject

/**
 设置混流配置更新的回调,当 [ZegoStreamMixer -mixStreamEx:mixStreamID:] 调用成功后,会进行此回调。
 */
- (void)setMixStreamExDelegate:(id<ZegoMixStreamExDelegate>)delegate;

/**
 设置拉取混流时带上音量信息的回调。拉流端可据此实现音浪功能。
 */
- (void)setSoundLevelInMixedStreamDelegate:(id<ZegoLiveSoundLevelInMixedStreamDelegate>)delegate;

@end

4.1.1 混流配置更新通知API

/**
 混流配置信息的回调接口
 */
@protocol ZegoMixStreamExDelegate <NSObject>

@optional
/**
 混流配置更新的回调

 * 调用 ZegoStreamMixer -setMixStreamExDelegate: 设置了回调监听,并调用 ZegoStreamMixer -mixStreamEx:mixStreamID: 设置混流配置后,SDK 通过此 API 通知调用方混流配置结果。
 * 注意:
 * 1. 如果输出流列表中输出流使用 url 作为输出,则此回调中的 info 参数中不会包含有效的 rtmp、hls、flv 格式的混流信息,即使用该参数中的 url 不能拉取混流。
 * 2. 常见错误码及其含义请参考 ZegoError 中 kMixStream 开头的错误码定义。

 @param errorCode 错误码,0 表示混流启动成功,非 0 表示混流启动失败。
 @param mixStreamID 混流任务 ID,与 ZegoStreamMixer -mixStreamEx:mixStreamID: 中的 mixStreamID 参数一致。
 @param info 混流播放信息
 */
- (void)onMixStreamExConfigUpdate:(int)errorCode mixStream:(NSString *)mixStreamID streamInfo:(ZegoMixStreamResultEx *)info;

@end

4.1.2 混流音量回调API

/**
 混流中的发言者及其说话音量的回调通知接口
 */
@protocol ZegoLiveSoundLevelInMixedStreamDelegate <NSObject>

@optional
/**
 混流中的发言者及其说话音量信息的回调

 * 注意:此接口是高频率同步回调,每秒钟10次通知,不拉流没有通知;请勿在该回调中处理耗时任务。

 @param soundLevelList 混流中各单流的音量信息列表
 */
- (void)onSoundLevelInMixedStream:(NSArray<ZegoSoundLevelInMixedStreamInfo *> *)soundLevelList;

@end

4.2 混流配置参数

ZegoMixStreamConfig 是 SDK 中定义的混流配置参数,其中包含输入流布局、输出流等信息。**ZegoMixStreamConfig 类型如下:**

/** 混流配置 */
@interface ZegoMixStreamConfig : NSObject

/**  混流输出视频帧率,值范围:[1,30],根据网络情况设定值,帧率越高画面越流畅 */
@property int outputFps;

/**  输出码率控制模式,0 表示 CBR 恒定码率,1 表示 CRF 恒定质量,默认为 0 
 *   CRF 恒定质量 表示保证视频的清晰度在固定水平上,因此若采用此控制模式,码率会根据网速的变化波动
 *   比如游戏类直播时,为了让观众看到比较流畅的操作类画面会使用恒定质量模式,提升视频质量
 */
@property int outputRateControlMode;

/**  输出码率,仅当输出码率控制模式设置为 CBR恒定码率 时此设置值生效
 *   视频码率值范围: <= 10M,此参数单位是 bps,1M = 1 * 1000 * 1000 bps
 */
@property int outputBitrate;

/**  输出分辨率 
 *   分辨率宽必须大于等于 输入流列表中所有输入流中最大的分辨率宽,即right布局值,且输入流的布局位置不能超出此值规定的范围
 *   分辨率高必须大于等于 输入流列表中所有输入流中最大的分辨率高,即bottom布局值,,且输入流的布局位置不能超出此值规定的范围
 */
@property CGSize outputResolution;

/**  输入流列表,SDK 根据输入流列表中的流进行混流 */
@property (strong) NSMutableArray<ZegoMixStreamInput*> *inputStreamList;

/**  输出流列表 */
@property (strong) NSMutableArray<ZegoMixStreamOutput*> *outputList;

/**  输出质量,输出码率控制模式设置为 CRF恒定质量 时有效,有效值范围 [0,51],默认值是 23 
 *   若想视频质量好点,在23的基础上降低质量值测试调整
 *   若想文件大小小一点,在23的基础上升高质量值测试调整,以 x 值下的文件大小为例, x + 6 下的文件大小是 x 值下文件大小的一半,x - 6 下的文件大小是 x 值下 文件大小的两倍
 */
@property int outputQuality;

/**  混流输出音频编码格式,默认值为 0。可选值为 0--默认编码;1--可选编码
 *   0--默认编码 在低码率下,编码后的音质要明显好于 1--可选编码,在码率较大后,达到128kbps及以上,两种编码后的音质近乎相同
 *   1--可选编码 的优点在于低复杂性,能兼容更多的设备播放;但是目前经过 0--默认编码 编码后的音频不能正常播放的情况很少 
 */
@property int outputAudioConfig;

/**  输出音频码率,码率范围值是[10000, 192000]
 *   若音频编码格式采用默认音频编码--outputAudioConfig 参数填0,采用 1/2声道时,建议码率值是 48k/64k,可根据需要在此基础上调整
 *   若音频编码格式采用可选音频编码--outputAudioConfig 参数填1,采用 1/2声道时,建议码率值是 80k/128k,可根据需要在此基础上调整
 */
@property int outputAudioBitrate;

/** 用户自定义数据 */
/** 发送的自定义数据接收端通过媒体次要信息 onRecvMediaSideInfo 接口回调 */
@property NSData* userData;

/** 混流声道数,默认为单声道*/
@property int channels;

/** 混流背景颜色,前三个字节为 RGB,即 0xRRGGBBxx 
 *  例如:选取RGB为 #87CEFA 作为背景色,此处写为 0x87CEFA00
 */
@property int outputBackgroundColor;

/** 混流背景图,支持预设图片,如 (preset-id://xxx)
 *  此值由 ZEGO 提供,开发者先将背景图提供给 ZEGO,ZEGO 设置后再反馈背景图片的设置参数
 */
@property (copy) NSString *outputBackgroundImage;

/** 是否开启音浪。true:开启,false:关闭 */
@property BOOL withSoundLevel;

/** 扩展信息 */
@property int extra;

/** 混流水印 */
@property (nonatomic, strong) ZegoMixStreamWatermark *watermark;

/** 混流输入为一条流时,是否混流;非必填。true:不对单流混流,混流输出的流属性与单流一致(分辨率,编码格式等),混流配置中设置的分辨率等配置无效;false:混单流,混流服务器会对此单流重新编解码,混流输出的流属性与混流配置相同;若需要开启此功能,请先与即构技术支持联系 */
@property (nonatomic, assign) BOOL singleStreamPassThrough;

/** 高级配置选项,适用于某些定制化的需求,格式 "config1=xxx;config2=xxx", 请与即构技术支持联系了解可支持字段 */
@property (nonatomic, copy) NSString *advancedConfig;
@end

4.2.1 输入流类型

inputStreamList 为输入流列表,列表中是 ZegoMixStreamInput 对象。 表示流 ID 为 streamID 的流,在输出的混流中的布局位置,根据所需的输入流个数构建 N 个 ZegoMixStreamInput 对象放入输入流列表。ZegoMixStreamInput 结构如下:

/** 混流图层信息,原点在左上角 */
@interface ZegoMixStreamInput : NSObject

/** 要混流的单流ID */
@property (copy) NSString *streamID;

/** 混流图层左上角坐标的第二个值 */
@property int top;

/** 混流图层左上角坐标的第一个值,即左上角坐标为 (left, top) */
@property int left;

/** 混流图层右下角坐标的第二个值 */
@property int bottom;

/** 混流图层右下角坐标的第一个值,即右下角坐标为 (right, bottom) */
@property int right;

/** 音浪ID,用于标识用户,注意大小是32位无符号数 */
@property unsigned int soundLevelID;

/** 推流内容控制, 0表示音视频都要, 1表示只要音频, 2表示只要视频。default:0。*/
@property int contentControl;

/**
 *  原点在左上角,top/bottom/left/right 定义如下:
 *
 *  (left, top)-----------------------
 *  |                                |
 *  |                                |
 *  |                                |
 *  |                                |
 *  -------------------(right, bottom)
 */

@end

备注: ZegoMixStreamInput 的使用示例:假设指定某条流的左上角坐标为(50,300),右下角坐标为(200,450),这条流在最终的输出混流中的位置如下所示:

4.2.2 输出流类型

outputList 为输出流列表,列表中是 ZegoMixStreamOutput 对象。 表示流输出为 url 或者流名,如果需要将流推到 CDN 上,采用 url;不需要将流推到 CDN 上时,由调用者决定采用 url 或者流名。注意: 如果需要配置单路流,输出流列表中只放一个 ZegoMixStreamOutput 对象;如果需要配置多路流,输出流列表中放 N 个 ZegoMixStreamOutput 对象。ZegoMixStreamOutput 结构如下:

/** 混流输出配置 */
@interface ZegoMixStreamOutput : NSObject

/**  isUrl 为 YES,则此值为 Url;否则为流名 */
@property (copy) NSString *target;

/**  输出是否为流名,或 Url */
@property BOOL isUrl;

@end

4.2.3 混流水印

watermark 混流水印,在输出的流中的指定位置上增加水印,其类型 ZegoMixStreamWatermark 结构如下:

/** 混流水印 */
@interface ZegoMixStreamWatermark : NSObject

/** 水印图片 */
@property (nonatomic, copy) NSString *image;

/** 混流画布左上角坐标的第一个值,即左上角坐标为 (left, top) */
@property int left;

/** 混流画布左上角坐标的第二个值 */
@property int top;

/** 混流画布右下角坐标的第一个值,即右下角坐标为 (right, bottom) */
@property int right;

/** 混流画布右下角坐标的第二个值 */
@property int bottom;

/**
 *  原点在左上角,top/bottom/left/right 定义如下:
 *
 *  (left, top)-----------------------
 *  |                                |
 *  |                                |
 *  |                                |
 *  |                                |
 *  -------------------(right, bottom)
 */

@end

4.3 开始混流API

@interface ZegoStreamMixer : NSObject

/**
 开始混流,支持单路或者多路混流输出

 @param config 混流配置
 @param mixStreamID 混流ID
 @return >0 表示调用成功,且返回值是调用序号seq,<=0 表示调用失败
 @discussion 每次需要更新混流配置时,都可以调用此接口;通过返回的seq区分回调
 */
- (int)mixStreamEx:(ZegoMixStreamConfig *)config mixStreamID:(NSString *)mixStreamID;

@end

5 常见错误码

错误码 说明
0 混流成功
1 混流失败
2 混流输入参数错误
3 混流鉴权失败
4 ~ 17 混流失败,联系ZEGO技术支持解决
150 混流的输入流不存在。请检查混流的inputStreamList里面的流是否正在推流
151 混流失败。请联系ZEGO技术支持解决
152 停止混流失败。请联系ZEGO技术支持解决
153 输入参数错误,输入参数错误,请检查 1) inputStreamList里面每个layer的输入参数是否正确,比如输出的码率、帧率都不能为空; 2) 混流mixoutput的输出分辨率小于混流mixinput参数的输入分辨率
154 输出参数错误,请检查output的输出参数是否正确,比如输出的码率、帧率都不能为空
155 输入分辨率格式错误,请检查输入分辨率大小是否已经大于混流输出设置的分辨率大小,例如输入流中的布局的分辨率宽高是否大于混流配置参数中的混流输出的视频分辨率宽高
156 输出分辨率格式错误,请检查输出分辨率格式是否正确
157 混流没开,请联系ZEGO技术支持开启混流模式
158 混流超过路数限制, 默认9路
159 调度失败,请联系ZEGO技术支持解决
160 主播停止混流失败
170 混流水印参数错误
171 混流水印图片为空

6 FAQ

Q1:用 Zego 的混流,能将混流推到第三方 CDN 吗?如何转推多路 CDN?

  答:若需要混流推到指定 CDN,对放入 ZegoMixStreamConfig 中的 outputList 输出列表的输出流对象 ZegoMixStreamOutput 采用URL做输出 target; 输出流对象 ZegoMixStreamOutput 采用流名做输出 target,混流推到 SDK 指定的 CDN。 推多路 CDN 就创建 N 个输出流 ZegoMixStreamOutput 放入 ZegoMixStreamConfig 中的 outputList 输出列表中。

Q2:混流的输出分辨率设置为 16:9,但是原图是 4:3 的,混流的画面将如何裁剪?

  答:SDK 会做等比缩放,假设混流画面的高远低于原图画面的高,SDK 在做缩放时能刚好满足混流画面的宽时,裁剪的部分就是 SDK 缩放原图后超出混流画面高的部分。

Q3:连麦的主播想让各自的观众看到自己的视频在混流后的画面上位于大窗口,如何混流?

  答:各自布局再各自混流;A 主播混流布局时设置自己推的流 A 布局的宽高大于拉 B 主播的流 B 的布局宽高,再调用混流接口输出 A_Mix;B 主播混流布局时设置自己推的流 B 布局的宽高大于拉 A 主播的流 A 的布局宽高,再调用混流接口输出 B_Mix。

Q4:调用混流返回失败,查询到是 startPublishflag 参数设置为ZEGO_SINGLE_ANCHOR 导致的,这是什么原因?

  答:采用单主播模式推流,是直接将流推到 CDN 上不经过 Zego 服务器,混流的实现是主播推流到 Zego 服务器,再由 Zego 服务器将指定流混成一路流推到 CDN 上。

Q5:混流的两种方式:1)主播开始直播后就开始混流,2)只有第二主播请求要连麦的时候才开始混流,这两种方式有什么区别?优劣势是什么?

  答:由于混流会推到 CDN 上,从头开始混流比第二主播请求连麦时才开始混流会多一些成本花销,具体的成本由主播开始直播到连麦的时间间隔决定。 如果采用 Zego SDK 拉流,第二路主播请求连麦时开始混的方式,开发实现上会复杂一些,观众端需要先拉取主播流,混流更新时再停止拉主播流改为拉取混流;而从头开始混的方式,观众端不需要做从拉主播流再到拉混流的一个切换。

Q6:你们混流是否支持圆形或者方形的画面?

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

本篇目录