WebController - Genvid クライアント初期化

Genvid クライアント初期化セクションには、ストリーム開始、さまざまな変数の初期化、イベントリスナーの割り当てに必要なほとんどのコードが含まれています。

start

start()

start メソッドがサービスへの接続を開始します。接続が適切に実行できると、検出した IChannelJoinResponse()onChannelJoin メソッドを実行します。

  // Starts the connection to the services
  start() {
    fetch("/api/public/channels/join", {
      method: "POST",
    })
      .then((data) => data.json())
      .then((res) => {
        if (res.name === "Error") {
          genvid.error(`Failed getting stream info: ${res.message}. Retrying in ${this.fiboStartIterator.get()} seconds...`);
          setTimeout(() => {
            this.start();
            this.fiboStartIterator.next();
          }, this.fiboStartIterator.get() * 1000);
        } else {
          this.onChannelJoin(res);
        }
      })
      .catch((error) => genvid.error(`Can't get the stream info: ${error}`));
  }

onChannelJoin

onChannelJoin(joinRep)

onChannelJoin メソッドは、サービスとチャネルに接続後、Genvid クライアントを作成します。このプロセスで検出された情報と、class 作成プロセスで送信された videoPlayerId を使用してクライアントを作成します (これは WebController class の引数です)。

その後、この class に特定のイベントを関連付ける必要があります。

onVideoPlayerReady
ビデオストリームの準備が完了した時にトリガします (コンテンツの初期化に使用)。
onStreamsReceived
ストリームコンテンツを受信した時にトリガします (タイムコードとゲームデータの取得に使用)。
ゲームデータの取得に使用)。
onNotificationsReceived
通知を受信した時にトリガします (popularity に使用)。
onDraw
ビデオで新しいフレームの描画時にトリガします。

次に、start() メソッドでクライアントを開始します。

  // Creates the genvid Client and the functions listening to it
  onChannelJoin(joinRep) {
    genvid.getConfig().framePerSeconds = 30; // Defines the rate at which onDraw is called (default being 30).
    this.genvidClient = genvid.createGenvidClient(
      joinRep.info,
      joinRep.uri,
      joinRep.token,
      this.videoPlayerId
    );

    this.genvidClient.onStreamsReceived((streams) =>
      this.onStreamsReceived(streams)
    );
    this.genvidClient.onDraw((frame) => this.onNewFrame(frame));
    this.genvidClient.onNotificationsReceived((notifications) => {
      this.onNotificationsReceived(notifications);
    });
    this.genvidClient.onDisconnect(() => this.onDisconnectDetected());
    this.genvidClient.onVideoPlayerReady((elem) =>
      this.onVideoPlayerReady(elem)
    );
    this.genvidClient.start();
  }

onDisconnectDetected

oDdisconnecDdetected()

このサンプルでは、onDisconnect() コールバック (IGenvidClient() インターフェイスにより公開) を使って、クライアントのソケットが閉じるタイミングを通知します。指定のコールバックをバインドすることで、実行しています。

thD.client.oDisconnect(() => {this.onDisconnectDetected();});

クライアントソケットの閉鎖通知が届いたら、スクリプトに再接続試行の指示を行います。

  onDisconnectDetected() {
    genvid.info("Disconnected");
    fetch("/api/public/channels/join", {
      method: "POST",
    })
      .then((data) => data.json())
      .then((res) => {
        this.genvidClient.reconnect(res.info, res.uri, res.token);
        this.fibonacciIterator.reset();
      })
      .catch(() => {
        genvid.info(
          `Will reconnect in ${this.fibonacciIterator.get()} seconds`
        );
        return this.sleep(this.getNewSleepDuration()).then(() =>
          this.onDisconnectDetected()
        );
      });
  }

ここで、新しい leaf アドレス、新しいトークン、新しい streamInfo の情報リクエストを開始します。

リクエストが成功した場合、reconnect() を呼び出して、この情報を使用して新しい websocket 接続を確立します。

リクエストが失敗した場合 (利用可能な leaf がないなど)、しばらく待って再試行します。増分フィボナッチ数の計算結果を使用して、待機時間を決定します。

  sleep(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
  }

フィボナッチ数列の結果に 10% のランダム要素を追加します。これにより、2 つのサービスが同時に接続を開始する状況を回避します。接続が成功した際にフィボナッチ数をリセットします。

onVideoPlayerReady

onVideoPlayerReady(videoPlayerElement)

変数の開始、WebGL コンテキストの作成、イベントリスナーの追加に使用します。

  1. この関数では、Div と Link 各要素のほとんどを JQuery で取得します。

        this.timeCamSceneDiv = document.querySelector("#timeCamScene_overlay");
        this.volumeDisplay = document.querySelector("#volume_display");
        this.videoOverlay = document.querySelector("#video_overlay");
        this.canvas3d = document.querySelector("#canvas_overlay_3d");
        this.genvidOverlayButton = document.querySelector("#genvid_overlay_button");
        this.genvidOverlay = document.querySelector("#genvid_overlay");
        this.helpOverlay = document.querySelector("#help_overlay");
        this.helpButton = document.querySelector("#help_button");
        this.fullScreenIcon = document.querySelector(".fa-expand");
        this.pipFrameDiv = document.querySelector("#pip_frame");
    
        const mouseOverlay = document.querySelector("#mouse_overlay");
        mouseOverlay.addEventListener(
          "click",
          (event) => this.clickScene(event),
          false
        );
    
        const fullScreenButton = document.querySelector(".fullscreen-button");
        fullScreenButton.addEventListener(
          "click",
          () => {
            this.toggleFullScreen();
          },
          false
        );
    
        // Debug overlay
        this.timeLocalDiv = document.querySelector("#time_local"); // browser clock current time
        this.timeVideoDiv = document.querySelector("#time_video"); // video player current time
        this.timeComposeLastDiv = document.querySelector("#time_compose_last");
        this.timeStreamDiv = document.querySelector("#time_stream");
        this.latencyDiv = document.querySelector("#latency");
        this.delayOffsetDiv = document.querySelector("#delay_offset");
    
    
        document.addEventListener("fullscreenchange", () => {
          this.onResize();
        });
        document.addEventListener("webkitfullscreenchange", () => {
          this.onResize();
        });
        document.addEventListener("mozfullscreenchange", () => {
          this.onResize();
        });
    
        window.addEventListener(
          "resize",
          () => {
            this.onResize();
          },
          true
        );
        window.addEventListener(
          "orientationchange",
          () => {
            this.onResize();
          },
          true
        );
        window.addEventListener(
          "sizemodechange",
          () => {
            this.onResize();
          },
          true
        );
    
        this.genvidOverlayButton.addEventListener(
          "click",
          () => this.toggleGenvidOverlay(),
          false
        );
        this.helpButton.addEventListener(
          "click",
          () => {
            this.onHelpActivation();
          },
          false
        );
        const muteIcon = document.getElementById("mute-button");
        muteIcon.addEventListener("click", () => this.toggleMute());
    
  2. canvas3d を選択して WebGLContext を作成します。

  3. ウィンドウ変更のイベントリスナー (全画面、サイズ変更) をすべて追加します。

  4. ここでは、クリックインタラクションのイベントリスナーを mouseOverlay (ビデオオブジェクトのクリック)、 Genvid ボタン、 Help ボタンに追加します。

          this.videoPlayer = this.genvidClient.videoPlayer;
          this.genvidClient.videoPlayer.addEventListener(
            genvid.PlayerEvents.PAUSE,
            () => this.hideOverlay()
          );
          this.genvidClient.videoPlayer.addEventListener(
            genvid.PlayerEvents.PLAYING,
            () => this.showOverlay()
          );
    
          videoPlayerElement.addEventListener("resize", () => {
            this.onResize();
          });
    
          // GENVID - init video player stop
    
          // We have to have a mute by default because of the autoplay policy
          if (!this.videoPlayer.getMuted()) {
            this.toggleMute();
          }
    
  5. onResize() を実行して、適切なウィンドウサイズにオーバーレイを合わせます (この処理を行わないと、オーバーレイが小さくなりすぎます)。

  6. 最後に WebGL オーバーレイを初期化します。

        this.initThreeJS(this.canvas3d);