本文中含有需要您注意的重要提示信息,忽略该信息可能对您的业务造成影响,请务必仔细阅读。
本文介绍连麦互动的操作步骤和示例代码,助您快速接入。
方案介绍
直播推流SDK互动版是基于实时音视频ARTC来实现连麦方案,帮助客户实现超低延时、更多人数的直播实时互动,一般流程如下:
连麦前 | 主播侧:使用ARTC连麦推流地址进行推流,推流地址前缀为artc。 观众侧:拉取CDN流进行观看。 | ||
连麦中 | 直播侧:
连麦观众:
观众侧:拉取CDN流进行观看。 | ||
结束连麦 | 主播侧:使用ARTC连麦推流地址进行推流,推流地址前缀为artc。 连麦观众:连麦观众切换为普通观众,停止ARTC推流和ARTC拉流,切换为拉取CDN流进行观看。 观众侧:拉取CDN流进行观看。 |
集成说明
请先完成实时音视频SDK Demo配置。具体操作,请参见SDK Demo试用。
直播连麦互动场景不同于一般直播场景,需使用连麦地址进行推拉流,您需要提前生成连麦地址。连麦地址生成,请参考步骤二:生成连麦互动推拉流地址。
您需要提前集成推流SDK,目前支持以下端的集成:Android端SDK集成、iOS端SDK集成、Windows端SDK集成。
集成步骤
步骤一:开通直播连麦服务
具体开通直播连麦功能方式,请参见直播连麦快速入门。
步骤二:生成连麦互动推拉流地址
您可以通过控制台或自定义拼接生成主播和连麦观众的推拉流地址,以及普通观众(非连麦观众)的CDN播放地址。
方法二:控制台生成(开发阶段)
步骤三:创建推流对象
主播端和连麦观众端都需要执行该操作。
创建AlivcLivePushConfig推流配置对象
创建AlivcLivePushConfig推流配置对象,指定当前推流模式livePushMode为AlivcLivePushInteractiveMode,设置分辨率、帧率、码率等配置信息。
重要如果使用场景为Native与Web连麦互通,则Native端(Android/iOS)必须使用H5兼容模式。否则,Web用户查看Native用户将是黑屏。请在Native端调用AlivcLivePushConfig#setH5CompatibleMode接口,接口详细说明请参考Native SDK API文档。
Android
// 初始化推流配置类 mAlivcLivePushConfig = new AlivcLivePushConfig(); // 设置推流模式,默认普通推流模式 mAlivcLivePushConfig.setLivePushMode(AlivcLiveMode.AlivcLiveInteractiveMode); // 设置分辨率,默认540P mAlivcLivePushConfig.setResolution(AlivcResolutionEnum.RESOLUTION_540P); // 设置帧率,默认20fps mAlivcLivePushConfig.setFps(AlivcFpsEnum.FPS_25); // 设置视频编码Gop,单位秒,默认2秒 mAlivcLivePushConfig.setVideoEncodeGop(AlivcVideoEncodeGopEnum.GOP_TWO); // 打开码率自适应,默认为true mAlivcLivePushConfig.setEnableBitrateControl(true); // 设置横竖屏,默认为竖屏,可设置home键向左或向右横屏 mAlivcLivePushConfig.setPreviewOrientation(AlivcPreviewOrientationEnum.ORIENTATION_PORTRAIT); // 设置音频编码模式,默认AAC-LC mAlivcLivePushConfig.setAudioProfile(AlivcAudioAACProfileEnum.AAC_LC); // 设置视频编码模式,默认硬编 mAlivcLivePushConfig.setVideoEncodeMode(AlivcEncodeModeEnum.Encode_MODE_HARD); // 设置音频编码模式,默认软编 mAlivcLivePushConfig.setAudioEncodeMode(AlivcEncodeModeEnum.Encode_MODE_SOFT); // 设置摄像头前后置,默认前置 mAlivcLivePushConfig.setCameraType(AlivcLivePushCameraTypeEnum.CAMERA_TYPE_FRONT); // 设置App推后台或暂停时推图片 mAlivcLivePushConfig.setPausePushImage("TODO: Image Path"); // 设置弱网推图片 mAlivcLivePushConfig.setNetworkPoorPushImage("TODO: Image Path");
iOS
AlivcLivePushConfig *rtcPushConfig = [[AlivcLivePushConfig alloc] init]; rtcPushConfig.livePushMode = AlivcLivePushInteractiveMode; rtcPushConfig.resolution = AlivcLivePushResolution540P; rtcPushConfig.fps = AlivcLivePushFPS20; rtcPushConfig.enableAutoBitrate = true; rtcPushConfig.orientation = AlivcLivePushOrientationPortrait; rtcPushConfig.enableAutoResolution = YES;
Windows
AlivcLivePushConfig config_; config_.mTargetVideoBitrate = video_bitrate_; config_.audioProfile = AlivcLiveHighQualityMode; config_.audioProfile = AlivcLiveStereoHighQualityMode; config_.height = 720; config_.width = 1280; if (config_.height > config_.width) { config_.mPreviewOrientation = AlivcLivePreviewOrientationPortRait; } else { config_.mPreviewOrientation = AlivcLivePreviewOrientationLandscape; } config_.frameRate = AlivcLiveFrameRateFps30; config_.mVideoEncodeGop = AlivcLiveVideoEncodeGopTwo; config_.mResolution = AlivcLiveResolutionSelfDefine; config_.externMainStream = true; config_.mLivePushMode = AlivcLiveInteractiveMode;
创建AlivcLivePusher
方式一:连麦观众仅能选择语音连麦或视频连麦中的一种,且不能切换
如果是纯音频推流,创建AlivcLivePushConfig推流配置对象时,需要执行以下代码指定纯音频推流模式。
非纯音频推流场景,无需执行。纯音频推流不需要调用预览接口,直接调用开始推流接口。
Android
mAlivcLivePushConfig.setAudioOnly(true);
iOS
rtcPushConfig.audioOnly = YES;
Windows
config_.mAudioOnly = true;
方式二:连麦观众可以随时在语音连麦和视频连麦进行切换
如果允许连麦观众在语音和视频间进行切换,具体请参见观众连麦视频/语音切换方案。
连麦互动模式下推流
使用连麦互动模式下推流地址URL进行推流,推流地址获取方式请参见步骤二:生成连麦互动推拉流地址。
Android
alivcLivePusher.startPreview(context, frameLayout, isAnchor); // 主播(大窗)isAnchor为true alivcLivePusher.startPushAysnc("artc://live.aliyun.com/push/6375?timestamp=1661596947&token=XXX&userId=7135&sdkAppId=XXX"); //主播或连麦观众的推流地址
iOS
[rtcPusher startPushWithURL:@"artc://live.aliyun.com/push/6375?timestamp=1661596947&token=XXX&userId=7135&sdkAppId=XXX"]; //主播或连麦观众的推流地址
Windows
pusher_->startPush("artc://live.aliyun.com/push/6375?timestamp=1661596947&token=XXX&userId=7135&sdkAppId=XXX");
步骤四:创建AliPlayer CDN播放
普通观众端(非连麦观众)需要执行该操作。
如果播放端需要使用AliPlayer进行CDN播放,需要先获取普通观众(非连麦观众)的CDN播放地址。具体操作,请参见步骤二:生成连麦互动推拉流地址。
建议您将普通观众的CDN播放地址从RTMP格式改为HTTP-FLV格式。
在阿里云视频直播控制台生成地址时,会同时生成RTMP与HTTP-FLV的地址,这两个协议里包含的数据内容是一致的,只是网络协议通道不一样。HTTP协议是互联网主要协议,CDN、运营商、中间网络设备等链路中都对HTTP有很长时间的网络优化,HTTP的默认80/443端口号也是常见白名单端口,不容易被禁用,而RTMP协议比较老,其默认端口号是1935有可能被防火墙等设备禁用,导致异常。
因此在综合网络环境下,HTTP-FLV的稳定性、性能(卡顿、延时)会比RTMP更好。
如果是纯音频推流,AliPlayer CDN播放纯音频流时,需要设置启播buffer,加快首帧播放,建议使用HTTP-FLV的播放地址。
只需要在纯音频连麦场景下额外设置启播buffer,视频连麦场景不需要额外设置。纯音频连麦场景的播放地址参见普通观众的CDN播放地址。
Android
mAliPlayer = AliPlayerFactory.createAliPlayer(mContext);
PlayerConfig playerConfig = mAliPlayer.getConfig();
// 起播缓存,越大起播越稳定,但会影响起播时间,可酌情设置
playerConfig.mStartBufferDuration = 1000;
// 卡顿恢复需要的缓存,网络不好的情况可以设置大一些,当前纯音频设置500还好,视频的话建议用默认值3000.
playerConfig.mHighBufferDuration = 500;
mAliPlayer.setConfig(playerConfig);
mAliPlayer.setAutoPlay(true);
iOS
self.cdnPlayer = [[AliPlayer alloc] init];
self.cdnPlayer.delegate = self;
self.cdnPlayer.autoPlay = YES;
//针对纯音频场景需要设置启播buffer,加快首帧播放
AVPConfig *config = [self.cdnPlayer getConfig];
config.enableStrictFlvHeader = YES; //纯音频 或 纯视频 的flv 需要设置 以加快起播
config.startBufferDuration = 1000; //起播缓存,越大起播越稳定,但会影响起播时间,可酌情设置
config.highBufferDuration = 500;//卡顿恢复需要的缓存,网络不好的情况可以设置大一些,当前纯音频设置500还好,视频的话建议用默认值3000.
[self.cdnPlayer setConfig:config];
步骤五:观众连麦
主播A RTC推流
主播A开始推流,调用AlivcLivePusher推流引擎开始主播A的推流。
Android
alivcLivePusher.startPreview(context, frameLayout, isAnchor); alivcLivePusher.startPushAysnc("artc://live.aliyun.com/push/123?timestamp=1661596947&token=XXX&userId=userA&sdkAppId=XXX"); //主播的推流地址
iOS
[rtcPusher startPushWithURL:@"artc://live.aliyun.com/push/123?timestamp=1661596947&token=XXX&userId=userA&sdkAppId=XXX"]; //主播的推流地址
Windows
pusher_->startPush("artc://live.aliyun.com/push/6375?timestamp=1661596947&token=XXX&userId=7135&sdkAppId=XXX");
普通观众(非连麦观众)的CDN播放主播A的流
所有观众观看主播A的直播,调用AliPlayer开始播放主播A的流。
Android
AliPlayer aliPlayer = AliPlayerFactory.createAliPlayer(context); aliPlayer.setAutoPlay(true); aliPlayer.setOnErrorListener(errorInfo -> { aliPlayer.prepare(); }); UrlSource urlSource = new UrlSource(); urlSource.setUri("http://test.alivecdn.com/live/streamId.flv?auth_key=XXX"); //普通观众(非连麦观众)的CDN播放地址 aliPlayer.setDataSource(urlSource); aliPlayer.prepare();
iOS
AliPlayer aliPlayer = AliPlayerFactory.createAliPlayer(context); aliPlayer.setAutoPlay(true); aliPlayer.setOnErrorListener(errorInfo -> { aliPlayer.prepare(); }); UrlSource urlSource = new UrlSource(); urlSource.setUri("http://test.alivecdn.com/live/streamId.flv?auth_key=XXX"); //普通观众(非连麦观众)的CDN播放地址 aliPlayer.setDataSource(urlSource); aliPlayer.prepare();
观众D发起连麦
重要互动模式下主播或者连麦观众的超低延时流,只能使用AlivcLivePlayer对象。AlivcLivePlayer目前只支持播放
artc://live.aliyun.com/play/
前缀的超低延时流。观众D创建AlivcLivePusher对象,使用D的互动推流地址开始推流,观众D角色从普通观众切换为连麦观众。
Android
// 初始化推流配置类 AlivcLivePushConfig alivcLivePushConfig = new AlivcLivePushConfig(); alivcLivePushConfig.setLivePushMode(AlivcLiveMode.AlivcLiveInteractiveMode); // 分辨率540P,最大支持720P alivcLivePushConfig.setResolution(AlivcResolutionEnum.RESOLUTION_540P); // 建议用户使用20fps alivcLivePushConfig.setFps(AlivcFpsEnum.FPS_20); // 打开码率自适应,默认为true alivcLivePushConfig.setEnableBitrateControl(true); // 默认为竖屏,可设置home键向左或向右横屏 alivcLivePushConfig.setPreviewOrientation(AlivcPreviewOrientationEnum.ORIENTATION_PORTRAIT); // 设置音频编码模式 alivcLivePushConfig.setAudioProfile(AlivcAudioAACProfileEnum.AAC_LC); AlivcLivePusher alivcLivePusher = new AlivcLivePusher(); alivcLivePusher.init(context, alivcLivePushConfig); alivcLivePusher.setLivePushErrorListener(new AlivcLivePushErrorListener() {}); alivcLivePusher.setLivePushInfoListener(new AlivcLivePushInfoListener() {}); alivcLivePusher.setLivePushNetworkListener(new AlivcLivePushNetworkListener() {}); alivcLivePusher.startPreview(context, frameLayout, isAnchor); // 普通观众isAnchor为false alivcLivePusher.startPushAysnc("artc://live.aliyun.com/push/123?timestamp=1661596947&token=XXX&userId=userD&sdkAppId=XXX"); //连麦观众的推流地址
iOS
AlivcLivePusher *rtcPusher = [[AlivcLivePusher alloc] initWithConfig:rtcPushConfig]; [rtcPusher startPushWithURL:@"artc://live.aliyun.com/push/123?timestamp=1661596947&token=XXX&userId=userD&sdkAppId=XXX"]; //连麦观众的推流地址
Windows
AlivcLivePusher * pusher_ = AlivcLivePusher::Create(""); pusher_->init(config_); pusher_->setLivePushErrorListener(this); pusher_->setLivePushInfoListener(this); pusher_->setLivePushNetworkListener(this); pusher_->startPush("artc://live.aliyun.com/push/123?timestamp=1661596947&token=XXX&userId=userD&sdkAppId=XXX");
主播A获取连麦观众D的互动模式直播拉流地址,创建AlivcLivePlayer对象拉取连麦观众D的实时流。
Android
AlivcLivePlayConfig config = new AlivcLivePlayConfig(); config.isFullScreen = isAnchor; AlivcLivePlayer alivcLivePlayer = new AlivcLivePlayerImpl(context, AlivcLiveMode.AlivcLiveInteractiveMode); alivcLivePlayer.setPlayInfoListener(new AlivcLivePlayInfoListener() {}); mAlivcLivePlayer.setupWithConfig(config); mAlivcLivePlayer.setPlayView(frameLayout); alivcLivePlayer.startPlay("artc://live.aliyun.com/play/123?timestamp=1661596947&token=XXX&userId=userD&sdkAppId=XXX"); //连麦互动模式下的对端拉流地址URL,主播使用连麦观众端的拉流地址URL。
iOS
AlivcLivePlayer *rtcPlayer = [[AlivcLivePlayer alloc] init]; [rtcPlayer setLivePlayerDelegate:self]; [rtcPlayer setPlayView:self.playerView playCofig:self.rtcPlayConfig]; [rtcPlayer startPlayWithURL:@"artc://live.aliyun.com/play/123?timestamp=1661596947&token=XXX&userId=userD&sdkAppId=XXX"]; //连麦互动模式下的对端拉流地址URL,主播使用连麦观众端的拉流地址URL。
Windows
AlivcLivePlayer *player_ = AlivcLivePlayer::Create(""); if (player_) { AlivcLivePlayConfig config; player_->setupWithConfig(config); player_->startPlay("artc://live.aliyun.com/play/123?timestamp=1661596947&token=XXX&userId=userD&sdkAppId=XXX"); player_->setPlayView(hwnd, width, height); }
同时,连麦观众D获取主播A的互动模式直播拉流地址创建AlivcLivePlayer对象拉取主播A的实时流。
Android
AlivcLivePlayConfig config = new AlivcLivePlayConfig(); config.isFullScreen = isAnchor; AlivcLivePlayer alivcLivePlayer = new AlivcLivePlayerImpl(context, AlivcLiveMode.AlivcLiveInteractiveMode); alivcLivePlayer.setPlayInfoListener(new AlivcLivePlayInfoListener() {}); mAlivcLivePlayer.setupWithConfig(config); mAlivcLivePlayer.setPlayView(frameLayout); alivcLivePlayer.startPlay("artc://live.aliyun.com/play/123?timestamp=1661596947&token=XXX&userId=userA&sdkAppId=XXX"); //连麦互动模式下的对端拉流地址URL,连麦观众使用主播端的拉流地址URL。
iOS
AlivcLivePlayer *rtcPlayer = [[AlivcLivePlayer alloc] init]; [rtcPlayer setLivePlayerDelegate:self]; [rtcPlayer setPlayView:self.playerView playCofig:self.rtcPlayConfig]; [rtcPlayer startPlayWithURL:@"artc://live.aliyun.com/play/123?timestamp=1661596947&token=XXX&userId=userA&sdkAppId=XXX"]; //连麦互动模式下的对端拉流地址URL,连麦观众使用主播端的拉流地址URL。
Windows
AlivcLivePlayer *player_ = AlivcLivePlayer::Create(""); if (player_) { AlivcLivePlayConfig config; player_->setupWithConfig(config); player_->startPlay("artc://live.aliyun.com/play/123?timestamp=1661596947&token=XXX&userId=userA&sdkAppId=XXX"); player_->setPlayView(hwnd, width, height); }
此时,主播A和连麦观众D进入超低延时实时互动场景中。
连麦成功后更新混流
视频连麦场景:
为了保证普通观众B和C(非连麦观众)可以看到连麦观众D的画面,主播A此时需要发起一次混流操作,即将主播A和连麦观众D的画面,混合成一路流给到CDN观众播放。主播A调用setLiveMixTranscodingConfig接口启动云端混流(转码)任务,设置需要混流的对象。混流出来的视频画面的分辨率、帧率等使用的是主播A创建AlivcLivePusher引擎时指定的AlivcLivePushConfig中的配置。即如果主播A创建AlivcLivePusher引擎时AlivcLivePushConfig中配置分辨率为720P,则混流出来的视频画面的分辨率也是720P。
Android
AlivcLiveTranscodingConfig transcodingConfig = new AlivcLiveTranscodingConfig(); AlivcLiveMixStream anchorMixStream = new AlivcLiveMixStream(); anchorMixStream.setUserId(anchorId); anchorMixStream.setX(0); anchorMixStream.setY(0); anchorMixStream.setWidth(mAlivcLivePushConfig.getWidth()); anchorMixStream.setHeight(mAlivcLivePushConfig.getHeight()); anchorMixStream.setZOrder(1); AlivcLiveMixStream audienceMixStream = new AlivcLiveMixStream(); audienceMixStream.setUserId(audience); audienceMixStream.setX((int) mAudienceFrameLayout.getX() / 3); audienceMixStream.setY((int) mAudienceFrameLayout.getY() / 3); audienceMixStream.setWidth(mAudienceFrameLayout.getWidth() / 2); audienceMixStream.setHeight(mAudienceFrameLayout.getHeight() / 2); audienceMixStream.setZOrder(2); ArrayList<AlivcLiveMixStream> mixStreams = new ArrayList<>(); mixStreams.add(anchorMixStream); mixStreams.add(audienceMixStream); transcodingConfig.setMixStreams(mixStreams); alivcLivePusher.setLiveMixTranscodingConfig(transcodingConfig);
iOS
AlivcLiveTranscodingConfig *liveTranscodingConfig = [[AlivcLiveTranscodingConfig alloc] init]; AlivcLiveMixStream *anchorMixStream = [[AlivcLiveMixStream alloc] init]; anchorMixStream.userId = userA; anchorMixStream.x = 0; anchorMixStream.y = 0; anchorMixStream.width = [self.rtcPushConfig getPushResolution].width; anchorMixStream.height = [self.rtcPushConfig getPushResolution].height; anchorMixStream.zOrder = 1; AlivcLiveMixStream *audienceMixStream = [[AlivcLiveMixStream alloc] init]; audienceMixStream.userId = userD; audienceMixStream.x = 100; audienceMixStream.y = 200; audienceMixStream.width = 200; audienceMixStream.height = 300; audienceMixStream.zOrder = 2; liveTranscodingConfig.mixStreams = [NSArray arrayWithObjects:anchorMixStream, audienceMixStream, nil]; [self.rtcPusher setLiveMixTranscodingConfig:liveTranscodingConfig];
Windows
AlivcLiveTranscodingConfig liveTranscodingConfig; AlivcLiveMixStream anchorMixStream ; anchorMixStream.userId = userA; anchorMixStream.x = 0; anchorMixStream.y = 0; anchorMixStream.width = width; anchorMixStream.height = height; anchorMixStream.zOrder = 1; AlivcLiveMixStream audienceMixStream; audienceMixStream.userId = userD; audienceMixStream.x = 100; audienceMixStream.y = 200; audienceMixStream.width = 200; audienceMixStream.height = 300; audienceMixStream.zOrder = 2; liveTranscodingConfig.mixStreams.Add(anchorMixStream); liveTranscodingConfig.mixStreams.Add(audienceMixStream); pusher_->setLiveMixTranscodingConfig(&liveTranscodingConfig);
这样,普通观众就可以看到主播A和连麦观众D的连麦互动。
纯语音连麦场景:
观众连麦后,主播需要更新混流,纯音频场景下AlivcLiveMixStream对象只需指定userId即可,不需要指定坐标信息。
Android
AlivcLiveTranscodingConfig transcodingConfig = new AlivcLiveTranscodingConfig(); AlivcLiveMixStream anchorMixStream = new AlivcLiveMixStream(); anchorMixStream.setUserId(anchorId); AlivcLiveMixStream audienceMixStream = new AlivcLiveMixStream(); audienceMixStream.setUserId(audience); ArrayList<AlivcLiveMixStream> mixStreams = new ArrayList<>(); mixStreams.add(anchorMixStream); mixStreams.add(audienceMixStream); transcodingConfig.setMixStreams(mixStreams); alivcLivePusher.setLiveMixTranscodingConfig(transcodingConfig);
iOS
AlivcLiveTranscodingConfig *liveTranscodingConfig = [[AlivcLiveTranscodingConfig alloc] init]; AlivcLiveMixStream *anchorMixStream = [[AlivcLiveMixStream alloc] init]; anchorMixStream.userId = userA; AlivcLiveMixStream *audienceMixStream = [[AlivcLiveMixStream alloc] init]; audienceMixStream.userId = userD; liveTranscodingConfig.mixStreams = [NSArray arrayWithObjects:anchorMixStream, audienceMixStream, nil]; [self.rtcPusher setLiveMixTranscodingConfig:liveTranscodingConfig];
Windows
AlivcLiveTranscodingConfig liveTranscodingConfig; AlivcLiveMixStream anchorMixStream; anchorMixStream.userId = userA; AlivcLiveMixStream audienceMixStream; audienceMixStream.userId = userD; liveTranscodingConfig.mixStreams.Add(anchorMixStream); liveTranscodingConfig.mixStreams.Add(audienceMixStream); pusher_->setLiveMixTranscodingConfig(&liveTranscodingConfig);
连麦观众D结束连麦
连麦观众D结束连麦,需要调用AlivcLivePusher推流引擎的结束推流接口,并将AlivcLivePusher推流引擎销毁。
Android
alivcLivePusher.stopPush(); alivcLivePusher.destroy(); alivcLivePusher = null;
iOS
[self.rtcPusher stopPush]; [self.rtcPusher destory]; self.rtcPusher = nil;
Windows
if ( pusher_) { pusher_->stopPush(); AlivcLivePusher::destroy(); pusher_ = nullptr; }
同时,连麦观众D需要调用AlivcLivePlayer拉流引擎的结束播放接口,并将AlivcLivePlayer拉流引擎销毁。
Android
alivcLivePlayer.stopPlay(); alivcLivePlayer.destroy(); alivcLivePlayer = null;
iOS
[self.rtcPlayer stopPlay]; self.rtcPlayer = nil;
Windows
if (player_) { player_->stopPlay(); player_->destroy(); player_ = nullptr; }
连麦观众D切换为普通观众,通过步骤四:创建AliPlayer CDN播放进行CDN播放。
主播A需要调用AlivcLivePlayer拉流引擎的结束播放接口,并将AlivcLivePlayer拉流引擎销毁。
Android
alivcLivePlayer.stopPlay(); alivcLivePlayer.destroy(); alivcLivePlayer = null;
iOS
[self.rtcPlayer stopPlay]; self.rtcPlayer = nil;
Windows
if (player_) { player_->stopPlay(); player_->destroy(); player_ = nullptr; }
同时,主播A调用setLiveMixTranscodingConfig接口,参数传入空值,从混流切换为旁路模式。
需要注意当不再需要混流,普通观众只需要观看主播A一个人画面时,可以调用setLiveMixTranscodingConfig接口,参数传入空值即可。
警告若主播还在房间中但不再需要混流,请务必传入空值进行取消。因为当发起混流后,云端混流模块就会开始工作,不及时取消混流可能会引起不必要的计费损失。
Android
alivcLivePusher.setLiveMixTranscodingConfig(null);
iOS
[self.rtcPusher setLiveMixTranscodingConfig:nil];
Windows
pusher_->setLiveMixTranscodingConfig(nullptr);