WebController - Genvid クライアント初期化¶
Genvid クライアント初期化セクションには、ストリーム開始、さまざまな変数の初期化、イベントリスナーの割り当てに必要なほとんどのコードが含まれています。
In This Section
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 => 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 コンテキストの作成、イベントリスナーの追加に使用します。
この関数では、Div と Link エレメントのほとんどを JQuery で取得します。
this.videoPlayer = this.genvidClient.videoPlayer; 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.clickCube(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");
canvas3d を選択して WebGLContext を作成します。
ウィンドウ変更のイベントリスナー (全画面、サイズ変更) をすべて追加します。
mouseOverlay のクリック操作用イベントリスナー (ビデオオブジェクトのクリック判定用)、 Genvid ボタン、 Help ボタンのクリック操作用イベントリスナーを追加します。
this.hideOverlay(); this.genvidClient.videoPlayer.addEventListener(genvid.PlayerEvents.PAUSE, () => this.hideOverlay()); this.genvidClient.videoPlayer.addEventListener(genvid.PlayerEvents.PLAYING, () => this.showOverlay()); document.addEventListener("fullscreenchange", () => { this.onResize(); }); document.addEventListener("webkitfullscreenchange", () => { this.onResize(); }); document.addEventListener("mozfullscreenchange", () => { this.onResize(); }); videoPlayerElement.addEventListener("resize", () => { 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()); // We have to have a mute by default because of the autoplay policy if (!this.videoPlayer.getMuted()) { this.toggleMute(); }
onResize() を実行して、適切なウィンドウサイズにオーバーレイを合わせます (この処理を行わないと、オーバーレイが小さくなりすぎます)。
最後に WebGL オーバーレイを初期化します。
this.genvidWebGL = genvid.createWebGLContext(this.canvas3d); // Inits genvidWebGL - not mandatory, any webGL framework can be used. this.onResize(); // Initialize graphics stuff. this.genvidWebGL.clear(); this.genvidWebGL.gl.disable(this.genvidWebGL.gl.DEPTH_TEST); this.gfxInitShaders(); this.gfxInitRenderCommands(); this.videoReady = true;