El punto de entrada del SDK de HappyOyster para iOS es el singleton a nivel de proceso HappyOysterEngine.shared. Todos los métodos de negocio son async throws y lanzan OysterSDKError en caso de fallo. Una sola experiencia es gestionada por un identificador OysterTravel, que abarca tres modos —adventure, directing y acting— tanto en UIKit como en SwiftUI.
- Este documento es la descripción de funciones externas + referencia de interfaz para el Happy Oyster iOS SDK: explica los parámetros, tiempos, uso y ejemplos breves de cada tipo y método público, uno por uno.
- Para el flujo de integración completo (configuración del proyecto, configuración de dependencias, coordinación del lado del servidor, ejecución de extremo a extremo), consulte la documentación del proyecto de ejemplo; no se repite aquí.
1. Conceptos básicos
Primero algunos términos, para facilitar la lectura del resto.
Concepto | Descripción |
|---|---|
token | Token de autenticación HTTP (API Key temporal de Bailian). Su servidor lo obtiene mediante intercambio a través de la API de Bailian y lo entrega al cliente; se inyecta mediante |
ticket | Credencial de prueba de un solo uso. Su servidor la obtiene mediante intercambio a través de la plataforma abierta |
Mundo | Un mundo de IA que contiene personajes y escenas. Creado y gestionado por su servidor; el SDK no interviene. |
Travel | Una única experiencia en tiempo real, correspondiente a un identificador |
Estado de la sesión |
|
Modo |
|
2. Descripción general
Tras integrar este SDK, su aplicación puede ingresar a "mundos" generados en tiempo real por IA y disfrutar de una experiencia de video interactiva en tiempo real en tres modos: aventura, dirección o actuación: iniciar la experiencia → reproducción en tiempo real → interacción en tiempo real → control de proceso (pausa/reanudación/rebobinado/finalización) → callbacks de estado y error.
Cada modo admite un conjunto diferente de capacidades. Controle su interfaz de usuario basándose en el mode devuelto por start():
Capacidad |
|
|
|
|---|---|---|---|
| Sí | No | No |
| No | Sí | Sí |
| No | Sí | Sí |
| No | Sí | No — ocultar el punto de entrada |
| Sí | Sí | Sí |
| Aplicado | Ignorado | Ignorado |
acting priorizan el retrato: start() devuelve un aspectRatio (9:16 / 16:9) para la sesión. Úselo para elegir la orientación del reproductor y el tamaño del contenedor antes de extraer el flujo (véase §8).import HappyOysterSDK; los puntos de entrada principales son dos tipos.
HappyOysterEngine — el punto de entrada de orquestación, un singleton a nivel de proceso HappyOysterEngine.shared.
Método / Propiedad | Descripción |
|---|---|
| Inicializa el entorno de ejecución y registra automáticamente el motor en tiempo real (una sola vez, antes de |
| Inyectar / actualizar el token de autenticación HTTP |
| Crear un identificador de sesión con una credencial de un solo uso |
| Liberar recursos (se puede |
| La versión actual del SDK |
OysterTravel — el identificador de sesión para una experiencia, creado por createTravel(ticket:).
Método / Propiedad | Descripción |
|---|---|
| Vista de reproducción (UIKit / SwiftUI) |
| Stream de push de cambio de estado + error / estado actual observable |
| Conectar y reproducir (opcionalmente solicitar la duración máxima de una experiencia de aventura) |
| Instrucción de texto en modo dirección |
| Control del modo Aventura |
| Pausar / reanudar ( |
| Rebobinar (solo en pausa) |
| Finalizar (idempotente, asegúrese de llamarlo) |
| Liberar / restaurar temporalmente el micrófono |
OysterLog para tomar el control del registro interno del SDK; HappyOysterEngine.version para leer la versión; OysterVideoView es la vista de reproducción de SwiftUI (equivalente a videoView). Su uso se describe más adelante.
Ciclo de vida: inicializar → inyectar token → crear sesión → montar video + suscribirse a eventos → iniciar reproducción → interactuar → finalizar. El SDK no es responsable de crear ni gestionar mundos (tarea realizada por su servidor), ni expone detalles de comunicación en tiempo real de bajo nivel.
3. Inicio rápido
Un flujo completo desde la inicialización hasta la finalización, con comentarios paso a paso. Los detalles de cada API se encuentran en la §6.
4. Requisitos
Elemento | Requisito |
|---|---|
SO mínimo | iOS 15.0+ (todos los tipos públicos están marcados con |
Lenguaje | Swift ( |
Concurrencia | Acceso desde el hilo principal (los tipos de entrada están marcados con |
Red | Se requiere acceso a la red pública |
Permisos |
|
Info.plist debe proporcionar NSMicrophoneUsageDescription; de lo contrario, iniciar la captura en tiempo real provocará un fallo. Cuando necesite acceso exclusivo al micrófono (por ejemplo, reconocimiento de voz), utilice pauseLocalAudioCapture() / resumeLocalAudioCapture() para cederlo y restaurarlo temporalmente (consulte la §6.2).
5. Integración y autenticación
5.1 Integración y dependencias
import HappyOysterSDK es todo lo que necesita a nivel de código. El SDK se distribuye como un binario precompilado (xcframework) a través de subespecificaciones de CocoaPods, publicado en el Trunk público de CocoaPods — declare las dependencias en su Podfile:
AliVCSDK_ARTC es obligatorio siempre que incluya HappyOysterSDK/StreamAliRTC: si falta, el SDK recurre silenciosamente a Loopback — puede conectarse y alcanzar running, pero muestra una pantalla negra sin error.5.2 Modelo de autenticación
El SDK no obtiene ni actualiza tokens, manteniendo la ligereza. La autenticación tiene dos capas y el integrador gestiona sus ciclos de vida:
- Token de autenticación HTTP (API Key temporal de Bailian): Su servidor lo obtiene mediante intercambio a través de la API de Bailian y lo entrega al cliente; se inyecta mediante
updateToken(_:). Algunos servicios internos del SDK llaman directamente a la puerta de enlace de Bailian, portando este token para la autenticación; por lo tanto, debe ser una API Key temporal emitida por Bailian, no un token de su propio servicio de negocio. El SDK conserva únicamente el más reciente, no lo persiste ni lo renueva; tras su caducidad, debe volver a obtenerlo e inyectarlo. - Credencial de prueba de un solo uso
ticket: Su servidor la obtiene mediante intercambio a través de la plataforma abiertaget-travel-credential(prefijotk_, válida durante 30 minutos, de un solo uso) y se utiliza como argumento decreateTravel(ticket:); deja de ser válida cuando la experiencia finaliza (de forma normal o anómala) o caduca, y no puede reutilizarse.
start / pause / resume / rewind / sendInstruct / sendCommand) se rechazan con 108001 y cualquier experiencia en curso es finalizada por el SDK (consulte la §9). OysterSDKError.raw contiene un motivo legible por humanos; solicite al usuario que actualice cuando la versión sea demasiado baja.updateToken(_:). Hay dos lugares donde necesita determinar si el token ha caducado:
- Al llamar a APIs como
engine.createTravelotravel.start, maneje el error y verifique los tipos de error de token caducado/inválido (101001/101002); después de inyectar un nuevo token, vuelva a llamar a la API correspondiente. - Al escuchar el evento
.errordeOysterTravelEvent, verifique los tipos de error de token caducado/inválido, vuelva a solicitar el token e inyéctelo.
6. Referencia de API
Hay dos tipos de entrada, ambos @MainActor y @available(iOS 15.0, *). Los métodos de negocio son async throws y lanzan OysterSDKError en caso de fallo; los métodos con valores de retorno están todos marcados con @discardableResult.
6.1 HappyOysterEngine
Un singleton a nivel de proceso, el punto de entrada de orquestación. init no es público — use siempre HappyOysterEngine.shared; no lo instancie usted mismo (el motor subyacente en tiempo real también es un singleton de proceso).
initialize(config:)
- Propósito: Inicializar el entorno de ejecución y registrar automáticamente el motor en tiempo real (no se requiere registro manual por parte del host).
- Parámetros:
config.apiHostes la URL de la puerta de enlace de Bailian, no la de su servidor de negocio, y es obligatoria; en entornos de prelanzamiento o prueba, debe pasar explícitamente la puerta de enlace correspondiente; de lo contrario, las solicitudes fallarán (por ejemplo,106001, dominio no resuelto).config.modeles el nombre del modelo versionado habilitado para su cuenta y también es obligatorio sin valor predeterminado: Happy Oyster se divide en submodelos por modo, por lo que el SDK no puede inferir cuál utilizar. Ambos deben pertenecer a la misma cuenta y región que el token inyectado. Otros campos se detallan en la §8OysterConfig. - Un modelo sirve a un
mode: cada modelo por modo tiene su propia ruta de puerta de enlace, por lo que una sola llamada ainitializesolo sirve mundos de ese únicomode. Si su aplicación ofrece mundos en varios modos, simplemente llame ainitialize()nuevamente con el modelo correspondiente antes de entrar a un mundo de un modo diferente; mientras está inactivo, prevalece la configuración más reciente, no se requierecleanup()y se conserva el token inyectado; mientras un Travel está en curso, la llamada se ignora, así que invoqueend()primero. Un modelo que no coincida con elmodedel mundo es rechazado por la puerta de enlace conAccessDenied, normalizado a106003. - Cuándo usar: Llamar una vez antes de
createTravel, lo antes posible después del inicio de la aplicación. - Devuelve:
Bool— indica si laconfigque usted proporcionó surtió efecto. Esfalseen dos casos: la configuración no es válida (apiHost/modelen blanco o sin formar una URL de puerta de enlace válida), o hay un Travel en curso, por lo que se ignoró la llamada. En ambos casos, el entorno de ejecución permanece sin cambios. - Nota: Mientras está inactivo, llamarlo nuevamente reconfigura el entorno de ejecución con la nueva configuración (cambiar
apiHost/modelno requierecleanup(), y se conserva el token inyectado); es una operación nula con solo una advertencia mientras un Travel está en curso, así que invoqueend()primero. Una configuración no válida deja el entorno de ejecución sin cambios. No utiliceisReadypara determinar si una re-initializetuvo éxito: si fue rechazada, la configuración anterior sigue vigente yisReadypermanecetrue;isReadyresponde a "¿está el motor usable ahora?", mientras que el valor de retorno responde a "¿surtió efecto la configuración que acabo de pasar?".
OysterLog
- Propósito: Configurar y tomar el control del registro interno del SDK, imprimiéndolo en su propio módulo de registro. Proporciona
setMinimumLevel(_:)para establecer el nivel ysetHandler(_:)para salida personalizada (véase el ejemplo de §3).
updateToken(_:)
- Propósito: Inyectar / actualizar el token de autenticación HTTP (clave de API temporal de Bailian, §5.2).
- Cuándo usarlo: Después de
initialize, puede llamarse en cualquier momento; vuelva a intercambiar y llame nuevamente después de que el token caduque o tras recibir un error relacionado con la autenticación (101001/101002). - Nota: Es una operación nula con una advertencia cuando no se ha
initialized.
createTravel(ticket:)
- Propósito: Crear un único identificador de sesión con un
ticketde un solo uso. - Parámetro:
ticketes una credencial de un solo uso; una vez creada, se considera ocupada para esta experiencia. - Cuándo usarlo: Llame antes de cada nueva experiencia; el identificador devuelto aún no está conectado y debe llamar a
travel.start()después. El video se toma del identificador devuelto (véase §6.2). - Nota (
throwssincrónico): lanza100001si no se ha ejecutadoinitialize; lanza103004si se llama nuevamente antes de que el Travel anterior haya ejecutadoend()(cada motor permite solo un Travel activo a la vez).
cleanup()
- Propósito: Liberar recursos del SDK (finalizar el travel activo, configuración de tiempo de ejecución, token).
- Cuándo usar: Al salir completamente del SDK o necesitar cambiar la
config. - Nota:
async— internamente termina determinísticamente el travel activo actual medianteend()primero, luego desmantela el entorno de ejecución, sin dejar operaciones fire-and-forget. Después de la liberación, puede ejecutarinitializenuevamente.
6.2 OysterTravel
El identificador de sesión creado por createTravel; es de un solo uso y se invalida al alcanzar un estado terminal (end / finalización del lado del servidor / fallo), lo que requiere invocar nuevamente createTravel a través del motor. También es un ObservableObject (@Published status, puede controlar directamente SwiftUI).
videoView / OysterVideoView(travel:)
- Propósito: El punto de entrada de renderizado para la imagen remota — "el SDK proporciona la vista, el host la coloca". Para UIKit, tome
travel.videoView; para SwiftUI, useOysterVideoView(travel:). - Cuándo usarlo: Disponible tan pronto como se crea el identificador (el acceso repetido devuelve la misma vista); móntela en cualquier jerarquía y, una vez que el motor esté listo, se renderiza automáticamente. Montarla antes o después de
start()funciona en ambos casos, sin pantalla negra. - Nota: Cuando finaliza la sesión, el SDK libera automáticamente el enlace de renderizado; elimine la vista de la jerarquía según sea necesario.
events / status / isEnded
- Propósito:
eventses el flujo push de cambios de estado + errores;statuses el estado externo actual observable;isEndedes un indicador legible sincrónicamente para el estado terminal. - Cuándo usarlo: Se recomienda comenzar a consumir
eventsantes destart(), para evitar perder los primeros estados. - Nota: Cada acceso a
eventsdevuelve un flujo independiente, compatible con múltiples suscripciones; cancelar la suscripción equivale a finalizar la iteraciónfor await(o destruir laTaskretenida). En SwiftUI, puede observar directamentestatuscon@StateObject/@ObservedObject(los errores siguen llegando a través deevents). Consulte la §7.
start() / start(maxExperienceTimeSec:)
- Propósito: Usar el
ticketcapturado en el momento de la creación para intercambiarlo por la configuración de travel + unión RTC y conectarse para reproducir. En caso de éxito, el SDK establece automáticamente la conexión en tiempo real y comienza el sondeo de estado interno, exponiendo el estado a través deevents. - Parámetro:
maxExperienceTimeSec(opcional) — solicita la duración máxima (en segundos) de esta experiencia de aventura. El valor se envía al servidor tal cual; los valores permitidos, la duración efectiva real y el momento de finalización automática son decididos por el servidor; el SDK no realiza validación local. Pasarnil(o llamar astart()sin parámetros) utiliza la duración predeterminada del servidor. El modo Dirección ignora este parámetro. Cuando se agota el tiempo, el servidor finaliza la experiencia y el host recibe el estado terminalendeda través deevents(igual que una finalización del lado del servidor, consulte la §7). - Devuelve:
OysterStartTravelData(mode/version/encryptedTravelId, etc., véase §8), que determina la interfaz de usuario de interacción. - Errores:
401010/401011(credencial no válida o ya utilizada),403002(mundo no listo),403007(especificación de servicio no habilitada, por ejemplo, actuación),429001/429002(límite de concurrencia / capacidad agotada),500001(fallo de recurso/servidor),103004(inicio concurrente). - El
modedel mundo delticketdebe coincidir con elmodelpasado ainitialize(responsabilidad del llamante): con modelos por modo, cada modelo es su propia ruta de puerta de enlace, ystart()envía elticketa la ruta del modelo actualmente inicializado****. El SDK no verifica ni puede verificar esto por usted de antemano —modese entrega mediante la respuesta a esta misma llamada destart()(OysterStartTravelData.mode); antes de la llamada, el SDK solo posee unticketopaco y un nombre de modelo, sin ningún modo contra el cual comparar, e inferir el modo a partir del nombre del modelo sería adivinar un esquema de nomenclatura propiedad del servidor, lo cual el SDK no hace. Por lo tanto: antes de entrar en un mundo de un modo diferente, llame nuevamente ainitialize()con el modelo correspondiente (mientras está inactivo, prevalece la configuración más reciente — no se requierecleanup()y se conserva el token; mientras un Travel está en curso, la llamada se ignora, así que ejecuteend()primero). En caso de discrepancia, esta llamada destart()falla en la puerta de enlace; al diagnosticar, verifique primero que elmodelactual y elmodedel mundo delticketpertenezcan juntos, luego consulte los códigos de error de credenciales anteriores. - Nota (finalización automática por ausencia de flujo): El servidor envía un "tiempo de espera sin flujo" (predeterminado ~30 s). Si, tras conectarse, no se recibe ningún flujo dentro de esa duración (nunca alcanza
running), el SDK finaliza automáticamente la experiencia, transiciona afailedy expone105006mediante.errordeevents(fatal; manéjelo regresando a la pantalla previa al inicio, sin necesidad de medir el tiempo usted mismo).
pause() / resume()
- Propósito: Pausar / reanudar la experiencia (idempotente).
- Cuándo usarlo: Soportado por mundos de
directingyacting; no soportado poradventure. Use elmodedevuelto porstart()para decidir de antemano si mostrar un botón de pausa.pauserequiere que el estado actual searunning;resumerequierepaused. - Errores:
103001(sin experiencia activa),103002(estado/versión no permitidos),103003(discordancia de modo).
rewind(toSec:)
- Propósito: Rebobinar a los segundos especificados. En caso de éxito, el SDK se reincorpora automáticamente con el rtcConfig original y reanuda la reproducción.
- Cuándo usarlo: Solo puede iniciarse en el estado
paused, y solo por mundos dedirecting—actingyadventureno admiten rebobinado, así que oculte el punto de entrada de rebobinado en esos modos y no lo llame. - Errores:
103001,103002.
end()
- Propósito: Finalizar la experiencia (idempotente, puede llamarse repetidamente). Tras una llamada exitosa o una salida anómala, el SDK desconecta automáticamente la conexión en tiempo real, detiene el sondeo y libera todos los recursos de la sesión; el
ticketse invalida simultáneamente y el identificador entra en un estado terminal. - Cuándo usar / Nota: Ya sea que el usuario salga activamente o que la experiencia finalice pasivamente (caducidad del temporizador, recepción de
.ended/.failed, destrucción de la página), asegúrese de que se ejecute una única llamada aend(); de lo contrario, los recursos remotos podrían no liberarse oportunamente. Se recomienda canalizar todas las rutas de salida hacia el mismo método de limpieza idempotente.
sendInstruct(content:) (modo dirección)
- Propósito: Enviar una instrucción de texto para impulsar la trama.
- Cuándo usarlo: Modo dirección; se envía directamente cuando está en
running, se almacena en caché cuando está enpausedy se reenvía con el primer fotograma tras reanudar arunningmediante reconexión. - Errores:
103001,103002,103003(llamado en modo aventura),403004(moderación de contenido),404000(travel no encontrado).
sendCommand(_:) / flushCommands() (modo aventura)
sendCommand: Envía comandos de control de dirección/vista/acción (consulte la §8OysterAdventureCommand; fire-and-forget, sin retorno, no lanza excepciones). Efectivo únicamente en modo aventura cuando estárunning. La entrada externa puede ser de alta frecuencia en cada fotograma, y el SDK aplica limitación internamente (muestreo de última victoria, fusión de fotogramas a la tasa de línea RTC); el host no necesita aplicar limitación por sí mismo. Tenga en cuenta que la respuesta del servidor a los comandos tiene latencia inherente, por lo que el momento efectivo real no es fijo.flushCommands: Llamado en el momento de "liberación de tecla / liberación de entrada", reenviando inmediatamente el último comando ya en espera en la cola; es una operación nula pura cuando no hay ningún comando pendiente, sin generar ningún comando nuevo.- Errores (todos expuestos a través del
.errordeevents, no mediantethrows): sin experiencia activa103001; llamado en modo dirección103003; canal en tiempo real no listo / envío fallido105004.
pauseLocalAudioCapture() / resumeLocalAudioCapture()
- Propósito: Liberar / restaurar temporalmente la ocupación del SDK sobre la captura del micrófono local.
- Cuándo usarlo: Cuando algo como el reconocimiento de voz necesita acceso exclusivo al micrófono, ejecute
pauseprimero yresumedespués.
7. Eventos y estado
Los eventos están adjuntos a OysterTravel.events y son el canal de push activo del SDK hacia usted, utilizados para exponer situaciones no desencadenadas por sus propias llamadas (por ejemplo, problemas con la conexión en tiempo real gestionada internamente o el sondeo de estado).
- SwiftUI:
OysterTraveles unObservableObject; use directamente@StateObject/@ObservedObjectpara observarstatusy controlar la interfaz de usuario; los errores siguen proviniendo deevents. - Imperativo / UIKit: en un
Task, usefor await event in travel.events { ... }yswitchsobre.statusChanged/.error; cancele elTaskretenido al finalizar.
OysterTravelStatus (5 estados de proceso + 2 estados terminales):
Status | Descripción | Manejo típico |
|---|---|---|
| después de crear, antes de iniciar | — |
| conectando / reconectando (conexión / reconexión interna) | mostrar aviso de conexión / reconexión |
| stream listo, interactivo (reproducción interna) | mostrar imagen y controles |
| pausa aceptada, esperando confirmación del servidor | mostrar "pausando…" |
| pausado (confirmado) | mostrar estado pausado (solo |
| finalizado (finalización activa o finalización del lado del servidor). Terminal | finalizar y cerrar la página |
| fallido. Terminal | mostrar error y finalizar |
ended / failed, la sesión ha terminado y todas las operaciones de sesión (pause/resume/sendCommand…) ya no surten efecto. Las devoluciones de llamada pueden activarse en el hilo principal, por lo que puede actualizar la interfaz de usuario directamente.8. Modelos de datos
@available(iOS 15.0, *). Los valores de retorno y parámetros a continuación son salidas del SDK, construidos internamente en el lugar con tipos nativos de Swift (Date / TimeInterval / OysterTravelStatus); no Codable son ni exponen detalles de transmisión (snake_case) — la decodificación de la transmisión ocurre dentro del SDK.- Nota: los rawValues de los comandos están en lower camelCase (por ejemplo,
front/mouseLeft/jump); los valores de enumeración anteriores son autoritativos. - Nota:
modees externamenteadventure(wander) /directing(historia) /acting(juego de roles); la definición deOysterModeValuees autoritativa. - Nota:
aspectRatioes una cadena abierta (actualmente9:16/16:9, pueden añadirse más). Analícela comowidth:heighty compare la proporción en lugar de coincidir con valores conocidos.
9. Códigos de error
El SDK reporta los errores uniformemente como OysterSDKError, y el tipo siempre se distingue por code; no determine el tipo basándose en "la ruta por la que llegó el error": el mismo code puede ser lanzado por un método de negocio (async throws) o expuesto mediante .error de events. Para la coincidencia tipada, utilice error.kind (consulte la §8 OysterErrorKind).
Códigos de error: servidor 4xxxxx/5xxxxx, cliente-local 1xxxxx.
Códigos de error del servidor (comunes)
code | Significado | Manejo sugerido |
|---|---|---|
| Parámetros no válidos (valor de enumeración no válido, etc.) | Verifique los parámetros de la solicitud o la versión del SDK |
| Credencial de experiencia ( | Solicitar al servidor que vuelva a emitir la credencial |
| Credencial de experiencia ( | Credencial de un solo uso; volver a emitir |
| El mundo no existe, fue eliminado o no pertenece al desarrollador actual (incluido un mundo eliminado después de emitir la credencial) | Seleccionar un mundo válido nuevamente |
| Estado del mundo no listo | Espere a que el mundo esté listo antes de comenzar |
| La API solo permite la clave de API principal | No se puede usar una clave temporal para esta API |
| Contenido de entrada rechazado por moderación de contenido; aplica a instrucciones de texto de | Cambie la entrada e inténtelo de nuevo |
| La especificación de servicio solicitada no está habilitada | No reintente como si la capacidad estuviera llena; cambie a una especificación habilitada (típicamente: la cuenta no tiene especificación de actuación) |
| Configuración de capacidad temporalmente no disponible | Reintentar más tarde |
| El recurso no existe (propiedad de mundo/wander o sin artefacto) | Verificar ID / estado |
| La solicitud entra en conflicto con el estado actual del recurso | Verifique el estado de la experiencia |
| Límite de concurrencia alcanzado para esta especificación | Reintente después de que finalice una sesión existente (no confundir con |
| Capacidad disponible insuficiente | Reintentar más tarde |
| Error interno del sistema | Reintentar más tarde / reportarlo |
| Asignación de recursos de inferencia o fallo interno del servicio | Reintentar más tarde |
Códigos de error del cliente local
code | Significado | El SDK finaliza automáticamente la sesión | Manejo sugerido |
|---|---|---|---|
| Llamado antes de la inicialización del SDK; también cubre un | No (lanzado sincrónicamente, rechazando esta llamada) | Ejecute |
| Token de autenticación HTTP no inyectado | No | reintentar después de |
| Token de autenticación HTTP no válido / rechazado | No | volver a intercambiar el token y luego reintentar |
| No hay experiencia activa actualmente | No (rechazando esta llamada) |
|
| El estado/versión actual no permite esta operación | No (rechazando esta llamada) | verificar estado de la experiencia / |
| Desajuste de modo (por ejemplo, | No (rechazando esta llamada) | elegir la API correcta por |
| Creación/inicio concurrente de experiencia | No (lanzado sincrónicamente) | serializar llamadas, |
| Error de conexión en tiempo real | Sí | finalizar y reiniciar |
| Tiempo de espera de unión en tiempo real agotado | Sí | finalizar y reiniciar |
| Tiempo de espera agotado esperando el primer fotograma de video | Sí | finalizar y reiniciar |
| Canal en tiempo real no listo / error de envío | depende (fallo de envío activo; el heartbeat es solo de reporte) | enviar después de |
| Tiempo de espera de callback agotado (predeterminado 30s) | No | reintentar y aumentar |
| Sin stream después de unirse; el SDK finaliza automáticamente la experiencia | Sí | finalizar y reiniciar |
| Error de red local | No | reintentable |
| Error al analizar la respuesta | depende | actualizar el SDK / reportar |
| Código de error no reconocible / código de error de cadena de proxy | No | reintentable |
| Deshabilitado remotamente por el interruptor de funciones del servidor (apagado total o versión demasiado baja; motivo en | Sí | Seguir el motivo en |
OysterSDKError no tiene isFatal). Semánticamente, "fatal" significa específicamente si el SDK termina activamente la sesión (desconectar RTC, liberar toda la sesión) —
- Errores que finalizan automáticamente la sesión (por ejemplo,
105001/105002/105003/105006/108001): el host detecta esto a partir del estado terminal de la máquina de estados (status → failed, expuesto mediante.statusChangeddeevents) y regresa a la pantalla previa a "iniciar experiencia" en consecuencia, sin necesidad de evaluar por sí mismo la gravedad del error. - Errores de rechazo de llamada (
100001/103001/103002/103003/103004): se lanzan sincrónicamente / la llamada se rechaza cuando usted llama activamente; no terminan la sesión. - Otros errores no fatales (por ejemplo,
101001/101002/105005/106001/106003): no terminan la sesión; reintente según lo sugerido o continúe después de volver a inyectar el token.
106001 puede tener dos causas: un error de red local o un apiHost incorrecto. Si reintentar no recupera la solicitud, verifique si apiHost está configurado correctamente.106003 después de configurar model suele indicar que el nombre o la versión del modelo son incorrectos, o que no están habilitados para su cuenta: verifique el modelo junto con apiHost y el token, los cuales deben pertenecer todos a la misma cuenta y región; la puerta de enlace rechaza cualquier discrepancia con AccessDenied, normalizado a este código.