1、简介

混流是把多路音视频流混合成单流的技术。本文讲述zego即构科技实时音视频SDK高级功能之一:混流功能,以iOS环境为例。

主播端和观众端均可主动触发混流。SDK 既支持音视频混流,也支持纯音频混流。SDK 对设置混流的时机没有硬性要求,建议开发者在拉流 /
推流后,或根据需求,在其他合适时机进行混流。

混流的主要流程是:

1.设置混流配置。

2.获取混流配置更新通知。

本文主要以主播端 / 观众端推流后混流为例,其他时机时设置混流的步骤类似,不再赘述。

2、步骤

按照上述流程,SDK API 调用过程如下所示。

混流模块定义在 zego-api-mix-stream-oc.h 中。

2.1 前置条件

主播端推流后混流的前置条件为推流,请参考文章:iOS-推流
<https://blog.csdn.net/sinat_20146421/article/details/83692318>

请注意:

1.推混流,请指定推流 API (startPublishing:title:flag: 或
startPublishing:title:flag:extraInfo:) 中的 flag 为 ZEGO_MIX_STREAM。

2.如果想实现观众端拉流混流,注意使观众端实现ZegoLivePublisherDelegate协议。

2.2 设置混流配置

主播端或客户端推流成功后,开始设置混流配置。

ZegoCompleteMixStreamConfig 是 SDK
中定义的混流配置参数对象,其中包含输入流信息、输出流布局等信息,开发者需要指定。具体结构为:

混流API
@interface ZegoStreamMixer : NSObject /** 设置混流配置的回调 */ -
(void)setDelegate:(id<ZegoMixStreamDelegate>)delegate; /** 设置拉取混流时带上音量信息的回调
note: 可以通过这个回调实现音浪的功能。 */ -
(void)setSoundLevelInMixedStreamDelegate:(id<ZegoLiveSoundLevelInMixedStreamDelegate>)delegate;
@end
ZegoCompleteMixStreamConfig 是 SDK
中定义的混流配置参数对象,其中包含输入流信息、输出流布局等信息,开发者需要指定。具体结构为:
/** 混流配置 */ @interface ZegoCompleteMixStreamConfig : NSObject /** outputIsUrl
为 YES,则此值为 Url;否则为流名 */ @property (copy) NSString *outputStream; /** 输出为流名,或
Url */ @property BOOL outputIsUrl; /** 输出帧率 */ @property int outputFps; /**
输出码率 */ @property int outputBitrate; /** 输出音频码率 */ @property int
outputAudioBitrate; /** 输出分辨率 */ @property CGSize outputResolution; /**
音频编码,默认为 0 */ @property int outputAudioConfig; /** 输入流列表 */ @property (strong)
NSMutableArray<ZegoMixStreamInfo*> *inputStreamList; /** 用户自定义数据 */ @property
NSData* userData; /** 混流声道数,默认为单声道*/ @property int channels; /** 混流背景颜色,前三个字节为
RGB,即 0xRRGGBBxx */ @property int outputBackgroundColor; /** 混流背景图,支持预设图片,如
(preset-id://xxx) */ @property (copy) NSString *outputBackgroundImage; /**
是否开启音浪。true:开启,false:关闭 */ @property BOOL withSoundLevel; @end
其中,inputStreamList 为输入流列表,列表中是 ZegoMixStreamInfo 对象。表示流 ID 为 streamID
的流,在输出的混流中的布局位置。
/** 混流图层信息,原点在左上角 */ @interface ZegoMixStreamInfo : 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表示音视频都要, 2表示只要视频。default:0 */ @property
int contentControl; /** * 原点在左上角,top/bottom/left/right 定义如下: * * (left,
top)----------------------- * | | * | | * | | * | | *
-------------------(right, bottom) */ @end
ZegoMixStreamInfo
的使用示例:假设指定某条流的左上角坐标为(50,300),右下角坐标为(200,450),这条流在最终的输出混流中的位置如下所示:

2.3 开始混流

App 组装 ZegoCompleteMixStreamConfig 成功后,调用
mixStream:(ZegoCompleteMixStreamConfig *)completeMixConfig seq:(int)seq
将混流配置发送至 Zego 混流服务器,并触发混流。

当混流信息发生变更(例如,混流的输入流列表发生增减、调整混流视频输出码率等),开发者仍然需要在合适的时机调用本接口,更新混流配置。
@interface ZegoStreamMixer : NSObject /** 开始混流 @param completeMixConfig 混流配置
@param seq 请求序号,回调会带回次 seq @return true 成功,等待回调,false 失败 @discussion
每次需要更新混流配置时,都可以调用此接口;如果需要多次调用,可以通过传入不同的 seq 区分回调 */ -
(bool)mixStream:(ZegoCompleteMixStreamConfig *)completeMixConfig seq:(int)seq;
@end
如果要混流纯音频数据,ZegoCompleteMixStreamConfig 的部分参数配置需要特殊处理:

*
ZegoMixStreamInfo 纯音频配置规则:top / left / bottom / right 不能全设置为 0,或全设置为
1。推荐配置:top = 0,left = 0,bottom = 1,right = 1。

*
ZegoCompleteMixStreamConfig 纯音频配置规则:outputFps 不能设置为 0。推荐配置:outputFps =
1,outputResolution = (1,1)。

2.4 混流配置更新通知

混流请求发送成功后,调用者可在此回调中获取混流配置的结果及混流 ID。
ZegoLiveRoomApi-Publisher.h /** 混流配置更新结果回调 @param errorCode 错误码,0 表示没有错误
@param mixStreamID 混流ID @param info 混流播放信息 @attention 调用 [ZegoLiveRoomApi
(Publisher) -mixStream:seq:] 设置混流配置后,通过此 API 通知调用方 */ -
(void)onMixStreamConfigUpdate:(int)errorCode mixStream:(NSString *)mixStreamID
streamInfo:(NSDictionary *)info;
常见错误码及含义如下

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

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

首先,在推流方,在混流配置中增加了两项设置,
withSoundLevel用于标记混流时是否要附带上各条流的音量信息,soundLevelID用于标记各条流,即用于标记推这条流的用户。
@interface ZegoCompleteMixStreamConfig : NSObject /** 是否开启音浪。true:开启,false:关闭
*/ @property BOOL withSoundLevel; @end @interface ZegoMixStreamInfo : NSObject
/** 音浪ID,用于标识用户,注意大小是32位无符号数 */ @property unsigned int soundLevelID; @end
其次,在拉流方,也需要设置对应的回调 ZegoLiveSoundLevelInMixedStreamDelegate,在回调中带回的
soundLevelList 里面就会有之前设置的流标记信息 soundLevelID 和音量信息
soundLevel。注意,这个回调是高频的同步回调,不要在回调中处理业务逻辑。
@protocol ZegoLiveSoundLevelInMixedStreamDelegate <NSObject> @optional /**
混流中,显示发言者及音量大小的回调。每秒钟10次通知,不拉流没有通知 */ -
(void)onSoundLevelInMixedStream:(NSArray<ZegoSoundLevelInMixedStreamInfo *>
*)soundLevelList; @end /** 设置拉取混流时带上音量信息的回调 note: 可以通过这个回调实现音浪的功能。 */ -
(void)setSoundLevelInMixedStreamDelegate:(id<ZegoLiveSoundLevelInMixedStreamDelegate>)delegate;
2.6 停止混流

停止混流也是调用 mixStream:(ZegoCompleteMixStreamConfig *)completeMixConfig
seq:(int)seq 实现。

操作步骤为:

*
将之前的 completeMixConfig 对象中的 inputStreamList 置为空列表,即清空输入列表内容

*
调用 mixStream:(ZegoCompleteMixStreamConfig *)completeMixConfig seq:(int)seq 更新
completeMixConfig

3、混流系统架构图