全部產品
Search
文件中心

ApsaraVideo Live:連麥互動開發指南

更新時間:Jul 19, 2024

阿里雲ApsaraVideo for Live提供了主播端與觀眾端進行連麥互動的功能,本文為您詳細介紹連麥互動的操作步驟和相關範例程式碼,協助您快速接入連麥互動情境。

接入RTC連麥互動方案介紹

直播SDK基於即時音視頻RTC來實現連麥方案,協助客戶實現超低延時、更多人數的直播即時互動,一般流程如下:

  • 連麥前:主播使用RTC連麥推流地址進行推流,觀眾拉取CDN流進行觀看。

  • 連麥中:觀眾從一般觀眾切換為連麥觀眾,使用RTC連麥推流地址進行推流,使用RTC連麥拉流地址拉取主播的超低延時流;主播使用RTC連麥拉流地址進行拉取連麥觀眾的超低延時流。

  • 結束連麥:連麥觀眾切換為一般觀眾,停止RTC推流和RTC拉流,切換為拉取CDN流進行觀看。

注意事項

  • 本文介紹推流SDK互動版的連麥功能使用。

    推流SDK互動版的整合,請參見:

  • 互動模式下主播或者連麥觀眾的超低延時流,只能使用AlivcLivePlayer對象。AlivcLivePlayer目前只支援播放artc://live.aliyun.com/play/首碼的超低延時流。

步驟一:開通直播連麥服務

具體開通直播連麥功能方式,請參見直播連麥快速入門

步驟二:產生連麥互動推拉流地址

您可以通過控制台產生或通過自訂拼接主播和連麥觀眾的推拉流地址,及一般觀眾(非連麥觀眾)的CDN播放地址

方法一:控制台產生

若您希望快速產生主播和連麥觀眾的推拉流地址,及一般觀眾(非連麥觀眾)的CDN播放地址進行體驗,可以藉助控制台工具進行產生。具體操作,請參見連麥地址產生器

方法二:自訂拼接

通過控制台產生主播和連麥觀眾的推拉流地址URL中,Token為臨時Token,一般用於測試使用。如果需要正式使用,為了安全起見,請使用自訂拼接的推拉流地址。自訂拼接地址中Token是基於您的SdkAppID、 AppKey、房間ID、UserID和Timestamp通過SHA256密碼編譯演算法計算得到,攻擊者很難通過偽造Token盜用您的雲端服務流量。自訂拼接詳情請參見連麥互動情境主播端和連麥觀眾端推拉流地址一般觀眾的CDN播放地址

步驟三:建立推流對象

主播端和連麥觀眾端都需要執行該操作。

  1. 建立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;
  2. 建立AlivcLivePusher

    方式一:連麥觀眾僅能選擇語音連麥或視頻連麥中的一種,且不能切換

    如果是純音頻推流,建立AlivcLivePushConfig推流設定物件時,需要執行以下代碼指定純音頻推流模式。

    非純音頻推流情境,無需執行。純音頻推流不需要調用預覽介面,直接調用開始推流介面。

    Android範例程式碼

    mAlivcLivePushConfig.setAudioOnly(true);

    iOS範例程式碼

    rtcPushConfig.audioOnly = YES;

    Windows範例程式碼

    config_.mAudioOnly = true;

    方式二:連麥觀眾可以隨時在語音連麥和視頻連麥進行切換

    如果允許連麥觀眾在語音和視頻間進行切換,具體請參見觀眾連麥視頻/語音切換方案

  3. 連麥互動模式下推流

    使用連麥互動模式下推流地址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格式。

在阿里雲ApsaraVideo for Live控制台產生地址時,會同時產生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];

步驟五:觀眾連麥

  1. 主播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");
  2. 一般觀眾(非連麥觀眾)的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 *cdnPlayer = [[AliPlayer alloc] init];
    cdnPlayer.delegate = self;
    cdnPlayer.autoPlay = YES;
    AVPUrlSource *source = [[AVPUrlSource alloc] urlWithString:@"http://test.alivecdn.com/live/streamId.flv?auth_key=XXX"];  //一般觀眾(非連麥觀眾)的CDN播放地址
    [self.cdnPlayer setUrlSource:source];
    [self.cdnPlayer prepare];
  3. 觀眾D發起連麥

    • 觀眾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進入超低延時即時互動情境中。

  4. 連麥成功後更新混流

    • 視頻連麥情境

      為了保證一般觀眾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);
                                      
  5. 連麥觀眾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);