ApsaraVideo Liveはバトル機能をサポートしています。 これにより、さまざまなライブルームにまたがる複数のストリーマーがリアルタイムの競争を開始でき、視聴者は視聴を楽しむことができます。 このトピックでは、ストリーマー間のバトルを開始する方法と、関連するサンプルコードについて説明します。
戦いを始める方法の概要
Push SDKは、ApsaraVideo Real-time Communication (ARTC) に基づくライブバトルを実装しています。 これにより、ユーザーはより多くの人を超低遅延で引き付けるインタラクティブなストリーミングを開始できます。
バトルの前: 2つのストリーマーがそれぞれARTCに基づく取り込みURLを使用してストリームを取り込み、視聴者はCDNからストリームをプルします。
戦闘中: ストリーマーは、ARTCに基づくストリーミングURLを使用して、超低レイテンシで互いのストリームをプルします。
戦いの後: ストリーマーはお互いの流れを引っ張るのをやめます。
上の図に示すように、ビューアCは、ストリーマAのストリームを見ており、ビューアDは、ストリーマBのストリームを見ています。
ストリーマA: ストリーマAは、ストリーマBのストリーミングURLを使用して、ストリーマBのストリームを超低レイテンシで再生します。 同時に、ストリーマAは、ストリーマAのストリームとストリーマBのストリームとを単一のストリームに混合するストリーム混合動作を実行し、ビューアCは、再生のためにCDNから引き出すことができます。
ストリーマB: ストリーマBは、ストリーマAのストリーミングURLを使用して、ストリーマAのストリームを超低レイテンシで再生します。 同時に、ストリーマBは、ストリーマBのストリームとストリーマAのストリームとを単一のストリームに混合するストリーム混合動作を実行し、ビューアDは、再生のためにCDNから引き出すことができます。
ビューアCおよびビューアDは、いかなる操作も実行する必要はない。 混合ストリームは自動的に表示されます。
使用上の注意
次のセクションでは、Push SDKのインタラクティブエディションを使用してバトルを開始する方法について説明します。
Push SDKのインタラクティブエディションを統合する方法の詳細については、以下のトピックを参照してください。
ステップ1: コストリーミング機能を有効にする
コストリーミング機能を有効にする方法については、「コストリーミングを開始する」をご参照ください。
ステップ2: バトルの取り込みとストリーミングURLを生成する
連結ルールを使用して、バトル中のストリーマーの取り込みURLとストリーミングURL、および視聴者のCDNストリーミングURLを構築できます。 詳細については、「戦闘シナリオでのさまざまなストリーマーの取り込みとストリーミングURL」および「視聴者のCDNストリーミングURL」をご参照ください。
ステップ3: Streamer Aのストリーム取り込みを開始する
AlivcLivePushConfigオブジェクトの作成
ストリーム取り込みの設定に使用されるAlivcLivePushConfigオブジェクトを作成します。 livePushModeをAlivcLivePushInteractiveModeに設定し、解像度、フレームレート、ビットレートなどのパラメーターを設定します。
重要AndroidまたはiOSのネイティブクライアントとwebの間でコストリーミングを実装する場合は、ネイティブクライアントでHTML5互換モードを有効にする必要があります。 それ以外の場合、web上のユーザーは、ネイティブクライアントのユーザーから送信された黒い画面が表示されます。 HTML5互換モードを有効にするには、NativeクライアントでAlivcLivePushConfig#setH5CompatibleModeを呼び出します。 詳細については、ネイティブSDKのAPIリファレンスをご参照ください。
Androidのサンプルコード:
// Initialize the class for stream ingest configurations. mAlivcLivePushConfig = new AlivcLivePushConfig(); // Specify the stream ingest mode. By default, the regular stream ingest mode is used. mAlivcLivePushConfig.setLivePushMode(AlivcLiveMode.AlivcLiveInteractiveMode); // Specify the resolution. The default resolution is 540p. mAlivcLivePushConfig.setResolution(AlivcResolutionEnum.RESOLUTION_540P); // Specify the frame rate. The default frame rate is 20 frames per second (FPS). mAlivcLivePushConfig.setFps(AlivcFpsEnum.FPS_25); // Specify the group of pictures (GOP) size. Unit: seconds. The default GOP size is 2 seconds. mAlivcLivePushConfig.setVideoEncodeGop(AlivcVideoEncodeGopEnum.GOP_TWO); // Specify whether to enable adaptive bitrate streaming. The default value is true. mAlivcLivePushConfig.setEnableBitrateControl(true); // Specify the screen orientation. The default screen orientation is portrait. You can configure the settings that allow you to press the Home key to change the orientation to landscape left or landscape right. mAlivcLivePushConfig.setPreviewOrientation(AlivcPreviewOrientationEnum.ORIENTATION_PORTRAIT); // Specify the audio encoding format. The default format is AAC-LC. mAlivcLivePushConfig.setAudioProfile(AlivcAudioAACProfileEnum.AAC_LC); // Specify the video encoding mode. By default, hardware encoding is used. mAlivcLivePushConfig.setVideoEncodeMode(AlivcEncodeModeEnum.Encode_MODE_HARD); // Specify the audio encoding mode. By default, software encoding is used. mAlivcLivePushConfig.setAudioEncodeMode(AlivcEncodeModeEnum.Encode_MODE_SOFT); // Specify whether to use the front camera or the rear camera. By default, the front camera is used. mAlivcLivePushConfig.setCameraType(AlivcLivePushCameraTypeEnum.CAMERA_TYPE_FRONT); // Specify the image that is ingested when your app is switched to the background or video stream ingest is paused. mAlivcLivePushConfig.setPausePushImage("TODO: Image Path"); // Specify the image that is ingested in poor network conditions. 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;
AlivcLivePusherオブジェクトの作成
ストリーム取り込みインスタンスとしてAlivcLivePusherオブジェクトを作成します。 作成されたAlivcLivePushConfigオブジェクトを渡し、関連するコールバックを設定します。
Androidのサンプルコード:
AlivcLivePusher alivcLivePusher = new AlivcLivePusher(); alivcLivePusher.init(context, alivcLivePushConfig); alivcLivePusher.setLivePushErrorListener(new AlivcLivePushErrorListener() {}); alivcLivePusher.setLivePushInfoListener(new AlivcLivePushInfoListener() {}); alivcLivePusher.setLivePushNetworkListener(new AlivcLivePushNetworkListener() {});
iOSのサンプルコード:
AlivcLivePusher *rtcPusher = [[AlivcLivePusher alloc] initWithConfig:rtcPushConfig]; [rtcPusher setInfoDelegate:self]; [rtcPusher setErrorDelegate:self]; [rtcPusher setNetworkDelegate:self];
バトルモードでストリーム取り込みを開始
バトルの取り込みURLを使用してストリームを取り込みます。 取り込みURLを取得する方法の詳細については、「手順2: バトルの取り込みURLとストリーミングURLの生成」をご参照ください。
Androidのサンプルコード:
alivcLivePusher.startPreview(context, frameLayout, isAnchor); alivcLivePusher.startPushAysnc("artc://live.aliyun.com/push/123?timestamp=1661596947&token=XXX&userId=123&sdkAppId=XXX"); // The ingest URL of Streamer A.
iOSのサンプルコード:
[rtcPusher startPushWithURL:@"artc://live.aliyun.com/push/123?timestamp=1661596947&token=XXX&userId=123&sdkAppId=XXX"]; // The ingest URL of Streamer A.
Windowsのサンプルコード:
pusher_->startPush("artc://live.aliyun.com/push/123?timestamp=1661596947&token=XXX&userId=123&sdkAppId=XXX");
ステップ4: Streamer Bのストリーム取り込みを開始する
AlivcLivePushConfigオブジェクトの作成
ストリーム取り込みの設定に使用されるAlivcLivePushConfigオブジェクトを作成します。 livePushModeをAlivcLivePushInteractiveModeに設定し、解像度、フレームレート、ビットレートなどのパラメーターを設定します。
重要AndroidまたはiOSのネイティブクライアントとwebの間でコストリーミングを実装する場合は、ネイティブクライアントでHTML5互換モードを有効にする必要があります。 それ以外の場合、web上のユーザーは、ネイティブクライアントのユーザーから送信された黒い画面が表示されます。 HTML5互換モードを有効にするには、NativeクライアントでAlivcLivePushConfig#setH5CompatibleModeを呼び出します。 詳細については、ネイティブSDKのAPIリファレンスをご参照ください。
Androidのサンプルコード:
// Initialize the class for stream ingest configurations. mAlivcLivePushConfig = new AlivcLivePushConfig(); // Specify the stream ingest mode. By default, the regular stream ingest mode is used. mAlivcLivePushConfig.setLivePushMode(AlivcLiveMode.AlivcLiveInteractiveMode); // Specify the resolution. The default resolution is 540p. mAlivcLivePushConfig.setResolution(AlivcResolutionEnum.RESOLUTION_540P); // Specify the frame rate. The default frame rate is 20 frames per second (FPS). mAlivcLivePushConfig.setFps(AlivcFpsEnum.FPS_25); // Specify the group of pictures (GOP) size. Unit: seconds. The default GOP size is 2 seconds. mAlivcLivePushConfig.setVideoEncodeGop(AlivcVideoEncodeGopEnum.GOP_TWO); // Specify whether to enable adaptive bitrate streaming. The default value is true. mAlivcLivePushConfig.setEnableBitrateControl(true); // Specify the screen orientation. The default screen orientation is portrait. You can configure the settings that allow you to press the Home key to change the orientation to landscape left or landscape right. mAlivcLivePushConfig.setPreviewOrientation(AlivcPreviewOrientationEnum.ORIENTATION_PORTRAIT); // Specify the audio encoding format. The default format is AAC-LC. mAlivcLivePushConfig.setAudioProfile(AlivcAudioAACProfileEnum.AAC_LC); // Specify the video encoding mode. By default, hardware encoding is used. mAlivcLivePushConfig.setVideoEncodeMode(AlivcEncodeModeEnum.Encode_MODE_HARD); // Specify the audio encoding mode. By default, software encoding is used. mAlivcLivePushConfig.setAudioEncodeMode(AlivcEncodeModeEnum.Encode_MODE_SOFT); // Specify whether to use the front camera or the rear camera. By default, the front camera is used. mAlivcLivePushConfig.setCameraType(AlivcLivePushCameraTypeEnum.CAMERA_TYPE_FRONT); // Specify the image that is ingested when your app is switched to the background or video stream ingest is paused. mAlivcLivePushConfig.setPausePushImage("TODO: Image Path"); // Specify the image that is ingested in poor network conditions. 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;
AlivcLivePusherオブジェクトの作成
ストリーム取り込みインスタンスとしてAlivcLivePusherオブジェクトを作成します。 作成されたAlivcLivePushConfigオブジェクトを渡し、関連するコールバックを設定します。
Androidのサンプルコード:
AlivcLivePusher alivcLivePusher = new AlivcLivePusher(); alivcLivePusher.init(context, alivcLivePushConfig); alivcLivePusher.setLivePushErrorListener(new AlivcLivePushErrorListener() {}); alivcLivePusher.setLivePushInfoListener(new AlivcLivePushInfoListener() {}); alivcLivePusher.setLivePushNetworkListener(new AlivcLivePushNetworkListener() {});
iOSのサンプルコード:
AlivcLivePusher *rtcPusher = [[AlivcLivePusher alloc] initWithConfig:rtcPushConfig]; [rtcPusher setInfoDelegate:self]; [rtcPusher setErrorDelegate:self]; [rtcPusher setNetworkDelegate:self];
バトルモードでストリーム取り込みを開始
バトルの取り込みURLを使用してストリームを取り込みます。 取り込みURLを取得する方法の詳細については、「手順2: バトルの取り込みURLとストリーミングURLの生成」をご参照ください。
Androidのサンプルコード:
alivcLivePusher.startPreview(context, frameLayout, isAnchor); alivcLivePusher.startPushAysnc("artc://live.aliyun.com/push/456?timestamp=1661596947&token=XXX&userId=456&sdkAppId=XXX"); // The ingest URL of Streamer B.
iOSのサンプルコード:
[rtcPusher startPushWithURL:@"artc://live.aliyun.com/push/456?timestamp=1661596947&token=XXX&userId=456&sdkAppId=XXX"]; // The ingest URL of Streamer B.
Windowsのサンプルコード:
pusher_->startPush("artc://live.aliyun.com/push/456?timestamp=1661596947&token=XXX&userId=456&sdkAppId=XXX");
ステップ5: 戦いを始める
Streamer AはAlivcLivePlayerを呼び出してStreamer Bのストリームを再生し、Streamer BはAlivcLivePlayerを呼び出してStreamer Aのストリームを再生します。
ストリーマーAとストリーマーBはお互いの流れを再生し、戦いを開始します。
ストリーマー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/456?timestamp=1661596947&token=XXX&userId=456&sdkAppId=XXX"); // The streaming URL of Streamer B.
iOSのサンプルコード:
AlivcLivePlayer *rtcPlayer = [[AlivcLivePlayer alloc] init]; [rtcPlayer setLivePlayerDelegate:self]; [rtcPlayer setPlayView:self.playerView playCofig:self.rtcPlayConfig]; [rtcPlayer startPlayWithURL:@"artc://live.aliyun.com/play/456?timestamp=1661596947&token=XXX&userId=456&sdkAppId=XXX"]; // The streaming URL of Streamer B.
Windowsのサンプルコード:
player_ = AlivcLivePlayer::Create(""); if (player_) { AlivcLivePlayConfig config; player_->setupWithConfig(config); player_->startPlay("artc://live.aliyun.com/play/456?timestamp=1661596947&token=XXX&userId=456&sdkAppId=XXX"); player_->setPlayView(hwnd, width, height); }
ストリーマーB:
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=123&sdkAppId=XXX"); // The streaming URL of Streamer A.
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=123&sdkAppId=XXX"]; // The streaming URL of Streamer A.
Windowsのサンプルコード:
player_ = AlivcLivePlayer::Create(""); if (player_) { AlivcLivePlayConfig config; player_->setupWithConfig(config); player_->startPlay("artc://live.aliyun.com/play/123?timestamp=1661596947&token=XXX&userId=123&sdkAppId=XXX"); player_->setPlayView(hwnd, width, height); }
ストリーマAおよびストリーマBは、それぞれ混合ストリームを更新する。
ビューアCおよびビューアDが、ストリーマAおよびストリーマBが戦うストリームを確実に見ることができるようにするために、ストリーマAおよびストリーマBは、それぞれ、ストリームミキシング動作を実行しなければならない。 このようにして、ストリーマAおよびストリーマBのストリームを単一のストリームに混合することができ、視聴者はそれを再生のためにCDNから引き出すことができます。
具体的には、ストリーマAおよびストリーマBは、setLiveMixTranscodingConfigメソッドを呼び出して、混合ストリームのトランスコーディングタスクを開始し、混合するストリームをそれぞれ指定します。 混合ストリームの解像度やフレームレートなどのパラメータは、AlivcLivePushConfigでストリーマーがAlivcLivePusherオブジェクトを作成するときに設定したものです。 たとえば、AlivcLivePusherオブジェクトを作成するときに、Streamer AがAlivcLivePushConfigで解像度を720pに設定した場合、Streamer Aの混合ストリームの解像度は720pになります。
Androidのサンプルコード:
AlivcLiveTranscodingConfig transcodingConfig = new AlivcLiveTranscodingConfig(); AlivcLiveMixStream anchorMixStream = new AlivcLiveMixStream(); anchorMixStream.setUserId(123); anchorMixStream.setX(0); anchorMixStream.setY(0); anchorMixStream.setWidth(mAlivcLivePushConfig.getWidth()); anchorMixStream.setHeight(mAlivcLivePushConfig.getHeight()); anchorMixStream.setZOrder(1); AlivcLiveMixStream audienceMixStream = new AlivcLiveMixStream(); audienceMixStream.setUserId(456); 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 = 123; 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 = 456; 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);
ステップ6: 戦いを終わらせる
ストリーマAおよびストリーマBは、互いのストリームの再生を停止する。
戦いは停止します。 ストリーマAとストリーマBは、独自のストリームを再び取り込みます。
Androidのサンプルコード:
alivcLivePlayer.stopPlay(); alivcLivePlayer.destroy(); alivcLivePlayer = null;
iOSのサンプルコード:
[self.rtcPlayer stopPlay]; self.rtcPlayer = nil;
Windowsのサンプルコード:
if (player_) { player_->stopPlay(); player_->destroy(); player_ = nullptr; }
ストリーマAおよびストリーマBは、それぞれ混合ストリームを更新する。
バトル終了後、ストリーマーAとストリーマーBはそれぞれsetLiveMixTranscodingConfigメソッドを呼び出して空の値を渡す必要があります。 このようにして、流れの混合は停止されます。
Viewer CまたはDがStreamer AまたはBのストリームのみを視聴したい場合、Streamer AまたはBはsetLiveMixTranscodingConfigメソッドを呼び出し、空の値を渡してストリームミキシングを停止することもできます。
警告ストリーマがまだ室内にあるが、ストリームミキシングを必要としない場合は、ストリームミキシングが停止していることを確認してください。 ストリームミキシングが停止されていない場合、実行を継続するストリームミキシングモジュールには不要な料金が発生します。
Androidのサンプルコード:
alivcLivePusher.setLiveMixTranscodingConfig(null);
iOSのサンプルコード:
[self.rtcPusher setLiveMixTranscodingConfig:nil];
Windowsのサンプルコード:
pusher_->setLiveMixTranscodingConfig(nullptr);