Skip to main content
SDK Android

Referensi API HappyOyster Android SDK

Titik masuk untuk HappyOyster Android SDK adalah objek singleton HappyOyster. Kecuali initialize, updateToken, attachVideo, dan sendCommand, semua metode bisnis adalah fungsi suspend yang melempar SDKError saat gagal. Mencakup tiga mode petualangan / pengarahan / akting, konfigurasi model yang diperlukan, dan aspectRatio.

Jika koroutine pemanggil dibatalkan, SDK membatalkan permintaan HTTP yang sedang berjalan dari panggilan tersebut, jika ada, dan meneruskan CancellationException tanpa perubahan alih-alih mengonversinya menjadi SDKError. Pembatalan tidak membatalkan permintaan yang telah diterima oleh server. Untuk alur integrasi, instalasi, dan praktik terbaik, lihat Panduan Integrasi Android SDK Happy Oyster.

Terminologi Inti

Istilah

Arti

token

API Key gateway Bailian: disuntikkan sebagai token Bearer oleh aplikasi Anda melalui updateToken(token). SDK hanya menyimpan yang terbaru; SDK tidak menyimpannya secara permanen atau menyegarkannya. Ketika Key berubah, Anda menyuntikkannya lagi. Gateway mewajibkan semua permintaan SDK, termasuk startTravel, untuk menggunakan Bearer ini. Ketika Bearer Key kedaluwarsa atau tidak valid, SDK melempar SDKError(101002); dalam kasus tersebut Anda harus memperoleh kembali dan menyuntikkan Bearer Key (updateToken), alih-alih menukarnya dengan tiket baru. Rekomendasi keamanan: Bearer sisi klien harus menggunakan token berumur pendek yang dicetak oleh server Anda, alih-alih menggabungkan API Key berumur panjang ke dalam aplikasi atau menyimpannya di repositori kode.

ticket

Kredensial pengalaman sekali pakai: ditukar oleh server Anda melalui platform terbuka dan dikirimkan ke klien, hanya digunakan untuk satu startTravel. Kredensial menjadi tidak valid setelah pengalaman berakhir (normal atau tidak normal) dan tidak dapat digunakan kembali. Kesalahan kredensial tingkat tiket diidentifikasi oleh kode server enam digit (misalnya, 401010 = tiket tidak valid/kedaluwarsa, 401011 = tiket sudah digunakan), yang diteruskan oleh SDK apa adanya.

Persyaratan Lingkungan

Item

Persyaratan

minSdk

24 (Android 7.0) dan di atasnya

compileSdk

36

Bahasa

Kotlin (API suspend korutin)

ABI

arm64-v8a / armeabi-v7a (mesin komunikasi waktu nyata mencakup pustaka native)

Jaringan

Akses internet publik diperlukan

Konsep Inti

Konsep

Deskripsi

Dunia

Dunia AI, yang berisi karakter dan adegan. Dibuat dan dikelola oleh server Anda.

Travel

Satu pengalaman real-time tunggal. Siklus hidup dasar: init → pending → running → completed (kegagalan adalah failed). Dalam mode pengarahan dan Akting, jika pengalaman mendukung jeda, running dapat masuk ke paused melalui pauseTravel, lalu kembali ke running melalui resumeTravel (pengarahan juga dapat menggunakan rewindTravel, setelah itu server melanjutkan pengalaman secara otomatis); running ⇄ paused dapat berulang beberapa kali.

Mode

adventure (interaksi perangkat/perintah), directing (narasi berbasis teks), atau acting (Acting: narasi berbasis teks yang rasio aspek pemutarannya ditetapkan oleh server saat pembuatan dunia). SDK mengekspos ketiga nilai ini secara seragam.

Video waktu nyata

Dibuat dan dipelihara secara otomatis oleh SDK setelah startTravel berhasil; Anda tidak perlu menghubungkan/memutuskan koneksi secara manual. Koneksi dilepaskan secara otomatis saat endTravel.

Ikhtisar

Metode HappyOyster

Metode

Deskripsi

initialize(context, config)

Menginisialisasi SDK. Inisialisasi ulang saat idle didukung; inisialisasi ulang saat Travel sedang dimulai, aktif, atau berakhir akan ditolak dengan 103004.

updateToken(token)

Menyuntikkan/memperbarui API Key gateway Bailian (token Bearer).

startTravel(ticket)

Memulai pengalaman dengan kredensial sekali pakai dan secara otomatis membangun koneksi video waktu nyata.

pauseTravel()

Menjeda pengalaman secara asinkron (pengarahan dan Akting, dan hanya jika pengalaman mendukung penjedaan); setelah diterima, jeda aktual ditentukan oleh onStatusChanged(Paused).

resumeTravel()

Melanjutkan pengalaman yang dijeda (pengarahan dan Akting); mencakup backoff coba lagi 3× secara internal.

rewindTravel(rewindToSec)

Memutar ulang ke jumlah detik yang ditentukan (hanya pengarahan, status paused). Nilai detik harus merupakan kelipatan dari 4. Akting tidak mendukung pemutaran ulang.

sendInstruct(content)

Mengirimkan instruksi teks untuk menggerakkan narasi (pengarahan dan Akting, running atau paused).

sendCommand(command)

Mengirimkan perintah kontrol arah/tampilan/tindakan (mode petualangan, hanya running; thread utama). Tidak tersedia untuk Akting.

attachVideo()

Mengembalikan SurfaceView untuk pemutaran; tambahkan ke tata letak Anda untuk merender (thread utama).

endTravel()

Mengakhiri pengalaman, secara otomatis memutuskan koneksi waktu nyata dan melepaskan semua sumber daya sesi.

VERSION

String versi SDK (SemVer), sebuah konstanta waktu kompilasi.

Event

Peristiwa

Deskripsi

onStatusChanged(status)

Perubahan status pengalaman (termasuk siklus hidup video waktu nyata); nilai didefinisikan dalam TravelStatusValue.

onError(error)

Panggilan balik ketika alur otomatis internal gagal; kesalahan fatal juga mengakhiri pengalaman saat ini.

Tipe data utama

Tipe

Deskripsi

SDKConfig

Konfigurasi inisialisasi SDK (apiHost dan model wajib diisi, ditambah logLevel, logcatEnabled, logHandler, dan callbackTimeoutMs).

TravelStatusValue

Status pengalaman: Init / Pending / Running / Paused / Failed / Completed.

ModeValue

Mode pengalaman: adventure / directing / acting.

CreationModelValue

Model pembuatan dunia: Simple (default, didorong instruksi) / ScriptList (skrip terstruktur, sendInstruct tidak didukung).

StartTravelData

Dikembalikan oleh startTravel; berisi metadata seperti mode, version, creationModel, aspectRatio, dan maxExperienceTimeSec.

AdventureCommand

Parameter untuk sendCommand; berisi tiga bidang translation / rotation / interaction.

SDKError

Kesalahan SDK; berisi code: Int dan opsional raw: Any?.

HappyOyster.initialize

Menginisialisasi SDK; panggil sebelum API lainnya (sebaiknya dalam Application.onCreate). config wajib diisi dan harus membawa apiHost Bailian akun Anda serta model berupa happyoyster-1.0-directing / happyoyster-1.0-acting / happyoyster-1.0-adventure (sesuai dengan entri Open API). SDK menyusun URL permintaan sebagai berikut:
https://{apiHost}/api/v2/apps/{model}/openapi/v1/{endpoint}
model tidak memiliki nilai default: mengabaikannya saat membuat SDKConfig merupakan kesalahan waktu kompilasi. Meneruskan nilai kosong menyebabkan initialize melempar SDKError(100002) secara sinkron; tidak ada runtime yang dibuat atau diganti dan tidak ada permintaan jaringan yang dilakukan. SDK hanya menyimpan konteks aplikasi, bukan Activity. Inisialisasi ulang hanya didukung saat runtime sebelumnya sedang idle. Untuk mengganti model, lakukan inisialisasi ulang dengan model baru saat idle; jika Travel sedang dimulai, aktif, atau berakhir, tunggu endTravel() terlebih dahulu.
Pemberitahuan kepatuhan regional:
  • Untuk mendukung kepatuhan terhadap persyaratan hukum dan data yang berlaku, jika pengguna target Anda mencakup pengguna AS, Anda harus mengonfigurasi API Host wilayah AS selama inisialisasi SDK untuk layanan yang disediakan kepada pengguna tersebut.
  • Pengembang bertanggung jawab atas konfigurasi yang benar dan menanggung tanggung jawab yang sesuai berdasarkan hukum yang berlaku jika gagal mengikuti persyaratan ini.

Tanda Tangan

fun initialize(context: Context, config: SDKConfig)

Parameter

Bidang

Tipe

Wajib

Deskripsi

context

Context

Ya

Disarankan untuk meneruskan applicationContext.

config

SDKConfig

Ya

Konfigurasi SDK; harus menyertakan apiHost dan model yang wajib diisi dan tanpa nilai default.

Mengembalikan

Tidak ada nilai kembalian.

Kesalahan

code

Deskripsi

100002

model kosong. Inisialisasi gagal secara sinkron dengan SDKError.raw diatur ke SDKConfig.model must not be blank; tidak ada runtime yang dibuat atau diganti dan tidak ada permintaan jaringan yang dilakukan.

103004

Inisialisasi ulang ditolak karena Travel sedang dimulai, aktif, atau berakhir. Tunggu endTravel() dan coba lagi.

HappyOyster.updateToken

Menyuntikkan/memperbarui Kunci API gateway Bailian. Aman untuk thread dan dapat dipanggil setelah initialize; SDK menggunakan token terbaru untuk startTravel dan permintaan kontrol pengalaman berikutnya. ticket adalah kredensial pengalaman sekali pakai dan tidak boleh dicampuradukkan dengan token Bearer.

Tanda Tangan

fun updateToken(token: String)

Parameter

Bidang

Tipe

Wajib

Deskripsi

token

String

Ya

API Key gateway Bailian, digunakan sebagai token Bearer.

Mengembalikan

Tidak ada nilai kembalian.

Kesalahan

code

Deskripsi

100001

SDK belum diinisialisasi.

HappyOyster.startTravel

Memulai pengalaman dengan ticket sekali pakai. Jika berhasil, SDK secara otomatis membuat koneksi video real-time dan memulai polling status internal, dengan status ditampilkan melalui onStatusChanged.
  • ticket adalah kredensial sekali pakai dan dianggap terpakai setelah panggilan dilakukan.
  • Hanya satu Travel konkuren yang diizinkan per aplikasi pada waktu tertentu; memanggil lagi saat pengalaman sedang berlangsung akan melempar SDKError(103004), dengan SDKError.raw hanya berisi ringkasan yang disamarkan dari tiket yang sedang aktif untuk diagnosis, tidak pernah tiket lengkap.
  • Secara opsional teruskan maxExperienceTimeSec untuk membatasi durasi maksimum pengalaman ini (hanya mode penjelajahan dunia / petualangan); lihat Parameter.
StartTravelData.creationModel (CreationModelValue, default CreationModelValue.Simple): menunjukkan model pembuatan dunia, yaitu bagaimana konten skrip dikelola. simple (default) adalah dunia berbasis instruksi biasa; dunia penjelajahan dunia juga dinormalisasi ke nilai ini. scriptlist adalah dunia ScriptList terstruktur—konten skripnya tidak diakses melalui SDK ini. Dalam mode ScriptList (creationModel == CreationModelValue.ScriptList), pemanggilan sendInstruct akan ditolak dan melempar SDKError(103002). Bidang ini secara default bernilai simple. StartTravelData.aspectRatio (String?): rasio aspek pemutaran yang ditetapkan server untuk sesi ini, sebagai string width:height. Non-null hanya untuk Akting—"9:16" (potret, default sisi server saat pembuatan) atau "16:9" (lanskap); null untuk mode penjelajahan dunia dan pengarahan, dan null ketika server tidak melaporkan nilainya. SDK mempertahankan nilai yang tidak dikenal apa adanya (tidak menciutkannya menjadi null), sehingga host harus memperlakukan nilai yang tidak dikenali seperti null dan kembali ke orientasi default mereka sendiri; SDK itu sendiri tidak menggunakan bidang ini. Nilai ini dikirimkan bersama nilai kembalian startTravel(): sesuaikan ukuran kontainer pemutaran darinya setelah startTravel() kembali dan sebelum memanggil attachVideo() serta menambahkan tampilan yang dikembalikan ke tata letak Anda—SDK hanya mulai mengikat aliran jarak jauh untuk rendering setelah host memasang tampilannya, sehingga memutuskan orientasi pada titik tersebut masih mendahului frame yang dirender pertama kali (namun, tidak dijamin terjadi sebelum SDK bergabung dengan ruang real-time). Tampilan jarak jauh diikat dengan mode render clip-to-fill, sehingga kontainer yang orientasinya tidak sesuai dengan nilai ini akan memotong gambar alih-alih memberikan efek letterbox.

Tanda Tangan

suspend fun startTravel(ticket: String): StartTravelData
suspend fun startTravel(ticket: String, maxExperienceTimeSec: Int?): StartTravelData

Parameter

Bidang

Tipe

Wajib

Deskripsi

ticket

String

Ya

Kredensial pengalaman sekali pakai, yang dikirimkan oleh server Anda.

maxExperienceTimeSec

Int?

Tidak

Durasi maksimum pengalaman ini dalam detik; dunia mengakhiri sesi secara otomatis setelah durasi tercapai. Hanya berlaku untuk mode penjelajahan dunia (petualangan); diabaikan dalam mode pengarahan (pengarahan real-time) dan Akting. Nilai yang diizinkan dikonfigurasi oleh server, saat ini 60 / 90 / 120; meneruskan null (atau menggunakan overload tanpa parameter ini) menerapkan default server (saat ini 60). Meneruskan nilai yang tidak didukung menyebabkan server menolak startTravel dengan 400000, melempar SDKError(400000) tanpa Travel aktif yang dibuat. SDK tidak memvalidasi nilai secara lokal — kumpulan yang diizinkan bersifat otoritatif di server.

Mengembalikan

Mengembalikan StartTravelData, yang berisi metadata pengalaman (mode, version, creationModel, aspectRatio, dll.). Periksa metadata yang dikembalikan sebelum memutuskan cara berinteraksi (misalnya, travel.mode, travel.creationModel, travel.version); untuk Acting, sesuaikan juga ukuran kontainer pemutaran dari travel.aspectRatio.

Kesalahan

code

Deskripsi

401010

ticket tidak valid atau kedaluwarsa

401011

ticket sudah digunakan

400000

Parameter tidak valid (misalnya maxExperienceTimeSec tidak termasuk dalam himpunan yang diizinkan server); startTravel ini gagal dimulai

403002

Dunia tidak dalam status siap

500001

Alokasi sumber daya / kegagalan layanan internal

103004

Travel sudah sedang dimulai, aktif, atau berakhir, atau startTravel dipanggil secara konkuren (hanya satu Travel yang diizinkan pada satu waktu; SDKError.raw hanya berisi ringkasan yang disamarkan dari tiket yang aktif)

HappyOyster.pauseTravel / HappyOyster.resumeTravel

Jeda / lanjutkan pengalaman. SDK hanya mengelola satu Travel pada satu waktu; encryptedTravelId diperoleh secara internal oleh SDK dan tidak perlu diteruskan oleh pemanggil. Prasyarat:
  • pauseTravel: hanya dapat dipanggil dalam pengarahan atau Akting dan ketika statusnya running.
  • resumeTravel: hanya dapat dipanggil dalam pengarahan atau Akting dan ketika statusnya paused.
Tidak semua pengalaman mendukung jeda / lanjut: pengalaman harus melaporkan pengidentifikasi versi yang diperlukan modenya (StartTravelData.version—storyV2 untuk directing, actingV2 untuk Acting; dibandingkan dengan mengabaikan spasi di sekitarnya dan huruf besar/kecil), jika tidak, baik pauseTravel maupun resumeTravel mengembalikan 103002. Acting mendukung jeda / lanjut tetapi tidak mendukung rewindTravel. Jeda bersifat asinkron (penting): pauseTravel adalah operasi "berat"—panggilan yang berhasil (pengembalian metode) hanya berarti jeda telah diterima; pada saat itu pengalaman belum benar-benar dijeda. Jeda baru menjadi nyata setelah callback onStatusChanged melaporkan paused. Oleh karena itu, gerakkan mesin status host dan pengontrolan panggilan dari callback tersebut: antara "memanggil pauseTravel" dan "menerima callback paused" Anda dapat menandai status lokal sebagai pausing; hanya setelah menerima paused Anda boleh memulai resumeTravel atau rewindTravel. Jangan menganggap pengembalian pauseTravel sebagai sudah dijeda. Penanganan koneksi real-time: setelah jeda aktual, SDK memutus koneksi real-time; saat dilanjutkan, SDK secara otomatis bergabung kembali dan memulihkan gambar menggunakan kredensial yang diberikan selama startTravel yang sama, tanpa intervensi host. Penghalang pembongkaran jeda terurut: setelah Paused dipancarkan, pembongkaran ruang real-time di sisi server mungkin masih tertunda sebentar. SDK menetapkan jendela penyelesaian 3 detik dari konfirmasi jeda. Jika resumeTravel atau rewindTravel dipanggil dalam jendela tersebut, panggilan penangguhan pertama-tama menunggu sisa waktu secara non-blokir, kemudian mengirimkan permintaan API pembukaan ulang ruang. Tidak ada penundaan yang ditambahkan jika 3 detik telah berlalu secara alami. Hal ini mencegah pembongkaran jeda yang terlambat menutup ruang yang baru dibuka dan memunculkan 105001. Percobaan ulang API resume: resumeTravel secara internal mencoba ulang hingga 3 kali saat gagal (backoff 1 d / 2 d / 3 d) untuk menangani ketidaktersediaan layanan singkat setelah jeda; hanya jika semua 3 upaya gagal, kesalahan akan diteruskan ke atas.
⚠️ Catatan: Disarankan agar host menunggu hingga 3 d setelah resumeTravel berhasil dikembalikan sebelum memulai pauseTravel lagi, untuk menghindari perpindahan yang terlalu sering. Ini adalah rekomendasi cooldown panggilan sisi host dan tidak diberlakukan oleh SDK itu sendiri. Lihat Panduan Integrasi Android SDK Happy Oyster untuk detailnya.

Tanda Tangan

suspend fun pauseTravel(): TravelStateData
suspend fun resumeTravel(): TravelStateData

Parameter

Tidak ada parameter.

Mengembalikan

Mengembalikan TravelStateData (berisi encryptedTravelId, status).

Kesalahan

code

Deskripsi

103001

Tidak ada pengalaman aktif

103002

Status tidak diizinkan, atau pengalaman ini tidak mendukung jeda / lanjut

103003

Dipanggil dalam mode petualangan; hanya pengarahan dan Akting yang mendukung jeda / lanjut

HappyOyster.rewindTravel

Memutar ulang ke jumlah detik yang ditentukan. encryptedTravelId diperoleh secara internal oleh SDK. Prasyarat: hanya dapat dipanggil dalam mode directing dan saat status paused (mundur tidak diizinkan dalam status running). Tidak semua pengalaman directing mendukung mundurn, dan yang tidak didukung akan mengembalikan 103002. Setelah mundur berhasil, pengalaman dilanjutkan secara otomatis dan SDK secara otomatis menyambungkan ulang RTC, tanpa intervensi host. Acting sama sekali tidak memiliki kemampuan mundur: memanggilnya dalam Acting ditolak secara lokal oleh SDK dengan 103003, dan tidak ada permintaan yang dikeluarkan. Dalam Acting, host sebaiknya menyembunyikan titik masuk mundur alih-alih sekadar menonaktifkan tombol.

Tanda Tangan

suspend fun rewindTravel(rewindToSec: Double): RewindTravelData

Parameter

Bidang

Tipe

Wajib

Deskripsi

rewindToSec

Double

Ya

Jumlah detik target untuk mundur, yang harus merupakan kelipatan dari 4 (misalnya, 4, 8, 12). Nilai yang bukan kelipatan dari 4 akan dibulatkan ke bawah oleh server menjadi kelipatan 4 terdekat yang lebih kecil (misalnya, memberikan 7 menghasilkan 4).

Mengembalikan

Mengembalikan RewindTravelData (berisi encryptedTravelId, status, resumedAtSec), di mana resumedAtSec adalah jumlah detik tujuan pemutaran ulang yang sebenarnya oleh server (sudah dibulatkan ke bawah menjadi kelipatan 4).

Kesalahan

code

Deskripsi

103001

Tidak ada pengalaman aktif

103002

Status bukan paused, atau pengalaman ini tidak mendukung pemutaran ulang

103003

Dipanggil dalam mode petualangan atau Akting; hanya mode pengarahan yang mendukung pemutaran ulang

HappyOyster.sendInstruct

Mengirim instruksi teks untuk menggerakkan narasi. Valid dalam directing atau Acting dan saat status pengalaman adalah running atau paused. encryptedTravelId diperoleh secara internal oleh SDK. Perilaku dalam status terjeda: SDK tidak melanjutkan secara otomatis saat terjeda; instruksi dikirim langsung. Terserah host untuk memutuskan apakah akan memanggil resumeTravel terlebih dahulu sebelum mengirim instruksi.

Tanda Tangan

suspend fun sendInstruct(content: String): SendInstructData

Parameter

Bidang

Tipe

Wajib

Deskripsi

content

String

Ya

Konten instruksi teks yang akan dikirim.

Mengembalikan

Mengembalikan SendInstructData (berisi encryptedTravelId, content, accepted).

Kesalahan

code

Deskripsi

103001

Tidak ada pengalaman aktif (tidak pernah memanggil startTravel, atau telah berakhir)

103003

Mode saat ini bukan pengarahan maupun Akting (dipanggil dalam mode petualangan)

103002

Status pengalaman bukan running maupun paused (misalnya, masih dalam fase init/pending); atau dunia saat ini berada dalam mode ScriptList (StartTravelData.creationModel == CreationModelValue.ScriptList)—pengiriman instruksi tidak diizinkan dalam mode ScriptList, di mana skrip dikelola oleh API platform Bailian

403004

Blokir moderasi konten

404000

Travel tidak ada

HappyOyster.sendCommand

Mengirimkan perintah kontrol arah/tampilan/tindakan. Hanya valid dalam mode petualangan dan ketika running.
  • Panggil pada thread utama; panggilan di luar thread utama secara sinkron melempar IllegalStateException.
  • Tidak ada pengalaman aktif melaporkan 103001.
  • Memanggil di luar mode petualangan (pengarahan / Akting) akan melaporkan 103003.
  • Status yang tidak diizinkan melaporkan 103002.
  • Uplink dibangun melalui aliran audio senyap (SDK tidak merekam atau mengunggah audio nyata); RECORD_AUDIO bukan prasyarat mutlak untuk DataChannel, namun mendeklarasikan dan memberikannya sangat disarankan untuk kompatibilitas lintas perangkat (lihat Panduan Integrasi Happy Oyster Android SDK § Instalasi · Izin). 105004 berarti saluran real-time belum siap / pengiriman gagal (misalnya gangguan koneksi DataChannel atau anomali saluran real-time); hal ini tidak dipicu secara langsung oleh izin yang hilang.
Pembatasan 42 ms bawaan (24 fps, terbaru-menang): sendCommand secara internal membatasi penulisan DataChannel dalam interval 42 ms (sekitar 24 fps). Validasi status berjalan secara sinkron dan segera, melempar kesalahan seketika pada panggilan ilegal; penulisan DataChannel yang sebenarnya dibatasi secara asinkron. Jika setidaknya 42 ms telah berlalu sejak pengiriman sebelumnya, perintah dikirimkan segera (termasuk panggilan pertama). Jika tidak, perintah yang tertunda diganti dengan nilai terbaru dan dikirimkan sekali di akhir jendela 42 ms saat ini. Beberapa panggilan dalam satu jendela karenanya menghasilkan satu penulisan on-wire yang berisi nilai terakhir. Host dapat memanggil sendCommand pada kecepatan frame game tanpa menerapkan pembatas laju sendiri. Kegagalan pengiriman selama pembatasan: flush yang dibatasi bersifat asinkron, dan kegagalan pengiriman tidak dapat dilempar ke pemanggil—kesalahan ditampilkan melalui callback onError (non-fatal, 105004). Perintah yang tertunda dibuang saat sesi berakhir (perintah tersebut tidak akan dikirim setelah sesi berakhir). Bidang dan nilai AdventureCommand:

Bidang

Semantik

Nilai

translation

Pergerakan: maju/kiri/mundur/kanan/diagonal/diam

W / A / S / D / W_A / W_D / S_A / S_D / None

rotation

Tampilan: atas/bawah/kiri/kanan/diagonal/none

Mouse_Up / Mouse_Down / Mouse_Left / Mouse_Right / Mouse_Up_Left / Mouse_Up_Right / Mouse_Down_Left / Mouse_Down_Right / None

interaction

Interaksi: lompat/serang/jongkok/lari cepat/none

Jump / Attack / Squat / Sprint / None

Ketiga bidang tersebut adalah grup perintah yang saling eksklusif dan independen. Gerakan/tampilan diagonal menggunakan nilai gabungan tunggal (misalnya, maju+kiri adalah W_A, bukan W dan A konkuren dalam bidang yang sama). Setiap panggilan harus membawa status saat ini yang lengkap. Praktik terbaik: tindakan sekali tekan vs tindakan tertahan Gunakan interval 42 ms sebagai model mental:
  • Tindakan satu kali (misalnya, ketuk lompat/serang atau ambil satu langkah): panggil sekali. SDK mengirimkannya pada interval terdekat; tidak diperlukan panggilan berulang atau perintah None lanjutan.
    // Jump once
    HappyOyster.sendCommand(AdventureCommand("None", "None", "Jump"))
    
  • Tindakan tahan (misalnya, terus bergerak atau berputar): panggil setiap frame saat ditahan. SDK mengeluarkan sekitar satu perintah setiap 42 md. Saat dilepaskan, kirimkan secara eksplisit satu perintah yang berisi None untuk mengatur ulang status. SDK tidak pernah menghasilkan perintah pengaturan ulang secara otomatis.
    // While held: call from the host's frame loop
    HappyOyster.sendCommand(AdventureCommand("W", "None", "None"))
    // On release: explicitly reset once
    HappyOyster.sendCommand(AdventureCommand("None", "None", "None"))
    

Tanda Tangan

fun sendCommand(command: AdventureCommand)

Parameter

Bidang

Tipe

Wajib

Deskripsi

command

AdventureCommand

Ya

Objek perintah yang berisi tiga bidang translation, rotation, interaction.

Mengembalikan

Tidak ada nilai kembalian (sinkron). Validasi status berjalan secara sinkron dan segera; penulisan DataChannel dibatasi secara asinkron.

Kesalahan

code

Deskripsi

103001

Tidak ada pengalaman aktif

103002

Status tidak diizinkan

103003

Dipanggil di luar mode petualangan (pengarahan / Akting)

105004 (melalui onError)

Kegagalan pengiriman flush yang dibatasi (non-fatal, panggilan balik asinkron)

HappyOyster.attachVideo

Mengembalikan SurfaceView untuk pemutaran, yang Anda tambahkan ke tata letak Anda; SDK secara internal menyelesaikan pengikatan render dengan stream jarak jauh.
  • Panggil pada thread utama; panggilan di luar thread utama secara sinkron melempar IllegalStateException.
  • SDK hanya menyimpan referensi lemah ke Tampilan yang dikembalikan dan melepaskan pengikatan render ketika pengalaman berakhir; Anda harus menghapus Tampilan dari tata letak sendiri.
  • Untuk pengalaman Acting, sesuaikan ukuran kontainer pemutaran dari StartTravelData.aspectRatio sebelum menambahkan tampilan yang dikembalikan ke tata letak Anda: rendering terikat dengan mode clip-to-fill, sehingga orientasi yang tidak cocok akan memotong gambar (lihat startTravel).

Tanda Tangan

fun attachVideo(): SurfaceView

Parameter

Tidak ada parameter.

Mengembalikan

Mengembalikan SurfaceView; tambahkan ke tata letak Anda untuk memutar video waktu nyata.

Kesalahan

code

Deskripsi

100001

SDK belum diinisialisasi

HappyOyster.endTravel

Mengakhiri pengalaman. encryptedTravelId diperoleh secara internal oleh SDK. Setelah panggilan berhasil (atau keluar tidak normal), SDK secara otomatis memutus koneksi real-time, menghentikan polling internal, dan melepaskan semua sumber daya sesi, dan ticket saat ini divalidasi pada saat yang sama.

Tanda Tangan

suspend fun endTravel(): EndTravelData

Parameter

Tidak ada parameter.

Mengembalikan

Mengembalikan EndTravelData (berisi encryptedTravelId, status, endedAt, durationSec).

Kesalahan

code

Deskripsi

100001

SDK belum diinisialisasi

103001

Tidak ada pengalaman aktif

HappyOyster.VERSION

Mengembalikan string versi SDK (SemVer), seperti "x.y.z". Nilai ini adalah konstanta waktu kompilasi yang disuntikkan oleh properti Gradle VERSION_NAME; nilainya dapat dibaca dengan aman tanpa memanggil initialize terlebih dahulu.

Tanda Tangan

val VERSION: String

Mengembalikan

String versi SDK, seperti "x.y.z".
Log.d("MyApp", "SDK version: ${HappyOyster.VERSION}")

Pendengaran Peristiwa

interface HappyOysterListener {
    fun onStatusChanged(status: TravelStatusValue) {}
    fun onError(error: SDKError) {}
}

fun addListener(listener: HappyOysterListener)
fun removeListener(listener: HappyOysterListener)
Event SDK adalah saluran push proaktif kepada Anda, yang digunakan untuk melaporkan situasi yang tidak dipicu oleh panggilan eksplisit Anda sendiri (misalnya, masalah pada koneksi real-time atau polling status yang dipelihara secara otomatis oleh SDK).

Peristiwa

Deskripsi

onStatusChanged

Perubahan status pengalaman (termasuk siklus hidup video waktu nyata); nilai didefinisikan dalam TravelStatusValue.

onError

Panggilan balik ketika alur otomatis internal gagal; kesalahan fatal juga mengakhiri pengalaman saat ini (lihat bagian kode kesalahan).

⚠️ Catatan: addListener / removeListener harus dipanggil setelah initialize; memanggilnya sebelum inisialisasi akan melempar SDKError(100001). Disarankan untuk mendaftarkan listener segera setelah HappyOyster.initialize(...) berhasil dikembalikan.

Model Data

// Configuration
data class SDKConfig(
    // Required: your account's Bailian API Host (e.g., llm-xxxx.ap-southeast-1.maas.aliyuncs.com), copied from the API Key page in the Bailian console;
    // must belong to the same account/region as the injected API Key, otherwise the gateway returns AccessDenied.
    val apiHost: String,
    // Required with no default: the complete HappyOyster model name and version (e.g., happyoyster-1.0);
    // refer to the official Bailian HappyOyster model documentation for available values.
    val model: String,
    // Minimum level for the built-in Logcat sink (does not affect logHandler); defaults to INFO, which
    // includes the lifecycle anchors (initialize, Travel start/status/end, RTC connect/first-frame) needed
    // to reconstruct a session timeline. Drop to WARN for errors-only, or raise to DEBUG/VERBOSE to diagnose.
    val logLevel: LogLevel = LogLevel.INFO,
    // Timeout for RTC join (timeout triggers 105002), first-frame wait (timeout triggers 105003), and SDK gateway HTTP signaling calls (timeout triggers 105005);
    // the two RTC phases are serial, so the worst-case wait is 2×callbackTimeoutMs (60s).
    val callbackTimeoutMs: Long = SDKConfig.DEFAULT_CALLBACK_TIMEOUT_MS, // 30_000ms
    // Whether the SDK writes its own logs to Android Logcat (tag HappyOysterSDK); defaults to false (silent).
    val logcatEnabled: Boolean = false,
    // Host log callback; receives the full stream of SDK LogRecords, unaffected by logLevel; defaults to null.
    val logHandler: HappyOysterLogHandler? = null,
) {
    companion object {
        /** Default callback timeout (milliseconds). Public constant, usable for comparison or display. */
        const val DEFAULT_CALLBACK_TIMEOUT_MS: Long = 30_000
    }
}

enum class LogLevel { VERBOSE, DEBUG, INFO, WARN, ERROR, NONE }

// Host log sink; injected via SDKConfig.logHandler; full firehose, unaffected by logLevel.
fun interface HappyOysterLogHandler {
    fun onLog(record: LogRecord)
}

// SDK structured log record; delivered to HappyOysterLogHandler; contains no sensitive values (Bearer /
// ticket / RTC token, RTC identity fields, and media URLs are all redacted). travelId (encryptedTravelId)
// is kept in full so it can be correlated with server-side session logs.
data class LogRecord(
    val level: LogLevel,
    val tag: String,        // fixed as "HappyOysterSDK"
    val message: String,    // readable log line (includes event name and details)
    val throwable: Throwable?,
    val timestampMs: Long,  // epoch milliseconds at emission time
)

// Status and mode (unknown values are preserved to allow service extension)
@JvmInline value class TravelStatusValue(val rawValue: String) {
    companion object {
        val Init = TravelStatusValue("init")
        val Pending = TravelStatusValue("pending")
        val Running = TravelStatusValue("running")
        val Paused = TravelStatusValue("paused")
        val Failed = TravelStatusValue("failed")
        val Completed = TravelStatusValue("completed")
    }
}
@JvmInline value class ModeValue(val rawValue: String) {
    companion object {
        val Adventure = ModeValue("adventure")
        val Directing = ModeValue("directing")
        val Acting = ModeValue("acting")
    }
}
@JvmInline value class CreationModelValue(val rawValue: String) {
    companion object {
        val Simple = CreationModelValue("simple")         // default; prompt/instruct-driven, world-exploration worlds normalize to this
        val ScriptList = CreationModelValue("scriptlist") // structured ScriptList world; sendInstruct not supported (throws 103002)
    }
}

// startTravel return
data class StartTravelData(
    val encryptedTravelId: String, // identifier for subsequent control interfaces
    val encryptedWorldId: String,
    val mode: ModeValue,           // adventure / directing / acting
    val creationModel: CreationModelValue = CreationModelValue.Simple, // world creation model; Simple (default) is instruct-driven, ScriptList does not support sendInstruct
    val playUrl: String?,
    val firstFrame: String?,       // first-frame image address, may be produced asynchronously
    val bgmUrl: String?,
    val version: String,           // world version identifier; Acting is actingV2
    val aspectRatio: String? = null, // Acting only: 9:16 / 16:9; other modes null. Use to set player orientation
    val maxExperienceTimeSec: Int? = null, // server-reported max experience time (seconds); non-null only for adventure; null for directing / acting
)

// Control interface parameters and returns
data class AdventureCommand(
    val translation: String, // movement: forward/left/back/right/diagonal (W_A, …)/idle
    val rotation: String,    // view: up/down/left/right/diagonal (Mouse_Up_Left, …)/none
    val interaction: String, // interaction: jump/attack/squat/sprint/none
)
data class TravelStateData(val encryptedTravelId: String, val status: TravelStatusValue)
data class RewindTravelData(val encryptedTravelId: String, val status: TravelStatusValue, val resumedAtSec: Double)
data class EndTravelData(val encryptedTravelId: String, val status: TravelStatusValue, val endedAt: String, val durationSec: Int)
data class SendInstructData(val encryptedTravelId: String, val content: String, val accepted: Boolean)

// Error (identified by code; the original information is in raw)
// Note: SDKError is not a data class (no copy()/destructuring), it is a plain class.
class SDKError(val code: Int, val raw: Any? = null) : Exception("Happy Oyster SDK error: $code")

Kode Kesalahan

Kesalahan diidentifikasi oleh code numerik. SDK meneruskan kode kesalahan bisnis yang dapat ditangani oleh pemanggil (umumnya 4xxxxx / 5xxxxx); kode kesalahan SDK lokal adalah 1xxxxx.

Kode kesalahan bisnis (umum)

code

Arti

Penanganan yang disarankan

400000

Parameter tidak valid (enum tidak valid, dll.)

Periksa parameter permintaan atau versi SDK

401010

ticket tidak valid atau kedaluwarsa

Minta server Anda menerbitkan ulang kredensial

401011

ticket sudah digunakan

Kredensial bersifat sekali pakai; terbitkan ulang

403001

Dunia tidak ada, telah dihapus, atau bukan milik pengembang saat ini (termasuk dunia yang sudah dihapus dalam kredensial startTravel)

Pilih ulang Dunia yang valid

403002

Dunia tidak dalam status siap

Tunggu hingga dunia siap sebelum memulai

403004

Pelanggaran konten input (moderasi konten); berlaku untuk instruksi teks sendInstruct

Ubah konten masukan dan coba lagi

403007

Spesifikasi layanan tidak diaktifkan untuk akun ini

Jangan coba lagi karena kapasitas penuh; beralihlah ke spesifikasi yang diaktifkan atau minta pengaktifan

403008

Konfigurasi kapasitas sementara tidak tersedia

Coba lagi nanti

404000

Sumber daya Travel tidak ada atau ID bukan milik akun saat ini

Mulai ulang Travel

409000

Permintaan bertentangan dengan status sumber daya saat ini

Periksa status Travel

429001

Batas konkurensi SKU tercapai

Coba lagi setelah sesi yang ada berakhir (jangan kelirukan dengan 500001)

429002

Tidak ada kapasitas yang tersedia saat ini

Coba lagi nanti

500001

Alokasi sumber daya inferensi / kegagalan layanan internal

Coba lagi nanti

500000

Kesalahan sistem internal

Coba lagi nanti / laporkan

Kode kesalahan lokal sisi klien

code

Arti

Fatal?

Penanganan yang disarankan

100001

Dipanggil sebelum SDK diinisialisasi

Panggilan ditolak

initialize terlebih dahulu

100002

model kosong selama inisialisasi SDK; dilempar secara sinkron dengan SDKError.raw diatur ke SDKConfig.model must not be blank; tidak ada runtime yang dibuat atau diganti dan tidak ada permintaan jaringan yang dilakukan

Inisialisasi gagal

Teruskan nama dan versi model lengkap yang tidak kosong, lalu panggil initialize lagi; lihat dokumentasi model HappyOyster Bailian resmi untuk nilai yang tersedia

101001

Kunci API gateway Bailian tidak disuntikkan

Tidak

Coba lagi setelah updateToken

101002

Kunci API Bearer gateway Bailian kedaluwarsa atau ditolak. Catatan: ini adalah Kunci Bearer gateway, bukan tiket sekali pakai; kesalahan kredensial tingkat tiket diidentifikasi oleh kode server enam digit (misalnya, 401010/401011)

Tidak

Dapatkan kembali Kunci Bearer dan updateToken; tidak perlu menukar dengan tiket baru

103001

Tidak ada pengalaman aktif saat ini

Panggilan ditolak

startTravel terlebih dahulu

103002

Status saat ini tidak mengizinkan operasi ini (termasuk: ketidakcocokan status; pengalaman tidak mendukung jeda / lanjut / mundur untuk pauseTravel/resumeTravel/rewindTravel (version-nya bukan pengidentifikasi v2 yang diperlukan modenya); status bukan paused untuk rewindTravel; creationModel == ScriptList untuk sendInstruct)

Panggilan ditolak

Periksa status dan mode pengalaman; sendInstruct tidak tersedia dalam mode ScriptList (creationModel == CreationModelValue.ScriptList), di mana konten skrip tidak dikelola melalui SDK ini

103003

Ketidakcocokan mode: sendCommand dipanggil dalam directing atau Acting, atau pauseTravel / resumeTravel / rewindTravel / sendInstruct dipanggil dalam adventure, atau rewindTravel dipanggil dalam Acting

Panggilan ditolak

Periksa apakah mode saat ini sesuai dengan persyaratan antarmuka

103004

Panggilan startTravel konkuren, atau inisialisasi ulang saat Travel sedang dimulai, aktif, atau berakhir (hanya satu Travel yang diizinkan pada satu waktu; SDKError.raw untuk awal konkuren hanya berisi ringkasan tiket yang disamarkan)

Panggilan ditolak

Tunggu endTravel() sebelum mencoba lagi

105001

Koneksi waktu nyata gagal

Ya

Akhiri dan mulai ulang

105002

Waktu bergabung waktu nyata habis

Ya

Akhiri dan mulai ulang

105003

Waktu menunggu frame pertama video habis

Ya

Akhiri dan mulai ulang

105004

Saluran waktu nyata belum siap / pengiriman gagal

Tidak

Konfirmasikan saluran real-time siap dan coba ulang sendCommand setelah running; jika perangkat tertentu bermasalah, cobalah mendeklarasikan dan memberikan RECORD_AUDIO (lihat Panduan Integrasi Android SDK Happy Oyster § Instalasi · Izin)

105005

Panggilan pensinyalan HTTP gateway SDK tidak mengembalikan respons dalam callbackTimeoutMs (default 30s); batas waktu bergabung RTC dan frame pertama masing-masing menggunakan 105002 dan 105003

Tidak

Disarankan untuk mencoba kembali, atau tingkatkan callbackTimeoutMs

105006

Berakhir otomatis karena tidak ada stream: frame pertama tidak pernah tiba, atau stream terputus saat berjalan dan tidak pulih sebelum batas waktu. SDK secara proaktif mengakhiri pengalaman saat ini

Ya

Akhiri dan mulai ulang

106001

Kesalahan jaringan lokal

Tidak

Dapat dicoba ulang

106002

Penguraian respons gagal

Tidak

Dilempar ke pemanggil ketika dipicu oleh panggilan eksplisit; pada polling status internal, hanya onError yang dipancarkan dan pengalaman tidak dihentikan

106003

Layanan hulu mengembalikan respons kesalahan yang tidak dapat dikenali; SDK telah menyimpan informasi asli dalam SDKError.raw (termasuk penolakan edge gateway seperti AccessDenied)

Tidak

Dapat dicoba ulang; jika berlanjut, selidiki ketersediaan layanan bersama dengan raw. Jika raw berisi AccessDenied (paling sering pada permintaan pertama setelah inisialisasi), ini adalah masalah konfigurasi gateway; periksa secara berurutan: ① apakah nama dan versi model benar, masih tersedia, dipublikasikan, dan diotorisasi; ② ejaan apiHost; ③ apakah apiHost, model, dan Key yang disuntikkan melalui updateToken cocok dengan akun dan wilayah yang diperlukan; ④ apakah akun Anda telah ditambahkan ke daftar izinkan aplikasi

108001

SDK dinonaktifkan dari jarak jauh (dimatikan sepenuhnya atau versi terlalu rendah); alasannya ada di SDKError.raw (String)

Ya (ketika SDK mendeteksi hasil penonaktifan, SDK secara otomatis mengakhiri pengalaman yang sedang berlangsung; Anda dapat memulai ulang setelah pemulihan)

Berikan petunjuk kepada pengguna berdasarkan alasan di raw; pandu peningkatan ketika versi terlalu rendah

"Fatal?" merujuk secara khusus pada apakah hal itu memicu SDK untuk mengakhiri pengalaman saat ini secara otomatis. Kesalahan validasi sinkron seperti 100001/100002/103xxx hanya menolak/melempar untuk panggilan tersebut (100002 secara langsung menggagalkan inisialisasi) dan tidak mengakhiri pengalaman.
Fatal vs non-fatal:
  • Kesalahan fatal: SDK secara otomatis mengakhiri pengalaman saat ini (memutuskan koneksi real-time, melepaskan sumber daya, memanggil endTravel) dan memunculkannya melalui onError; host harus membersihkan status pengalaman saat ini dan mengizinkan memulai ulang. Terdapat empat kategori: ① polling status internal membaca status pengalaman failed (misalnya, kegagalan inferensi 500001); ② koneksi real-time fatal (105001/105002/105003); ③ berakhir otomatis tanpa aliran (105006: frame pertama tidak pernah tiba, atau aliran terputus saat berjalan dan tidak pulih sebelum batas waktu, dan SDK secara proaktif mengakhirinya); ④ SDK dinonaktifkan dari jarak jauh (108001).
  • Kesalahan non-fatal: tidak mengakhiri pengalaman dan hanya dimunculkan melalui onError; Anda dapat memanggil updateToken lagi atau menunggu layanan / saluran real-time pulih sebelum melanjutkan. Satu permintaan gagal dari polling status internal itu sendiri (jaringan 106001, parsing 106002, anomali hulu 106003, kesalahan bisnis 5xxxxx) termasuk dalam kategori ini—polling berlanjut pada siklus berikutnya, dan hanya ketika membaca status failed barulah pengalaman diakhiri; kegagalan autentikasi 101001 dan kegagalan pengiriman flush-terbatas asinkron sendCommand 105004 juga bersifat non-fatal. Catatan: SDK tidak pernah mengirimkan payload keepalive apa pun melalui saluran real-time, sehingga 105004 tidak dapat muncul saat sesi idle—hal ini hanya dapat dipicu oleh panggilan sendCommand Anda sendiri.
Pembuatan Gambar
  • FAQ
Video Generation
Model Dunia
Audio
  • Pembuatan audio
Realtime API
Penyematan Teks
TokenPlan
Model production
Referensi API HappyOyster Android SDK - Alibaba Cloud Model Studio