このトピックでは、視聴者クライアントが単一ストリーマーストリーミングから共同ストリーミングへのレイアウト変更に関する情報をどのように受信するかについて説明します。
レイアウトが単一ストリーマーストリーミングから共同ストリーミングに変更されると、ApsaraVideo Live はストリームに Supplemental Enhancement Information(SEI)フレームを自動的に追加します。 SEI フレームには、ライブストリームのすべての参加者に関するレイアウト情報が含まれています。 視聴者クライアントで SEI リスニングを有効にすることで、レイアウトの変更を検出できます。 これは、コンテンツ配信ネットワーク (CDN) からストリームがプルされるときの遅延の問題に対処するのに役立ちます。 SEI の構成については、「StartLiveMPUTask」または「UpdateLiveMPUTask」をご参照ください。
次の表は、SEI フレームの構造を示しています。
データ型 | パラメーター | 説明 |
ビデオストリーム情報 | stream | ストリーマーに関する情報。 uid: ストリーマーのユーザー ID。 |
ストリーマーがストリーミングしている領域のレイアウト情報。次のレイアウトパラメーターに注意してください。
|
単一のストリーマーがストリーミングしている場合、視聴者が受信する SEI メッセージには、1 人の参加者に関する情報のみが含まれます。 共同ストリーミングまたは対戦が発生した場合、視聴者が受信する SEI メッセージには、複数の参加者に関する情報が含まれます。
たとえば、ユーザー ID が 111 のストリーマーがストリーミングしている場合、次の形式の SEI フレームが視聴者側に送信されます。
{"stream":[{"uid":"111","paneid":-1,"zorder":0,"x":0,"y":0,"w":0,"h":0,"type":0,"ms":0,"vol":0,"vad":0}]}
ユーザー ID が 111 のストリーマーがユーザー ID が 222 の共同ストリーマーと共同ストリーミングしている場合、次の形式の SEI フレームが視聴者側に送信されます。
{"stream":[{"uid":"111","paneid":0,"zorder":1,"x":0,"y":0.25,"w":0.5,"h":0.5,"type":0,"ms":0,"vol":1,"vad":119},{"uid":"222","paneid":1,"zorder":1,"x":0.5018382,"y":0.25,"w":0.5,"h":0.5,"type":0,"ms":0,"vol":60,"vad":123}]}
視聴者は、ストリーム配列の数に基づいて、ストリーミングレイアウトが変更されるかどうかを判断できます。 ストリーム配列が 1 つだけ存在する場合、単一のストリーマーがストリーミングしています。 複数のストリーム配列が存在する場合、共同ストリーミングまたは対戦が発生します。 参加者のレイアウト情報は、混合ストリーム内の各参加者の位置を示します。
次のサンプルコードは、ApsaraVideo Player を使用して SEI フレームを解析する方法の例を示しています。
Android のサンプルコード:
mAliPlayer = AliPlayerFactory.createAliPlayer(mContext);
PlayerConfig playerConfig = mAliPlayer.getConfig();
// FLV 形式の音声のみまたはビデオのみのストリームの SEI フレーム解析を構成して、起動時間を短縮します。
// 開始バッファー時間を構成します。 値が大きいほど、起動が安定します。 ただし、値が大きすぎると、起動時間に影響する可能性があります。 ビジネス要件に基づいてこのパラメーターを指定します。 単位: ミリ秒。
playerConfig.mStartBufferDuration = 1000;
// 途切れからの回復に必要なキャッシュを構成します。 ネットワークの状態が悪い場合は、大きい値を指定します。 音声のみのストリームの場合は 500、ビデオストリームの場合は 3000 に設定することをお勧めします。 単位: ミリ秒。
playerConfig.mHighBufferDuration = 500;
// SEI リスニングを有効にします。
playerConfig.mEnableSEI = true;
mAliPlayer.setConfig(playerConfig);
mAliPlayer.setAutoPlay(true);
mAliPlayer.setOnErrorListener(errorInfo -> {
mAliPlayer.prepare();
});
mAliPlayer.setOnSeiDataListener(new IPlayer.OnSeiDataListener() {
@Override
public void onSeiData(int i, byte[] bytes) {
}
});iOS のサンプルコード:
self.cdnPlayer = [[AliPlayer alloc] init];
self.cdnPlayer.delegate = self;
AVPConfig *config = [self.cdnPlayer getConfig];
config.enableSEI = YES;
[self.cdnPlayer setConfig:config];
// SEI 関連のコールバックをリッスンします。
- (void)onSEIData:(AliPlayer*)player type:(int)type data:(NSData *)data {
if (data.bytes){
NSString *str = [NSString stringWithUTF8String:data.bytes];
// SEI メッセージを処理します。
}
}