Web サイト統合

Genvid の公開方法は、すべてのゲームで異なるため、ゲームごとにカスタマイズした Web サイトが必要です。これには、スキン面 (HTML、CSS) と機能面 (JavaScript) のカスタマイズがあります。ブラウザ用 Web アプリケーションをホストする Web サーバーも実行する必要があります。

Web サイトの作成方法は複数存在します。このセクションでは Genvid SDK に共通する手順に限定して説明します。

バックエンドの統合

Genvid Web クライアントは、leaf というサービスにアクセスする必要があります。このサービスは、クライアントがゲームデータにアクセスするための Web ソケットサーバーを提供します。このサービスの接続 URL を取得するには、2 つの Web リクエストを Disco サービス API に送信する必要があります。

API は、セキュリティのためセキュリティコードを使用します。そのため、信頼できる Web サイトからのみ呼び出すようにしてください。チュートリアル Web サイトでは、 routes/streams.t.ts ファイル内に、 /streams/channels/join URL を送っています。

disco サービスが Consul に登録され、URL を見つけることができます。

注釈

API の将来のバージョンでは、サードパーティのサービスでユーザーを認証し、この認証を使って Web ソケットの割り当てに使用する API を公開予定です。これにより、API の安全性を向上することができます。現時点では、この機能は無効のため、このバージョンでは認証確認は行っていません。

コマンドと通知の統合

コマンドと通知サービスは、エンドポイントの 2 つのカテゴリを公開します。

  • /commands は、ゲームに直接コマンドを送信します
  • /notifications は、視聴者に直接通知を送信します

これらは強力な機能であり、公共の用途には使用しないことをお勧めします。

詳細は、コマンドと通知サービス API を参照してください。

JavaScript API

Genvid は 2 つのライブラリを提供しています。

  • genvid leaf への接続、ストリームのデコード、ビデオプレイヤーの作成、データとビデオの同期に必要なロジックを含みます。
  • genvid-math WebGL オーバーレイなどを作成するための、様々なジオメトリ演算ユーティリティ関数を提供します。サンプル で、このライブラリの使用例をご確認ください。

この 2 つのライブラリは、それぞれ 2 つのバンドルに含まれています:

  • NPM パッケージアーカイブ ローカル NPM パッケージ としてインポート可能な gzip 圧縮された tarball ファイル。ES6 構文で依存関係のインポート、好きなメソッドを使用してプロジェクトのバンドルができます。タイプ定義へのアクセスも可能です。

    Unity サンプルWebpack を使用したバンドルの例もご確認ください。

  • UMD js モジュール グローバル変数 genvidgenvidMath の公開など、様々な方法でライブラリのインポートを可能にする UMD モジュール 。タイプ定義へのアクセスはありません。Unity を除き、すべてのクライアントサンプルがこのメソッドを使用しています。

注釈

「genvid」 および 「genvid-math」 の依存関係を使用する優先メソッドは、NPM パッケージのインポートとなりました。タイプ定義を直接ソースコードに含めることはお勧めしていません。下位互換のため、古いタイプ定義も api/web/legacy_types フォルダで提供しています。Unity を除くすべてのゲーム統合サンプルでこのメソッドを使用しています。新しいプロジェクトを作成する際には、 Unity サンプル のご参照を強くお勧めします。

フロントエンドの統合

Genvid のフロントエンドへの統合の最初のステップは、 genvidClient.createGenvidClient() を使用して genvidClient.IGenvidClient() をインスタンス化することです。

let client = genvid.createGenvidClient(streamInfo, websocketURL, websocketToken, video_player_id);

1 つ目のパラメータ streamInfo は、 genvidClient.IStreamInfo() 構造体に対応し、通常は、 POST /disco/stream/join コールからのバックエンドサービスで返されます。

次の 2 つのパラメータ、 websocketURLwebsocketToken は、それぞれ Websocket アドレスとセキュリティトークンを指定する値です。 POST /disco/stream/join コールによりバックエンドで提供されます。

最後のパラメータ video_player_id は、ライブストリーミングビデオプレイヤーを使用する HTML 要素を参照する文字列です。 IGenvidClient() がビデオプレイヤーを作成した時に、この HTML 要素がライブストリーミングサービスのものに置き換えられます。

onVideoPlayerReady コールバック

プレイヤーの作成時、 IGenvidClient()genvidClient.IGenvidClient.onVideoPlayerReady() で指定された関数を呼び出します。これは通常、オーバーレイの連携に使用します。

client.onVideoPlayerReady( function(elem) { console.log('Create the overlay!'); } );

onAuthenticated コールバック

onAuthenticated() のコールバックは、 IGenvidClient() が Genvid Services にうまく接続できたことを通知します。

client.onAuthenticated( function(succeed) { if (succeeded) { console.log('Connected!'); } });

onStreamsReceived コールバック

onStreamsReceived() コールバックは、新しいストリームデータを受信したことを通知します。レンダリング前にデータのデコードや分析をする時に、役立ちます。

client.onStreamsReceived((streams) => { myGameOverlay.onStreamsReceived(streams); });

onNotificationsReceived コールバック

通知は、情報を迅速に転送します。タイムコードには関連付けられません。 IDataNotifications() インターフェイスで記述を行います。

client.onNotificationsReceived((notifications) => { myGameOverlay.onNotificationsReceived(notifications); });

onDraw コールバック

onDraw() コールバックは、オーバーレイの描画のために定期的に (一般的には秒間 30 回) 呼び出すルーチンを指定します。

client.onDraw((frame) => { myGameOverlay.onDraw(frame); });

onDraw() コールバックを呼び出すと、このビデオフレームのタイムコード、さまざまなストリームからのデータ、ビデオ合成の情報を含む genvidClient.IDataFrame() インスタンスを受け取ります。フレームデータは以下のように構成されています。

  • データソースが複数存在する場合、各セッションのストリームとアノテーションデータを公開するセッションプロパティ内で取得できます。
  • ストリームが 1 つしかない場合、IDataFrame インスタンスのルートで、ストリームとアノテーションにアクセスすることもできます。

合成データ (genvidClient.ISourceCompositionData() の配列) は、どのトランスフォーメーションがさまざまなビデオストリームに適用されたかに関する情報です。利用方法としては、ビデオオーバーレイのどのピクセルが、どのビデオソースに対応するかを知ったり、1 つのビデオソースに関連するオーバーレイが、別のビデオに重なることを防ぐためのクリッピング操作を行ったりすることです。

ストリームとアノテーションの動作は異なりますが、どちらも genvidClient.IDataStreamFrame() の構造体で記述します。

現在のストリームにはストリームの最新フレームのみが含まれていますが、アノテーションには、それまでに蓄積されたすべてのフレームが保持されており、次回同じ処理は繰り返されません。

Genvid は、 rawdata フィールドを使用してバイナリ形式でデータを送信します。これは、JavaScript の ArrayBuffer() です。データはどのようにでも読み取ることができますが、Genvid はデコードに役立つユーティリティルーチンをいくつか提供しています。

たとえば、ゲームが UTF-8 形式にエンコードされた JSON データを送信する場合、Website のコードは、 rawdata バイナリフィールドを UTF-8 にデコードし、その文字列を JSON として解析する必要があります。

onDraw(frame) {
   let stream = frame.streams["position"]
   let datastr = genvid.UTF8ToString(frame.rawdata);
   stream.user = JSON.parse(datastr);
   console.log(stream.user.myPosition);
}

Genvid はデータが繰り返されることがある (たとえば、ストリームのフレームレートが低い場合など) ため、同一データを複数回デコードしてしまうことを防ぐ機能を搭載しています。 IGenvidClient() には onStreamsReceived() が含まれています。これは、データを受け取った時に、 genvidClient.IDataStreams() のコレクションを渡します。データストリームは、ビデオストリームとフレームのコレクションを含み、調整を行って Genvid の同期エンジンに統合することができます。たとえば、予定のイベントを検知するためにコレクション解析したり、コレクションを完全に削除したりなどです。

また、ゲームプロセスからのデータ送信時に使用される形式に違反しないかぎり、 streamId ごとに、デコードするための関数を調整することもできます (ゲームデータストリーミング を参照)。

ゲームの Web サイトのコードの準備ができたら、次のコマンドで GenvidClient のストリーミングを開始できます。

client.start();

IGenvidClient() は、設定したコールバックを自動的に使用して、ストリーミングビデオと onDraw() で送信されるゲームデータの同期処理を行います。

onDisconnect コールバック

Websocket が閉じたときに、onDisconnect() コールバックが呼び出されます。このコールバックに機能をバインドして、ソケットが閉じたことを通知させることもできます。

client.onDisconnect(() => {this.onDisconnectDetected();});

reconnect コールバック

reconnect() が新しい websocket 接続を確立します。新しいストリーム情報、新しい leaf URI、新しいトークンをパラメータとして受信します。

client.reconnect(info, uri, token);

オーバーレイ

Genvid では厳密なオーバーレイ API は提供されていませんが、オーバーレイを動作させるための IGenvidClient() に必要なものはすべて公開されています。また、すべてのサンプルに使用する WebGL ユーティリティルーチンも公開しています。

オーバーレイのメインエントリポイントは、 onDraw() を使用して設定されたコールバックです。一定間隔で、ゲーム内に存在するすべてのストリームのデータフレームで、指定されたコールバックが呼び出されます。

このコールバックが、すべてのストリームの最新ゲームデータフレームを受け取ります。このデータは、WebGL キャンバスに 3D ハイライトをレンダリングしたり、HTML 要素を変更して現在のゲームの統計情報を表示したり、ボタンの可視性を調整して視聴者参加型ゲームイベントを許可したりなど、自由に処理することができます。

WebGL を簡単にレンダリングできるように、Genvid には、WebGL の反復タスクを簡略化する genvidWebGL.IWebGLContext() class が用意されています。これは、 genvidWebGL.createWebGLContext() メソッドで作成できます。

イベント

イベントは、 IGenvidClient() インスタンスで Genvid サービスに戻すことができます。詳細は、 sendEvent() および sendEventObject() を参照してください。

Google Chrome の自動プレイサポート

Google Chrome には、ビデオ再生処理関する 特別なポリシー が存在します。弊社 API では、対応するビデオプレイヤーすべてに autoplay のタグセットが存在します。これにより、Firefox などのブラウザや、Media Engagement Index を適切なレベルに設定した Web サイトから自動的に動画再生を開始することが出来ます。

Chrome など、ほとんどのブラウザで自動ビデオ再生を有効にするには、ビデオをミュートに設定することも出来ます。動画をポーズしたときに、画面が停止したまま固まってしまうことを防ぐため、必ずオーバーレイを隠す必要があります。以下にサンプルコードを示します。

client.onVideoPlayerReady( (elem) => {

    // Optional: Set to muted to autostart even on Chrome and also iOS.
    client.videoPlayer.setMuted(true);

    // Always safe to hide the overlay on startup.
    // The PLAYING event below will show it.
    myGameOverlay.hide();

    client.videoPlayer.addEventListener(genvid.PlayerEvents.PAUSE, () => {
      myGameOverlay.hide();
    });

    client.videoPlayer.addEventListener(genvid.PlayerEvents.PLAYING, () => {
      myGameOverlay.show();
    });
});