フロントエンド開発者およびフルスタック開発者向けに、HappyOyster Web SDK の Adventure、Directing、Acting モードを本番環境へ安定して統合する方法を説明します。
0. 最小限の統合例
バックエンドから Model Studio の一時 API キー token と Travel の ticket が返されたら、フロントエンド SDK では次のフローを実行します。
ticket の取得、Model Studio の一時 API キー token の取得は、すべてアプリケーションのバックエンドで、またはバックエンドを介して行ってください。
1. 全体フローの概要
体験全体には、主に次の構成要素が関わります。
1.1 構成要素
構成要素 | 役割 |
|---|---|
アプリケーションのフロントエンド | UI、 |
アプリケーションのバックエンド | プライマリ API キーを保管し、クライアントに代わって Open Platform のワールド API を呼び出し、Model Studio の一時認証情報を発行します |
HappyOyster OpenAPI | HappyOyster ワールドモデルに必要な API を提供します。 |
HappyOyster SDK | アプリケーションのフロントエンドで使用する SDK です。主にクライアント側の Travel セッションと動画ストリームへのアクセスを管理します。 |

1.2 体験フロー
段階 | 実行主体 | 操作 | 説明 |
|---|---|---|---|
① ワールドを作成 | アプリケーションのバックエンド → HappyOyster OpenAPI |
|
|
② 準備完了まで待機 | アプリケーションのバックエンド → HappyOyster OpenAPI |
|
|
③ Travel 認証情報を取得 | アプリケーションのバックエンド → HappyOyster OpenAPI |
| enter-travel 用の使い捨て |
④ 一時 API キートークンを取得 | アプリケーションのバックエンド → HappyOyster OpenAPI |
| 一時 API キーの |
⑤ 一時 API キートークンと Travel 認証情報を渡す | アプリケーションのフロントエンド → アプリケーションのバックエンド → アプリケーションのフロントエンド | 一時 API キーと Travel 認証情報をリクエストします | フロントエンドが |
⑥ 体験を開始 | アプリケーションのフロントエンド → HappyOyster SDK | 後述の「SDK 起動サブフロー」を参照してください |
|
1.3 SDK 操作サブフロー(段階 ⑥ の詳細)
1.3.1 Travel の開始

手順 | API | 説明 |
|---|---|---|
1 |
| 同じ |
2 |
|
|
3 |
|
|
4 |
|
|
5 |
| 正常に開始すると |
1.3.2 Adventure モードでの操作

1.3.3 Directing / Acting モードでの操作

モード | 主な API | 主な用途 | 注意点 |
|---|---|---|---|
Adventure ( |
| キーボード、ジョイスティック、ボタンによるリアルタイム制御 |
|
Directing ( |
| 自然言語による演出と再生制御 | 一時停止、再開、巻き戻しはセッションの機能に依存します。まず |
Acting ( |
| 演技中心の体験とアスペクト比の設定 | 一時停止と再開はセッションの機能に依存します。 |
1.4 アプリケーションのバックエンド実装の要点
バックエンドでは、次のルールを厳守してください。
- プライマリ API キーはアプリケーションのバックエンドでのみ保管します。ブラウザには有効期間の短い
tokenのみを渡してください(デモ:POST /server-api/temp-api-key)。 - Travel 認証情報はバックエンドを介して取得します。
ticketの発行前にワールドとユーザーの権限を確認し、フロントエンドにハードコードしたり長期間キャッシュしたりしないでください。 - ワールドが
readyになるまで認証情報を発行しないでください。それ以前に発行すると、enter-travel が失敗したり体験が不完全になったりする場合があります。 - アプリケーションのバックエンドと SDK は同じ Open Platform 環境に接続してください。バックエンドでは完全な OpenAPI URL を使用できますが、SDK の
APIHostにはopen-platform.example.comのようにホスト名のみを指定します。
2. SDK の主要概念
第 1 節のフローのうち、SDK が担当するのは「Travel に入る → 再生 → 制御 → 終了」の部分です。主要なオブジェクトは次の 2 つです。
オブジェクト | 用途 |
|---|---|
|
|
| 1 つのセッションを表します。 |
statusChanged):
- 各 Engine で同時にアクティブにできる Travel は 1 つだけです。
videoElementをcreateTravelに渡す必要があります。- Model Studio の一時 API キートークンと Travel チケットは用途が異なります(第 1.2 節の段階 ④~⑤、および第 3.2 節を参照)。
3. 初期化とトークン管理
3.1 Engine のインスタンス化
必須事項
APIHostには、https://などのスキームやパスを含めず、open-platform.example.comのように Open Platform のホスト名のみを設定します。HappyOysterEngineは同じAPIHost + modelに対して再利用します。ホストまたはモデルを変更する前に、アクティブな Travel を終了し、新しい接続先に合わせて設定した Engine を使用してください。
- 開発環境では
logLevel: 'debug'、本番環境では'warn'または'none'を使用します。 - 開始のたびに新規作成せず、セッションのオーケストレーション層で Engine を作成します。
フィールド | 必須事項 | 設定方法 |
|---|---|---|
| はい |
|
| はい | 必須で、デフォルト値はありません。ワールドの作成とチケットの発行にバックエンドが使用するモデルと一致させてください。Engine ごとに固定され、 |
| いいえ | コンストラクターに渡すか、後から |
| いいえ | 開発環境では |
| いいえ | ネットワーク接続やレンダリングの準備に時間がかかる場合は値を増やし、タイムアウト後に再試行できるようにします |
- レンダリング中や頻繁に実行される処理で
new HappyOysterEngine()を繰り返し呼び出すこと。 https://を含むような完全な URL を渡すこと、またはAPIHostを省略したまま SDK のバックエンド API を呼び出すこと。
3.2 2 種類の認証情報
第 1.2 節の段階 ③~⑤ に対応します。
認証情報 | 取得元 | 設定方法 | 用途 |
|---|---|---|---|
Model Studio の一時 API キートークン | アプリケーションのバックエンドが発行する有効期間の短いキー |
| SDK から Open Platform へのリクエストを認証します |
Travel チケット | アプリケーションのバックエンドがリクエストする Travel 認証情報 |
| Travel セッション用の使い捨て認証情報 |
travel.start()の前に両方の認証情報を準備します。- SDK はトークンを永続化も自動更新もしません。
- トークンが期限切れになった場合、または
onErrorでハートビートエラーを受信した場合は、アプリケーションのバックエンドを介して新しいトークンを取得し、updateTokenを呼び出します。
- 2 種類の認証情報を混同すること。
- プライマリ API キーをアプリケーションのフロントエンドに公開すること。
4. Travel のライフサイクル
4.1 作成と開始
必須事項
createTravel({ ticket, videoElement })を呼び出します。ticketは使い捨ての Travel 認証情報で、videoElementもこの時点で渡します。statusChangedとonErrorはawait travel.start()の前に登録し、エラーや状態変更を確実に監視できるようにします。
prepare中は接続中の UI を表示し、重複クリックを防ぎます。travelInfoReadyでセッションのメタデータを早期に取得し、firstFrameGeneratedが利用可能な場合は最初のフレームをプレースホルダーとして使用します。
- DOM 要素の準備ができる前に Travel を作成すること。
4.2 実行中の処理
statusChangedに基づいて UI を更新します。prepareは動画の待機中、runningは操作可能であることを示します。pause、resume、rewindの用途と前提条件に従ってください。これらはセッションの機能に依存します。また、rewindにはセッションがpausedであり、ストリームが停止していることも必要です。
4.3 終了と再作成
必須事項
await travel.end()でセッションを終了します。- 新しい Travel を作成する前に、前の Travel が終了していることを確認します。
- ページのアンロード時やルートの変更時に、クリーンアップ処理で
travel.end()を呼び出します。
- 失敗後は「終了 → リスナーの削除 → 第 1.2 節の段階 ③ または ⑤ から再試行」の順で処理します。
- 認証情報が使い捨ての場合、再試行時に新しい Travel 認証情報を取得します。
- 最初の Travel を終了せずに
createTravelを再度呼び出すこと。この場合、同期的に例外が発生します。 - クリーンアップせずにページを離れること。RTC リソースのリークにつながります。
5. 動画要素とブラウザのポリシー
必須事項
playsInlineを<video>に設定します(iOS では必須)。- ブラウザの自動再生ポリシーが
autoPlayとmutedに与える影響を把握してください。
prepare中は最初のフレーム画像をオーバーレイ表示し、セッションがrunningに移行したら非表示にします。- 必要に応じて
streamReadyTimeout(デフォルト:15,000 ms)を設定し、タイムアウト後に再試行できるようにします。 - プレーヤーのコンテナーに固定のアスペクト比を確保します。
- 動画要素が DOM に追加される前に、その参照を渡すこと。
- セッションが
pausedであるかストリームが切断されているのに、UI を操作可能な状態のままにすること。
6. イベント購読とエラー処理
6.1 イベント購読
必須事項
- イベントは
Travelに属し、HappyOysterEngineには属しません。 travel.on(...)とtravel.onError(...)が返す購読解除関数を保存します。
- リスナーの登録とクリーンアップを一か所で管理します。Travel セッションを切り替える前に古いリスナーを削除してください。
イベント | 用途 |
|---|---|
| 状態の表示、動画の準備完了( |
| RTC 接続前に |
| 空でない最初のフレームが存在する場合、 |
| ログ記録、トースト通知、トークン更新の開始 |
6.2 エラーの分類
- 起動時の失敗:
travel.start()が reject されます(enter-travel / RTC / タイムアウト)。 - 実行時のエラー:
travel.onErrorで通知されます(RTC エラー、ハートビート認証の失敗など)。 - 第 1.2 節の段階 ①~④ で発生するアプリケーションのバックエンドと Open Platform のエラーはアプリケーション層で処理し、SDK には渡されません。
start()のエラーのみを捕捉し、onErrorを購読しないこと。- 購読解除せずにリスナーを繰り返し登録すること。
7. 指示の送信:Command と Instruct
7.1 sendCommand(リアルタイム制御)
sendCommand() は Adventure モード(1)のリアルタイム制御に使用します。RTC DataChannel を介してコマンドを送信し、セッションが running の間のみ使用できます。
SDK が送信するコマンドは約 42 ms(約 24 FPS)ごとに最大 1 件です。前回の送信から 1 周期が経過していれば、新しいコマンドを即座に送信します。同じ周期内に sendCommand() が複数回呼び出された場合、最後の呼び出しの完全なコマンドのみを送信します。translation、rotation、interaction は独立した制御軸です。省略したフィールドは None として送信されます。SDK は呼び出し間でフィールドをマージせず、前のコマンドを定期的に繰り返したり、None を自動送信したりもしません。
単発の操作
ジャンプや攻撃などの単発の操作では、sendCommand() を 1 回呼び出します。
sendCommand() を呼び出し続けます。フロントエンドのアプリケーションで呼び出しを 42 ms 間隔に制限する必要はありません。SDK が高頻度の呼び出しをまとめ、約 24 FPS のレートで出力します。操作を離したら、None を明示的に送信して制御をリセットしてください。
prepare中に大量のコマンドを送信すること。- 自然言語の Directing 指示に
sendCommandを使用すること。
7.2 sendInstruct(演出指示)
必須事項
- Directing セッション(
2)、または Acting セッション(3)のうちscriptlistではないものに使用します。await travel.sendInstruct({ content })を呼び出してください。
- 送信前に
contentが空でないことを確認し、重複送信を防ぎます。 acceptedなどの戻り値に基づいてユーザーに結果を伝えます。
8. トラブルシューティング
現象 | 主な原因 | 対処方法 |
|---|---|---|
SDK の初期化が引数エラーで失敗する |
|
|
チケットが無効または使用済みのため |
| バックエンドから新しい |
セッションの開始後に | Model Studio の一時 API キー | バックエンドから新しいトークンを取得し、 |
プレーヤーが読み込み中のままになる、または | リモートストリームの準備ができていない、ネットワークが遅い、または | 再試行できるようにし、必要に応じて |
アクティブな Travel が存在するため、2 回目の | 前の Travel が終了していない | 終了、再試行、セッションの切り替え時に |
制御や指示に反応しない | セッションが |
|
ErrorCode、現在の TravelStatus、バックエンドのリクエストログをまとめて記録してください。通常、認証情報、状態、ネットワーク、レンダリングのどこに問題があるかを判断できます。