2022年05月16日

ライブ配信時の「受講者発言リクエスト」WebRTCサンプル(Agora.io Video、Real-time Messaging SDK利用)

今回はAgora.io Video SDKAgora.io Real-time MessagingSDKを利用したライブ配信サービスでの「受講者発言リクエスト」機能のWebRTCサンプルをご紹介します。

「受講者発言リクエスト」機能とは、ライブ配信中に質問や意見を発したい受講者(視聴のみ)に対応するための機能で、受講者が発言リクエストを配信者に送信し許可されると、受講者の映像・音声が有効になり、配信者と受講者にてリアルタイムに会話ができる機能になります。

資料ダウンロード  【すぐ読める!ガイドブック】ビデオ通話・ライブ配信SDK「Agora」  ビデオ通話やライブ配信の機能をあらゆるアプリケーションに簡単に実装できるSDKの特徴から活用例まで徹底解説! 無料ダウンロード

利用するSDK

・agora.io VideoSDK(Web)
・agora.io Real-time Messaging SDK(Web)

サンプルコード

機能一覧

受講者側

・受講者発言リクエスト

配信者側

・受講者発言リクエスト応答(許可/拒否)
・受講者発言オン
・受講者発言オフ

※基本機能(入室/退室など)は省略しています。

シーケンス

受講者発言リクエストの流れは以下になります。

※ざっくりと流れをつかむ目的のため、細かい部分は省略しています。

実装のポイント

配信者、受講者の役割を分けるには

・入室時、配信者の場合はストリームをパブリッシュし、受講者の場合はパブリッシュしません。
(これにより配信者のみが映像・音声を送信し、受講者は視聴のみとなります。)
・受講者発言リクエスト許可時、受講者のストリームをパブリッシュします。
 (これにより受講者の映像・音声が送信され発話できるようになります。)

受講者発言リクエストを送信/応答するには

・Agora.io Real-time Messaging SDKを利用して接続し、テキストメッセージを受講者から配信者に送信します。
 (これにより配信者側でテキストメッセージごとに応答処理を切り分けます。)

実装

※追加・変更分のみ記載します。

Join時のパブリッシュ制御

Join時は配信者のみストリームをパブリッシュするように変更します。

index.js

    async function join() {
      /*省略*/
      //hostの場合のみpublishする
      if(options.role == "host"){
        [localTracks.audioTrack, localTracks.videoTrack ] = await Promise.all([
          // create local tracks, using microphone and camera
          AgoraRTC.createMicrophoneAudioTrack(),
          AgoraRTC.createCameraVideoTrack()
        ]);
        // play local video track
        localTracks.videoTrack.play("local-player");
        $("#local-player-name").text(`localVideo(${options.uid})`);
        // publish local stream
        // publish local tracks to channel
        await client.publish(Object.values(localTracks));
        console.log("publish success");
      }
    }
    

Real-time Messaging SDKの追加

index.html
  <script src="agora-rtm-sdk-1.4.1.js"></script> 
    

受講者発言用UIの追加

index.html
<form id="join-form">
    .....(省略)
     <div class="form-group w-25">
      <div class="form-check">
        <input class="form-check-input" type="radio" name="role" id="role" value="host" checked>
        <label class="form-check-label" for="host">host</label>
      </div>
     <div class="form-check">
        <input class="form-check-input" type="radio" name="role" id="role" value="audience">gt;
        <label class="form-check-label" for="audience">audience</label>
      </div>
     </div>
    </form>
    
    <div class="input-group mb-2 w-50">
      <div class="input-group-prepend">
        <span class="input-group-text">Message</span>
      </div>
      <textarea type="text" class="form-control" id="messageDisp" ></textarea>
    </div>
    <div class="button-group mb-2">
      <button id="request" class="btn btn-info btn-sm">REQUEST</button>
    </div>
    
    <div class="input-group mb-2 w-25">
      <div class="input-group-prepend">
        <span class="input-group-text">Audience ID</span>
      </div>
      <select type="text" class="form-control" id="audienceId" ></select>
    </div>
    
    <div class="button-group mb-2">
      <button id="muteOfRemote" class="btn btn-info btn-sm">MUTE</button>
      <button id="unmuteOfRemote" class="btn btn-info btn-sm">UNMUTE</button>
    </div>
    

各種ボタンクリック時処理の追加

index.js
$("#unmuteOfRemote").click(function (e) {
      console.log("unmuteOfRemote")
      unmuteOfRemote();
    })
    
    $("#muteOfRemote").click(function (e) {
      console.log("muteOfRemote")
      muteOfRemote();
    })
    
    $("#request").click(function (e) {
      console.log("request")
      request();
    })
    
    

メッセージ処理の追加(送信部分)

index.js
function sendChannelMessage(localMessage){
      setDispMessage(localMessage);
      rtc.channelRtm.sendMessage({text:localMessage}).then(function(){
    console.log("AgoraRTM client succeed in sending channel message: " + localMessage);
      }).catch(function(err){
    console.log("AgoraRTM client failed to sending role" + err);
      });
    }
    

メッセージ処理の追加(受信部分)

function receiveChannelMessage(){
        //省略//
      rtc.channelRtm.on("ChannelMessage", function (sentMessage, senderId) {
        console.log("AgoraRTM client got message: " + JSON.stringify(sentMessage) + " from " + senderId);
    
        setDispMessage(sentMessage.text);
        console.log((sentMessage.text == senderId + ":requested") && (options.uid == host));
        if ((sentMessage.text == senderId + ":requested") && (options.uid == host)){
          var res = confirm("Are you sure " + senderId + " to be speaker?");
          (res == true) ? permit(senderId) : deny(senderId);
    
        }
        //省略//
      });
    }
    

動作確認

実装が完了したので動作を確認します。

1. 初期表示

1-1.index.htmlファイルをクリックし起動します。

 

2. 入室(配信開始)

2-1.(配信者/受講者)"APPID"を入力します。

2-2.(配信者)Roleで"host"を選択し"Join"ボタンをクリックします。

2-3.(受講者)Roleで"audience"を選択し"Join"ボタンをクリックします。

この時点で配信者の映像・音声が受講者側に送信されます。

配信者側
受講者側

3. (受講者)発言リクエスト送付

受講者が"Request"ボタンをクリックします。

 

4. (配信者)リクエスト許可

4-1.配信者側に受講者発言リクエストの確認ダイアログが表示されます。

4-2.配信者はOKをクリックし許可します。

5. (受講者)映像・音声の有効化

5-1.受講者側にカメラ・マイク許可ダイアログが表示されます。

5-2.受講者は許可をクリックします。

5-3.配信者側、受講者側両方に受講者の映像・音声が送信されます。

配信者側
受講者側

5-4.配信者、受講者で会話します。

6. (配信者側)受講者発言オフ

6-1.(配信者)受講者の"AudienceID"を選択します。

6-2.(配信者)"MUTE"ボタンをクリックします。

 

受講者が発言前(視聴のみ)に戻ります。

7. (配信者側)受講者発言オン

7-1.(配信者)受講者の"AudienceID"を選択します。

7-2.(配信者)"UNMUTE"ボタンをクリックします。

 

受講者が再び発言の状態になります。

受講者発言リクエストができました。

 

資料ダウンロード  【一気に読める!】Agora 導入事例集  オンラインフィットネス・カウンセリング、音声サービスやファンサービスなど、バラエティに富んだ導入事例をご紹介! 無料ダウンロード
ブイキューブ

執筆者ブイキューブ

Agoraの日本総代理店として、配信/通話SDKの提供だけでなく、導入支援から行い幅広いコミュニケーションサービスに携わっている。

関連記事

先頭へ戻る