ライブ Q&A は、ユーザーが決められた時間にライブストリームチャンネルに入り、配信者の案内の下でオンラインクイズを完了するアクティビティです。 12 の問題すべてに正解したユーザーは、各アクティビティのボーナスセットを分け合います。 2018 年の初めに、インターネット関係者は「大きなボーナスのあるオンライン Q&A ゲーム」のブームを目の当たりにしました。 このようなインタラクティブゲームをビジネスに導入して、高度にインタラクティブなユーザーコミュニティを構築できます。 次のセクションでは、ApsaraVideo のライブ Q&A スキームを例として、ライブ Q&A 機能を実装する方法を説明します。

  • ライブ Q&A を開始する前に、Alibaba Cloud アカウントの登録ApsaraVideo Live の有効化が必要です。
  • ライブ Q&A スキームでは、アプリケーションサーバー経由で API を呼び出して SEI (Supplemental Enhancement Information) 信号をライブストリームに挿入し、ApsaraVideo の Q&A プレーヤーを使用して SEI 信号を解析します。

手順

手順 1:ライブ Q&A プロセスを理解します。
  1. 配信者が問題を出すと、オンサイトディレクターが問題を配信する準備をします。
  2. オンサイトディレクターは、アクセス側のアプリケーションサーバーを介して API を呼び出し、ライブビデオストリームの現在の場所に複数の SEI フレームを挿入します。 SEI コンテンツは、ビジネスニーズに基づいてカスタマイズできます。
  3. ApsaraVideo Player SDK はビデオストリームを受信し、ストリーム内の SEI フレームを解析し、アプリケーションにコールバックメッセージを送信します。 アプリケーションは、すぐにアプリケーションサーバーに問題のコンテンツをリクエストし、ユーザーにそのコンテンツを表示します。
    ストリームの取り込みには遅延があるため、オンサイトディレクターがクラウドサービスを使用して SEI 信号を挿入すると、SEI 信号が予想よりも早く画像に挿入される場合があります。 この問題を解決するために、オンサイトディレクターはストリーム取り込み遅延を事前に測定し、SEI 信号をライブストリームに挿入するときに遅延分を追加します。

    オンサイト配信者が 12:00:00 に問題を出し、サイトから Alibaba Cloud へのストリームの取り込みに 1 秒の遅延があるとします。 このシナリオでは、オンサイトディレクターは 12:00:01 に API を呼び出して SEI 信号を挿入する必要があります。 あるいは、オンサイトディレクターは 12:00:00 に API を呼び出して、API の delay1000 ms に設定します。 これにより、配信者が問題を出すタイミングで SEI 信号が画像に挿入されます。

    • SEI 信号を受信した後、クライアントはアプリケーションサーバーから問題を取得する必要があり、これには通信時間がかかります。 実際の Q&A システムでは、回答の提出期間を適切な範囲に (元の期間に基づいて 1 秒など) 延長できます。
    • ユーザーが問題に回答した後、クライアントは回答を通知する必要があり、これには通信時間がかかります。 実際の Q&A システムでは、アプリケーションサーバーは、ユーザーの回答送信期間に猶予を設けています。 たとえば、元の回答提出期間から 1 秒以内に受け取った回答はすべて有効と見なされます。
    次の図は、ライブ Q&A スキームのアーキテクチャを示しています。
手順 2:ApsaraVideo Live を有効化して、ライブ Q&A の開始を準備します。
  • 最初に ApsaraVideo Live を有効化します。
  • ドメイン名とアプリケーション名を含むチケットを送信して、ApsaraVideo で SEI 信号を挿入する機能を有効にします。
  • ストリームの取り込み時、取り込み URL に wm=1 パラメーターを追加します。
手順 3:アプリケーションサーバーを介して API を呼び出します。

前のプロセスで説明したように、アクセス側のアプリケーションサーバーは、次の API を呼び出してライブストリームに SEI 信号を挿入する必要があります。

または、ApsaraVideo のカスタム OBS ツールを使用して問題を配信することもできます。
  1. SEI 信号を挿入する API
    • パラメータのリクエスト
      名前 タイプ 必須/省略可能 説明
      Action String 必須 実行する操作。 値を AddTrancodeSEI に設定します。
      DomainName String 必須 CDN ドメイン名。
      AppName String 必須 ライブストリーミングアプリケーションの名前。
      StreamName String 必須 ライブストリームの名前。 SEI は、このストリームとすべてのエンコードされたストリームに挿入されます。
      Text String 必須 SEI テキスト。 長さの制限:4,000 バイト。
      Pattern String 必須 SEI をキーフレームまたはフレームに挿入するかどうか。

      有効な値:keyframe と frame。

      Repeat Integer 必須 SEI が挿入される回数。 値が -1 の場合、ライブストリーミングが終了するまで SEI が無制限に挿入されることを示します。
      Delay Integer 必須 リクエスト時に SEI を挿入するための遅延。 単位:ミリ秒。
    • レスポンスのパラメータ
      名前 タイプ 説明
      RequestId String Alibaba Cloud によって生成された、リクエストに対する GUID。
    • エラーコード
      エラーコード エラーメッセージ HTTP ステータスコード 説明
      InvalidDomain.NotFound The domain provided does not exist in our records. 404 このエラーメッセージは、ドメイン名が存在しないか、現在のユーザーに属していない場合に返されます。
      IllegalOperation Illegal domain operate is not permitted. 403 このエラーメッセージは、実行中の操作がサポートされていない場合に返されます。 たとえば、ドメイン名がライブストリーミングに使用されていないなどです。
      InvalidParams Invalid parameters 400 このエラーメッセージは、パラメーターが無効の場合に返されます。
      InternalError 不明なエラーのためにリクエスト処理に失敗しました。 500 このエラーメッセージは、バックグラウンドで不明なエラーが発生した場合に返されます。
  2. https://live.aliyuncs.com?Action=AddTrancodeSEI&Domain=test101.cdnpe.com&App=xxx&Stream=xxx&Text=hahaha&Pattern=frame&Repeat=300&Delay=0&<common request parameters>
    					
    ライブ Q&A シナリオでは、Patternframe に設定し、Repeat をキーフレーム間隔の 3 倍に設定することを推奨します。 (例では、Repeat は 300 ) これらの設定により、フレームが損失したとしても、プレーヤーが 3 回のキーフレーム間隔で 1 つのフレームを受信していれば SEI を取得できます。 フレーム内の SEI は互いに重複している可能性があるため、プレーヤーは SEI を重複排除する必要があります。
手順 4:ApsaraVideo Player SDK を統合して使用します。

最初に ApsaraVideo Player SDK を統合します。 詳細については、プレイヤー SDK > プロダクト紹介をご参照ください。

ライブ Q&A の場合、ApsaraVideo Player SDK には、SEI のコールバック機能が用意されています。 次のセクションでは、Android デバイスと iOS デバイス用の SEI コールバック API について説明します。
  1. Android デバイス用の SEI コールバック API
    プレーヤーで SEI コールバック API を設定して、ビジネス処理用の SEI を取得します。 方法は以下のとおりです。
    • setSEIDataListener

      public void setSEIDataListener(MediaPlayerSEIDataListener listener)

      説明:プレーヤーで SEI コールバック API を設定して、ストリームの SEI を取得します。

      パラメーター:listenerは、コールバックリスナーです。

    • MediaPlayer.MediaPlayerSEIDataListener

      public void onSEIdata(String data)

      説明:SEI コールバックメッセージをリッスンします。

      パラメーター:data は、コールバックされる SEI です。

    再生プロセスでは、同じ SEI は 1 度だけコールバックされます。
    aliVcMediaPlayer = new AliVcMediaPlayer(DemoLiveAnswerActivity.this, videoSurface);
    aliVcMediaPlayer.setSEIDataListener(new MediaPlayer.MediaPlayerSEIDataListener() {
            @Override
            public void onSEIdata(String data) {
                   praseData(data); // Parse SEI data.
            }
    });
    aliVcMediaPlayer.setMaxBufferDuration(3 * 1000);
    aliVcMediaPlayer.prepareAndPlay(liveUrl);
    
    private void praseData(String data) {
    // Parse the SEI into the format that meets the business needs and then perform business processing.
         JSONObject jsonObject = null;
         try {
             jsonObject = new JSONObject(data);
         } catch (JSONException e) {
             e.printStackTrace();
         }
    
         SeiInfo seiInfo = SeiInfo.getFromJson(jsonObject);
         if (seiInfo == null) {
             Toast.makeText(getApplicationContext(), "SEI data error", Toast.LENGTH_SHORT).show();
             return;
         }
    
         if (seiInfo.type.equals("startAnswer")) {
         // Request question content from the application server.
             requestQuestion(seiInfo.questionId);
         } else if (seiInfo.type.equals("showResult")) {
         // Request the Q&A summary from the application server.
             requestQuestionReport(seiInfo.questionId, seiInfo.showTime);
         }
    
     }
    						

    詳細については、デモをご参照ください。

  2. iOS デバイス用の SEI コールバック API

    プレーヤーで SEI データ通知をリッスンし、SEI データを取得します。 通知は次のとおりです。

    AliVcMediaPlayerSeiDataNotification

    リスニング通知 API を追加します。
    // The message received during live Q&A.
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(onSeiData:)
                                                     name:AliVcMediaPlayerSeiDataNotification object:self.mediaPlayer];
    
    							
    リスニング通知の SEI を処理します。
    // Answer questions.
    - (void)onSeiData:(NSNotification *)notification{
        /*
        {
         "questionId": "001”,
         "type": "startAnswer"
         } Start to answer questions.
    
         {
         "questionId": "001”,
         "type": "showResult",
         "showTime": "5"
         } Show the Q&A result.
    
         */
        NSDictionary* dict = [notification userInfo];
        if (dict) {
            NSString* seiData = [dict objectForKey:@"seiData"];
            if (seiData) {
                NSLog(@"sei data is %@",seiData);
        }
    
      }
    							

    詳細については、デモをご参照ください。

考慮事項

  • プレーヤーの遅延に対処する方法

    各端末で同じ遅延となるように、最長のプレーヤー遅延を設定します。 通常、遅延が長いほどジッタ耐性が強いことを示し、遅延が短いほどビデオ停止率が高いことを示します。 ライブ Q&A のリンク全体の総合的な遅延を考慮すると、遅延設定は各問題の有効期間に影響します。 プレーヤーの遅延が 3 秒で、回答提出期間が 10 秒の場合、各質問の有効期間は 13 秒 (10 秒 + 3 秒)です。

    @property(nonatomic, readwrite) int dropBufferDuration; で、dropBufferDuration パラメーターに iOS デバイスのプレーヤー遅延をミリ秒単位で指定します。

    public void setMaxBufferDuration(int duration); で、setMaxBufferDuration API が Android デバイスのプレーヤー遅延を制御します。 duration パラメーターには、プレーヤーの遅延をミリ秒単位で指定します。

  • 問題の配信遅延に対処する方法

    SEI 信号を受信した後、クライアントはアプリケーションサーバーから問題を取得する必要があり、これには通信時間がかかります。 問題の配信時、必要に応じて expiredSeconds を増やします (1 秒など)。