Dokumen ini ditujukan bagi pengembang frontend dan full-stack serta menjelaskan cara mengintegrasikan HappyOyster Web SDK secara andal di lingkungan produksi untuk mode Adventure, Directing, dan Acting.
Dokumen ini ditujukan bagi pengembang frontend dan full-stack. Dokumen ini menjelaskan cara mengintegrasikan SDK secara andal di lingkungan produksi. Untuk masing-masing API, lihat Referensi API.
0. Contoh Integrasi Minimal
Jika backend Anda sudah mengembalikan token API key sementara Model Studio dan ticket Travel, alur SDK frontend adalah sebagai berikut:
import { HappyOysterEngine, isSdkError } from "@happy-oyster/js-sdk";
const engine = new HappyOysterEngine({
APIHost: "open-platform.example.com",
model: "happyoyster-1.0-adventure", // Required; Adventure model shown as an example
logLevel: "warn",
});
engine.updateToken(token);
const videoElement = document.querySelector("video") as HTMLVideoElement;
const travel = engine.createTravel({
ticket,
videoElement,
maxExperienceTimeSec: 90, // Optional, Adventure only: 60 / 90 / 120
});
const offStatus = travel.on("statusChanged", (status) => {
// Use status to drive loading states, disabled buttons, and player UI.
});
const offError = travel.onError((error) => {
// Usually log, show a toast, and refresh the token if it has expired.
if (isSdkError(error)) console.error(error.code, error.message);
});
try {
await travel.start();
// Enable controls or Directing input with travel.can(action) after the session is running.
} finally {
offStatus();
offError();
await travel.end();
}
Cuplikan ini hanya mencakup sisi SDK. Pembuatan dunia, menunggu hingga siap, meminta ticket, dan meminta token API key sementara Model Studio harus dilakukan di atau melalui backend aplikasi Anda.
1. Gambaran Umum Alur Menyeluruh
Pengalaman lengkap terutama melibatkan komponen berikut.
1.1 Komponen
Komponen | Tanggung jawab |
|---|---|
Frontend aplikasi | UI, |
Backend aplikasi | Menyimpan API Key utama, memanggil API dunia Open Platform atas nama klien, dan menerbitkan kredensial sementara Model Studio |
HappyOyster OpenAPI | Menyediakan API yang diperlukan oleh model dunia HappyOyster. |
HappyOyster SDK | SDK yang digunakan oleh frontend aplikasi. SDK ini terutama mengelola sesi Travel dan akses stream video pada klien. |

1.2 Alur Pengalaman
Tahap | Pelaksana | Tindakan | Deskripsi |
|---|---|---|---|
① Buat dunia | Backend aplikasi → HappyOyster OpenAPI |
| Mengembalikan |
② Tunggu hingga siap | Backend aplikasi → HappyOyster OpenAPI |
| Lakukan polling hingga |
③ Dapatkan kredensial Travel | Backend aplikasi → HappyOyster OpenAPI |
| Mengembalikan |
④ Minta token API key sementara | Backend aplikasi → HappyOyster OpenAPI |
| Mengembalikan |
⑤ Kirim token API key sementara dan kredensial Travel | Frontend aplikasi → backend aplikasi → frontend aplikasi | Minta API key sementara dan kredensial Travel | Setelah frontend menerima |
⑥ Masuk ke pengalaman | Frontend aplikasi → HappyOyster SDK | Lihat “Subalur startup SDK” di bawah |
|
1.3 Subalur Interaksi SDK (Rincian Tahap ⑥)
1.3.1 Memulai Travel

Langkah | API | Deskripsi |
|---|---|---|
1 |
| Gunakan kembali Engine untuk |
2 |
| Selesaikan sebelum |
3 |
|
|
4 |
| Daftarkan listener sebelum |
5 |
| Memasuki |
1.3.2 Bermain dalam Mode Adventure

1.3.3 Bermain dalam Mode Directing / Acting

Tabel ini merangkum perbedaan Adventure, Directing, dan Acting:
Mode | API utama | Penggunaan umum | Hal yang perlu diperhatikan |
|---|---|---|---|
Adventure ( |
| Kontrol real-time dengan keyboard, joystick, dan tombol | Kirim hanya setelah |
Directing ( |
| Pengarahan dengan bahasa alami dan kontrol pemutaran | Jeda, lanjutkan, dan putar balik bergantung pada kemampuan sesi; periksa |
Acting ( |
| Pengalaman berorientasi akting dan konfigurasi rasio aspek | Jeda dan lanjutkan bergantung pada kemampuan sesi; |
1.4 Praktik Backend Aplikasi (Ringkasan)
Di sisi backend, patuhi aturan berikut:
- Simpan API Key utama hanya di backend aplikasi. Browser hanya boleh menerima
tokenberumur pendek (demo:POST /server-api/temp-api-key). - Minta kredensial Travel melalui backend. Otorisasi dunia dan pengguna sebelum menerbitkan
ticket; jangan hard-code atau menyimpannya dalam cache jangka panjang di frontend. - Jangan terbitkan kredensial sebelum dunia berstatus
ready. Jika tidak, enter-travel dapat gagal atau pengalaman menjadi tidak lengkap. - Arahkan backend aplikasi dan SDK ke lingkungan Open Platform yang sama. Backend dapat menggunakan URL OpenAPI lengkap;
APIHostSDK harus hanya berupa nama host, sepertiopen-platform.example.com.
2. Konsep Inti SDK
Dalam alur pada §1, SDK hanya bertanggung jawab atas “masuk Travel → putar → kontrol → akhiri”. Ada dua objek inti:
Objek | Tujuan |
|---|---|
| Mengonfigurasi |
| Mewakili satu sesi: |
Status sesi (statusChanged):
idle ──start()──► prepare ──video playable──► running ⇄ paused ──end()──► idle
Tiga batasan (dijelaskan kemudian):
- Setiap Engine hanya boleh memiliki satu Travel aktif pada satu waktu.
videoElementharus diberikan kecreateTravel.- Token API key sementara Model Studio dan tiket Travel memiliki tujuan berbeda (lihat tahap ④–⑤ pada §1.2 dan §3.2).
3. Inisialisasi dan Pengelolaan Token
3.1 Instansiasi Engine
Wajib- Konfigurasikan
APIHostsebagai nama host Open Platform saja, tanpahttps://, skema, atau path, sepertiopen-platform.example.com. - Gunakan kembali
HappyOysterEngineuntukAPIHost + modelyang sama. Sebelum mengganti host atau model, akhiri Travel aktif dan gunakan Engine yang dikonfigurasi untuk target baru.
- Gunakan
logLevel: 'debug'dalam pengembangan dan'warn'atau'none'dalam produksi. - Buat Engine pada lapisan orkestrasi sesi, bukan membuat yang baru setiap kali memulai.
Tabel berikut merangkum kolom konfigurasi umum:
Kolom | Wajib | Panduan |
|---|---|---|
| Ya | Berikan nama host saja, seperti |
| Ya | Wajib, tanpa nilai default; samakan dengan model backend yang digunakan untuk membuat dunia dan menerbitkan tiketnya. Nilai ini tetap untuk Engine dan tidak disimpulkan dari |
| Tidak | Anda dapat memberikannya melalui konstruktor atau mengaturnya nanti dengan |
| Tidak | Gunakan |
| Tidak | Naikkan nilainya jika jaringan atau persiapan rendering lambat; sediakan cara mencoba ulang setelah timeout |
- Memanggil
new HappyOysterEngine()berulang kali saat rendering atau pada jalur yang sering dieksekusi. - Memberikan URL lengkap, misalnya yang menyertakan
https://, atau memanggil API backend SDK tanpa mengisiAPIHost.
3.2 Model Dua Kredensial
Sesuai dengan tahap ③–⑤ pada §1.2:
Kredensial | Sumber | Cara mengatur | Tujuan |
|---|---|---|---|
Token API key sementara Model Studio | Kunci berumur pendek yang diterbitkan backend aplikasi |
| Mengautentikasi permintaan SDK ke Open Platform |
Tiket Travel | Kredensial Travel yang diminta oleh backend aplikasi |
| Kredensial sekali pakai untuk sesi Travel |
- Siapkan kedua kredensial sebelum
travel.start(). - SDK tidak menyimpan secara persisten atau memperbarui secara otomatis token.
- Jika token kedaluwarsa atau error heartbeat diterima melalui
onError, minta token baru melalui backend aplikasi lalu panggilupdateToken.
- Mencampuradukkan kedua kredensial.
- Mengekspos API Key utama ke frontend aplikasi.
4. Siklus Hidup Travel
4.1 Membuat dan Memulai
Wajib- Panggil
createTravel({ ticket, videoElement });ticketadalah kredensial Travel sekali pakai, danvideoElementdiberikan pada tahap ini. - Daftarkan
statusChangeddanonErrorsebelumawait travel.start()agar error dan perubahan status selalu terpantau.
- Tampilkan UI sedang menghubungkan selama
prepareuntuk mencegah klik berulang. GunakantravelInfoReadyuntuk membaca metadata sesi lebih awal, dan gunakanfirstFrameGeneratedsebagai placeholder frame pertama jika tersedia.
- Membuat Travel sebelum elemen DOM siap.
4.2 Saat Berjalan
- Perbarui UI berdasarkan
statusChanged:prepareberarti menunggu video, sedangkanrunningberarti interaksi tersedia. - Perhatikan penggunaan dan prasyarat
pause,resume, danrewind(bergantung pada kemampuan sesi;rewindjuga memerlukan sesi berstatuspauseddan stream sudah berhenti).
4.3 Mengakhiri dan Membuat Ulang
Wajib- Akhiri sesi dengan
await travel.end(). - Pastikan Travel sebelumnya sudah berakhir sebelum membuat yang baru.
- Panggil
travel.end()saat pembersihan ketika halaman ditutup atau rute berubah.
- Setelah kegagalan, lakukan “akhiri → hapus listener → coba ulang dari tahap ③ atau ⑤ pada §1.2”.
- Minta kredensial Travel baru saat mencoba ulang jika kredensial bersifat sekali pakai.
- Memanggil
createTravelkedua kali tanpa mengakhiri Travel pertama; tindakan ini melempar pengecualian secara sinkron. - Meninggalkan halaman tanpa pembersihan, yang menyebabkan kebocoran resource RTC.
5. Elemen Video dan Kebijakan Browser
Wajib- Atur
playsInlinepada<video>(wajib di iOS). - Pahami pengaruh kebijakan autoplay browser terhadap
autoPlaydanmuted.
- Selama
prepare, tampilkan gambar frame pertama sebagai overlay; sembunyikan setelah sesi memasukirunning. - Konfigurasikan
streamReadyTimeoutsesuai kebutuhan (default: 15.000 ms), dan sediakan tindakan coba ulang setelah timeout. - Tetapkan rasio aspek tetap untuk kontainer pemutar.
- Memberikan referensi elemen video sebelum elemen tersebut terpasang di DOM.
- Membiarkan UI tetap interaktif saat sesi berstatus
pausedatau stream terputus.
6. Langganan Event dan Penanganan Error
6.1 Langganan Event
Wajib- Event milik
Travel, bukanHappyOysterEngine. - Simpan fungsi berhenti berlangganan yang dikembalikan oleh
travel.on(...)dantravel.onError(...).
- Daftarkan dan bersihkan listener di satu tempat. Hapus listener lama sebelum beralih sesi Travel.
Event | Tujuan |
|---|---|
| Menampilkan status, mendeteksi kesiapan video ( |
| Membaca |
| Jika frame pertama yang tidak kosong tersedia, event ini mengikuti |
| Pencatatan log, notifikasi toast, dan pemicu pembaruan token |
6.2 Lapisan Error
- Kegagalan startup:
travel.start()ditolak (enter-travel / RTC / timeout). - Error runtime: dilaporkan melalui
travel.onError(error RTC, kegagalan autentikasi heartbeat, dan sebagainya). - Error backend aplikasi dan Open Platform pada tahap ①–④ di §1.2 ditangani oleh lapisan aplikasi dan tidak masuk ke SDK.
- Hanya menangkap error
start()tanpa mendengarkanonError. - Mendaftarkan listener berulang kali tanpa berhenti berlangganan.
7. Mengirim Instruksi: Command dan Instruct
7.1 sendCommand (Kontrol Real-Time)
sendCommand() menyediakan kontrol real-time dalam mode Adventure (1). Metode ini mengirim perintah melalui RTC DataChannel dan hanya tersedia saat sesi berstatus running.
SDK mengirim maksimal satu perintah kira-kira setiap 42 ms (sekitar 24 FPS). Jika satu siklus telah berlalu sejak pengiriman sebelumnya, perintah baru langsung dikirim. Jika sendCommand() dipanggil beberapa kali dalam siklus yang sama, hanya perintah lengkap dari panggilan terakhir yang dikirim. translation, rotation, dan interaction adalah dimensi kontrol independen. Kolom yang dihilangkan dikirim sebagai None; SDK tidak menggabungkan kolom antar-panggilan, mengulangi perintah sebelumnya secara berkala, atau mengirim None secara otomatis.
Panggil sendCommand() sekali untuk tindakan satu kali seperti melompat atau menyerang:
await travel.sendCommand({ interaction: "Jump" });
Tindakan berkelanjutan
Terus panggil sendCommand() selama kontrol gerakan atau rotasi pandangan berkelanjutan tetap ditekan. Aplikasi frontend tidak perlu membatasi panggilan menjadi setiap 42 ms; SDK menggabungkan panggilan berfrekuensi tinggi menjadi laju output sekitar 24 FPS. Saat dilepas, kirim None secara eksplisit untuk mereset kontrol:
// Keep calling while the control is pressed
void travel.sendCommand({ translation: "Front" });
// Stop moving on release
void travel.sendCommand({ translation: "None" });
Hindari
- Mengirim banyak perintah selama
prepare. - Menggunakan
sendCommanduntuk instruksi Directing dengan bahasa alami.
7.2 sendInstruct (Instruksi Directing)
Wajib- Gunakan sesi Directing (
2) atau sesi Acting (3) yang bukanscriptlist; panggilawait travel.sendInstruct({ content }).
- Pastikan
contenttidak kosong sebelum mengirim dan cegah pengiriman duplikat. - Berikan umpan balik kepada pengguna berdasarkan kolom yang dikembalikan seperti
accepted.
8. Pemecahan Masalah
Gejala | Penyebab umum | Tindakan |
|---|---|---|
Inisialisasi SDK gagal dengan error argumen |
| Berikan nama host saja, seperti |
|
| Minta |
|
| Minta token baru dari backend, lalu panggil |
Pemutar terus memuat atau | Stream jarak jauh belum siap, jaringan lambat, atau | Sediakan tindakan coba ulang; naikkan |
Panggilan | Travel sebelumnya belum diakhiri | Panggil |
Kontrol atau instruksi tidak bereaksi | Sesi tidak berstatus | Atur ketersediaan tombol berdasarkan |
Saat debugging, catat tiga hal bersama-sama: ErrorCode SDK, TravelStatus saat ini, dan log permintaan backend. Biasanya informasi ini menunjukkan apakah masalah terkait kredensial, status, jaringan, atau rendering.