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);