ApsaraVideo Live は、ライブ配信対戦機能をサポートしています。この機能を使用すると、異なるライブ配信ルームにいる複数のストリーマーがリアルタイムの対戦を開始できます。このトピックでは、対戦の開始方法と関連するサンプルコードについて説明します。
ワークフロー
Push SDK は、リアルタイム音声・映像(ARTC)に基づいてライブ配信対戦を実装しています。これにより、ユーザーは超低遅延でより多くのユーザーを惹き付けるインタラクティブストリーミングを開始できます。次の図は、ライブ配信対戦のワークフローを示しています。
図に示すように、視聴者 C はストリーマー A のストリームを視聴し、視聴者 D はストリーマー B のストリームを視聴しています。ストリーマー A とストリーマー 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 のインタラクティブ エディションが必要です。SDK の統合については、以下のトピックをご参照ください。
手順 1:共同ストリーミング機能を有効にする
共同ストリーミング機能を有効にする方法については、「共同ストリーミングの概要」をご参照ください。
手順 2:対戦用のアップストリーミング URL とストリーミング URL を生成する
連結ルールを使用して、対戦におけるストリーマーのアップストリーミング URL とストリーミング URL、および視聴者の CDN ストリーミング URL を構築できます。詳細については、「対戦シナリオにおける異なるストリーマーのアップストリーミング URL とストリーミング URL」および「視聴者の CDN ストリーミング URL」をご参照ください。
手順 3:ストリーマー A のアップストリーミングを開始する
AlivcLivePushConfig オブジェクトを作成する
アップストリーミングを構成するために使用される AlivcLivePushConfig オブジェクトを作成します。livePushMode を AlivcLivePushInteractiveMode に設定し、解像度、フレームレート、ビットレートなどのパラメーターを構成します。
重要Android または iOS のネイティブ クライアントと Web 間で共同ストリーミングを実装する場合、ネイティブ クライアントで HTML5 互換モードを有効にする必要があります。有効にしないと、Web ユーザーにはネイティブ クライアントのユーザーから送信された黒い画面が表示されます。HTML5 互換モードを有効にするには、ネイティブ クライアントで AlivcLivePushConfig#setH5CompatibleMode を呼び出します。詳細については、ネイティブ SDK の API リファレンスをご参照ください。
Android のサンプルコード:
// アップストリーミング構成のクラスを初期化します。 mAlivcLivePushConfig = new AlivcLivePushConfig(); // アップストリーミングモードを指定します。デフォルトでは、通常のアップストリーミングモードが使用されます。 mAlivcLivePushConfig.setLivePushMode(AlivcLiveMode.AlivcLiveInteractiveMode); // 解像度を指定します。デフォルトの解像度は 540p です。 mAlivcLivePushConfig.setResolution(AlivcResolutionEnum.RESOLUTION_540P); // フレームレートを指定します。デフォルトのフレームレートは 25 フレーム/秒(FPS)です。 mAlivcLivePushConfig.setFps(AlivcFpsEnum.FPS_25); // グループ オブ ピクチャ(GOP)サイズを指定します。単位:秒。デフォルトの GOP サイズは 2 秒です。 mAlivcLivePushConfig.setVideoEncodeGop(AlivcVideoEncodeGopEnum.GOP_TWO); // アダプティブ ビットレート ストリーミングを有効にするかどうかを指定します。デフォルト値は true です。 mAlivcLivePushConfig.setEnableBitrateControl(true); // 画面の向きを指定します。デフォルトの画面の向きは縦です。ホームキーを押すと向きが左向きまたは右向きに変わるように設定できます。 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); // アプリがバックグラウンドに切り替えられたとき、またはビデオストリームのアップストリーミングが一時停止されたときにアップストリーミングされる画像を指定します。 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;
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"); // ストリーマー A のアップストリーミング URL
iOS のサンプルコード:
[rtcPusher startPushWithURL:@"artc://live.aliyun.com/push/123?timestamp=1661596947&token=XXX&userId=123&sdkAppId=XXX"]; // ストリーマー A のアップストリーミング URL
Windows のサンプルコード:
pusher_->startPush("artc://live.aliyun.com/push/123?timestamp=1661596947&token=XXX&userId=123&sdkAppId=XXX");
手順 4:ストリーマー B のアップストリーミングを開始する
AlivcLivePushConfig オブジェクトを作成する
アップストリーミングを構成するために使用される AlivcLivePushConfig オブジェクトを作成します。 livePushMode を AlivcLivePushInteractiveMode に設定し、解像度、フレームレート、ビットレートなどのパラメーターを構成します。
重要Android または iOS のネイティブ クライアントと Web 間で共同ストリーミングを実装する場合、ネイティブ クライアントで HTML5 互換モードを有効にする必要があります。有効にしないと、Web ユーザーにはネイティブ クライアントのユーザーから送信された黒い画面が表示されます。 HTML5 互換モードを有効にするには、ネイティブ クライアントで AlivcLivePushConfig#setH5CompatibleMode を呼び出します。詳細については、ネイティブ SDK の API リファレンスをご参照ください。
Android のサンプルコード:
// アップストリーミング構成のクラスを初期化します。 mAlivcLivePushConfig = new AlivcLivePushConfig(); // アップストリーミングモードを指定します。デフォルトでは、通常のアップストリーミングモードが使用されます。 mAlivcLivePushConfig.setLivePushMode(AlivcLiveMode.AlivcLiveInteractiveMode); // 解像度を指定します。デフォルトの解像度は 540p です。 mAlivcLivePushConfig.setResolution(AlivcResolutionEnum.RESOLUTION_540P); // フレームレートを指定します。デフォルトのフレームレートは 25 フレーム/秒(FPS)です。 mAlivcLivePushConfig.setFps(AlivcFpsEnum.FPS_25); // グループ オブ ピクチャ(GOP)サイズを指定します。単位:秒。デフォルトの GOP サイズは 2 秒です。 mAlivcLivePushConfig.setVideoEncodeGop(AlivcVideoEncodeGopEnum.GOP_TWO); // アダプティブ ビットレート ストリーミングを有効にするかどうかを指定します。デフォルト値は true です。 mAlivcLivePushConfig.setEnableBitrateControl(true); // 画面の向きを指定します。デフォルトの画面の向きは縦です。ホームキーを押すと向きが左向きまたは右向きに変わるように設定できます。 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); // アプリがバックグラウンドに切り替えられたとき、またはビデオストリームのアップストリーミングが一時停止されたときにアップストリーミングされる画像を指定します。 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;
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"); // ストリーマー B のアップストリーミング URL
iOS のサンプルコード:
[rtcPusher startPushWithURL:@"artc://live.aliyun.com/push/456?timestamp=1661596947&token=XXX&userId=456&sdkAppId=XXX"]; // ストリーマー B のアップストリーミング URL
Windows のサンプルコード:
pusher_->startPush("artc://live.aliyun.com/push/456?timestamp=1661596947&token=XXX&userId=456&sdkAppId=XXX");
手順 5:対戦を開始する
ストリーマー A は AlivcLivePlayer を呼び出してストリーマー B のストリームを再生し、ストリーマー B は AlivcLivePlayer を呼び出してストリーマー 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"); // ストリーマー B のストリーミング URL
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"]; // ストリーマー B のストリーミング URL
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"); // ストリーマー A のストリーミング 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=123&sdkAppId=XXX"]; // ストリーマー A のストリーミング URL
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 メソッドを呼び出して混合ストリーム トランスコード タスクを開始し、それぞれ混合するストリームを指定します。混合ストリームの解像度やフレームレートなどのパラメーターは、ストリーマーが AlivcLivePusher オブジェクトを作成するときに AlivcLivePushConfig で構成したものになります。たとえば、ストリーマー A が AlivcLivePusher オブジェクトを作成するときに AlivcLivePushConfig で解像度を 720p に設定した場合、ストリーマー 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 メソッドを呼び出して空の値を渡す必要があります。これにより、ストリーム混合が停止されます。
視聴者 C または D がストリーマー A または B のストリームのみを視聴したい場合、ストリーマー A または B は setLiveMixTranscodingConfig メソッドを呼び出して空の値を渡し、ストリーム混合を停止することもできます。
警告ストリーマーがまだルーム内にいるが、ストリーム混合を必要としない場合は、ストリーム混合が停止していることを確認してください。ストリーム混合を停止しないと、実行中のストリーム混合モジュールが不要な料金を発生させます。
Android のサンプルコード:
alivcLivePusher.setLiveMixTranscodingConfig(null);
iOS のサンプルコード:
[self.rtcPusher setLiveMixTranscodingConfig:nil];
Windows のサンプルコード:
pusher_->setLiveMixTranscodingConfig(nullptr);