Преминете към основното съдържание

API на Sphere

Уеб приложението на Sphere е обикновен клиент на REST API под /api/v1. Всичко, което прави приложението, можете да направите и чрез API. Пълният справочник на крайните точки е справочникът на API на Sphere, генериран от entrosity-sphere.backend/api/openapi.yaml – спецификацията, от която се генерират маршрутизаторът и валидирането на заявките на сървъра (и TypeScript типовете на приложението).

Конвенции​

  • Базов URL: https://hub.entrosity.com/sphere/api/v1 (проксито премахва /sphere). API на конектора е под /sphere/api/connector/v1 (Протокол на конектора на Sphere).
  • Удостоверяване: Authorization: Bearer <product token> – петминутен токен от Entrosity Hub за продукта sphere (POST /api/platform/v1/auth/product-token {"product":"sphere"} със сесията в Hub, API на Hub). Sphere няма собствено влизане; потребителите, тенантите и ролите идват от Hub. Докато Sphere е в бета версия, Hub издава токените му само на администраторите на платформата.
  • Правила за достъп: всеки маршрут има правило в entrosity-sphere.backend/internal/http/portal/access.go: публичен, влязъл потребител, глобален администратор или право в тенанта (Роли и права). Потребителите на тенант могат да извикват само /tenants/{id на техния тенант}/…; всеки друг тенант връща 404. Липсващо право връща 403. Два маршрута проверяват второ право в обработчика: възпроизвеждането на запис (kind: playback) изисква и playback:view, а споделеният изглед – и views:manage.
  • JSON тела с ключове в snake_case, най-много 1 MB. Схемите на заявките отказват непознати полета (422).
  • Списъци: одитните журнали и администраторският списък с тенанти приемат ?page=&page_size= (по подразбиране 50, най-много 200) и връщат items, page, page_size и total. Другите списъци връщат всички елементи.
  • Журнал с аларми: GET /tenants/{tenantID}/alarms е подреден от най-новите с keyset страниране: limit (1–500, по подразбиране 100), филтри from, to, nvr_id, camera_id, acked и code (повторете за няколко, най-много 20). Когато страницата е пълна, отговорът има next_before_at и next_before_id: подайте ги като before_at и before_id за следващата страница.
  • Ограничение на заявките: 20 заявки в секунда за IP адрес на клиент, пик 60 (SPHERE_API_RATE_PER_SECOND, SPHERE_API_RATE_BURST); над това 429.
  • Всеки отговор съдържа X-Request-ID.

Грешки​

Грешките са RFC 7807 application/problem+json със стабилен code:

{
"type": "/problems/stream_limit",
"title": "Conflict",
"status": 409,
"code": "stream_limit",
"detail": "too many streams are open for this site or NVR; close some first",
"request_id": "…"
}

Грешките при валидиране имат code: "validation" и fields със съобщение за всяко поле. Най-честите конфликти:

КодКога
stream_limitPOST /streams: достигнато е ограничението на конектора или на видеорекордера за основни потоци или възпроизвеждания и никой неизползван поток на живо не може да спре, за да освободи място (Ограничения).
nvr_offlinePOST /streams, PTZ, търсене на записи: видеорекордерът не е свързан или не е online (също и докато конекторът му е офлайн). POST /nvrs/{nvrID}/tune-live: видеорекордерът не е свързан.
camera_disabledPOST /streams: камерата е изключена.
connector_offlinePOST /nvrs/{nvrID}/test, POST /nvrs/{nvrID}/tune-live: конекторът на видеорекордера не е свързан.
nvr_address_takenДобавяне или промяна на видеорекордер: конекторът вече управлява видеорекордер на този хост и порт.
connector_has_nvrsПремахване на конектор, който още управлява видеорекордери.

Всички кодове: Кодове на грешки.

Гледане на видео​

Видеото не минава през API: API дава сесия на зрител с краткотраен токен, а браузърът възпроизвежда потока от медийния сървър по WebRTC (WHEP).

  1. Отваряне: POST /tenants/{tenantID}/streams с camera_id и:

    • на живо: kind: "live" (по подразбиране) и profile sub (по подразбиране, за решетки) или main (пълна резолюция);
    • запис: kind: "playback", start и end (след start, най-много 24 часа по-късно, start не в бъдещето).

    Отговорът (201) е StreamSession: неговият id (сесията на зрителя), медийният path, whep_url, token и token_expires_at (пет минути) и state и error на потока.

  2. Възпроизвеждане: изпратете WebRTC предложението (offer) към whep_url (WHEP) с Authorization: Bearer <token>. Токенът се проверява при отварянето на WHEP сесията и само за този път.

  3. Поддържане: POST /tenants/{tenantID}/streams/{streamID}/keepalive на всеки 15 секунди. Той връща отново сесията с текущото състояние и нов токен (използвайте го, ако плейърът трябва да се свърже отново). Зрител без keepalive от 45 секунди се премахва.

  4. Затваряне: DELETE /tenants/{tenantID}/streams/{streamID} (204). Поток на живо, който никой не гледа, продължава през времето си за изчакване, 5 минути за подпоток и 2 минути за основен поток (SPHERE_LIVE_IDLE_GRACE, SPHERE_LIVE_IDLE_GRACE_MAIN), така че зрител, който се върне към камерата, се присъединява към него без ново стартиране във видеорекордера; при достигнато ограничение неизползваният поток, който не е гледан най-дълго, спира, за да освободи място. Възпроизвеждането на запис спира веднага щом зрителят му изчезне, при следващото изпълнение на streams.sweep (до 10 секунди), включително когато зрителят е премахнат заради липсващи keepalive заявки. Уеб приложението затваря сесиите си, когато страницата се разтоварва (заявка с keepalive при pagehide), така че презареждане или затворен раздел ги освобождава веднага.

stateЗначение
startingЖелан; конекторът още не го е публикувал (също и докато конекторът му се свързва отново).
liveКонекторът го публикува (от момента, в който задачата му за стартиране успее): възпроизвеждайте го.
failedКонекторът не можа да го стартира; error казва защо. Следващият зрител, който го отвори, го стартира отново.
stoppedНикой вече не го иска (затворен е или видеорекордерът е несвързан) или възпроизвеждането е стигнало края на записа.
  • Потокът на живо (t/<tenant>/live/<camera>/<main|sub>) е общ: първият зрител го стартира на конектора, следващите се присъединяват, и той се взима от видеорекордера веднъж, колкото и зрители да има. Възпроизвеждането (t/<tenant>/pb/<session>) е на самия зрител.
  • Сесията на зрител принадлежи на потребителя, който я е отворил: сесия на друг потребител връща 404.
  • Промените на състоянието идват и като събития stream.state (по-долу).

Асинхронни операции​

Някои извиквания стартират задача на конектора и връщат задачата веднага (202):

ИзвикванеЗадачаРезултат
POST /tenants/{tenantID}/nvrs/{nvrID}/testsphere.nvr.test{info, rtsp_reachable, warnings}; при успех данните и камерите на видеорекордера се обновяват.
POST /tenants/{tenantID}/cameras/{cameraID}/recordings {from, to} (най-много 7 дни)sphere.recordings.find{segments: [{start, end, type, size_bytes}], truncated}
POST /tenants/{tenantID}/cameras/{cameraID}/ptz {code, action, speed?, preset?}sphere.ptzняма
POST /tenants/{tenantID}/nvrs/{nvrID}/tune-live {keyframe_seconds?}sphere.nvr.tune_liveNvrLiveTuneResult: {channels: [{channel, fps, gop_before, gop_after, changed, error, measured_ms}]} (measured_ms: интервалът, измерен в подпотока; камера, която запазва по-дълъг, е changed: false)

Проверявайте GET /tenants/{tenantID}/jobs/{jobID}, докато status стане succeeded, failed, timeout или cancelled (или следете job.update); result, error_code и error носят резултата.

  • PTZ: движение (Up, Down, Left, Right, диагоналите, ZoomTele, ZoomWide, FocusNear, FocusFar, IrisLarge, IrisSmall) продължава от action: "start" до action: "stop" (задръжте, за да се движи); speed е 1–8. GotoPreset, SetPreset и ClearPreset използват само start, с preset 1–255. Командата изтича след 5 секунди, така че закъсняла команда никога не движи камерата. Камерите, които видеорекордерът не отчита като PTZ, не се отказват; командата се проваля на конектора, ако камерата не може да я изпълни.
  • Състояние на видеорекордера: добавянето на видеорекордер, свързването и прекъсването на връзката (POST /nvrs/{nvrID}/connect, …/disconnect) и, за свързан видеорекордер, нов адрес или часова зона и нови идентификационни данни (PUT /nvrs/{nvrID}/credentials) сами поставят в опашката задача sphere.nvr.apply; по-новата замества по-стара, която още чака. GET /tenants/{tenantID}/nvrs/{nvrID}/jobs изброява последните 50 задачи на видеорекордера.
  • Оптимизиране за изглед на живо: tune-live (nvrs:manage, записва се в одита като nvr.tune_live) задава във видеорекордера интервала между ключовите кадри на подпотока на всяка камера на най-много keyframe_seconds (1–4, по подразбиране 1; тялото не е задължително) × кадровата ѝ честота. Основните потоци никога не се променят, по-кратките интервали се запазват. За всеки канал fps е кадровата честота на подпотока, gop_before и gop_after – интервалът в кадри, changed – дали видеорекордерът е приел новия (false без error: вече е достатъчно кратък), а error – защо не (също когато видеорекордерът е приел стойност, която не е запазил). 422 validation за друг keyframe_seconds, 409 nvr_offline, когато видеорекордерът не е свързан, 409 connector_offline, когато конекторът му е офлайн (Видеорекордери).
  • Паролите на видеорекордерите са само за запис: POST /nvrs и PUT /nvrs/{nvrID}/credentials ги приемат и те никога не се връщат.

Обновления на живо​

Приложението получава обновления на живо като server-sent events:

  1. POST /auth/sse-token {"tenant_id": …} връща токен, валиден 60 секунди, обвързан с тенанта и сесията.
  2. GET /tenants/{tenantID}/stream?sse_token=<token> (или с bearer токена) предава text/event-stream, с коментар за поддържане на връзката на всеки 25 секунди.
СъбитиеДанни
alarm.newМасив от нови аларми {id, occurred_at, code, action, channel, nvr_id, camera_id} (до 50 в събитие).
alarm.ack{ids?, before?}: аларми са потвърдени, по id или до даден момент.
nvr.status{nvr_id, status, error?, changed?}; changed означава, че данните или камерите на видеорекордера са се променили (прочетете ги отново).
stream.state{path, state, error?}
connector.status{connector_id, status} (online, offline, deleted)
job.update{id, connector_id, nvr_id?, type, status, error_code?, finished_at?}: задача на конектор е сменила състоянието си.

Аларми и изгледи​

  • POST /tenants/{tenantID}/alarms/ack потвърждава аларми по ids (най-много 500) или всички аларми до before, или и двете; връща {acked} (колко) и изпраща alarm.ack. Потвърждаването записва кой и кога; иначе алармите никога не се променят.
  • Запазени изгледи (/tenants/{tenantID}/views): name, layout (разделянето по броя клетки: 1, 4, 6, 8, 9, 16, 25, 36 или 64, където 6 и 8 са „една голяма + 5“ и „една голяма + 7“), cells (камера за всяка клетка, по ред, най-много 64; null за празна клетка), shared. Изгледът е собствен на потребителя или споделен с тенанта (views:manage за запазване, промяна или изтриване). Собствените изгледи на друг потребител връщат 404.

Инсталатори на конектора​

  • GET /tenants/{tenantID}/connector-release (nvrs:manage) връща най-новото издание на конектора от SPHERE_CONNECTOR_UPDATE_CHANNEL, ConnectorRelease: {version, channel, sha256, size_bytes, notes, created_at, download_url, download_expires_at}. download_url не изисква вход и работи един час; всяко извикване създава нова връзка. 404, когато няма съхранено издание (или изданията са изключени). Изтегляне на конектора го използва.
  • Новите токени за регистриране (POST /tenants/{tenantID}/enrollment-tokens) носят същия вид връзка в download_url, когато има съхранено издание, иначе SPHERE_CONNECTOR_DOWNLOAD_URL (може да е празно).

Самите инсталатори се обслужват от API за изданията, /api/releases/v1 (https://hub.entrosity.com/sphere/api/releases/v1), извън /api/v1 и неговото влизане:

Метод и пътПредназначение
POST /connector?version=&channel=&notes=CI качва версия: тялото е MSI (до 64 MiB), Authorization: Bearer <SPHERE_RELEASE_TOKEN>, channel е stable (по подразбиране) или dev. 201 {id, version, channel, sha256, size_bytes, created_at}; 401 грешен токен; 409 release_exists (версията вече е публикувана); 422 невалидна версия, канал или размер; 503 releases_disabled (няма SPHERE_RELEASE_SIGNING_KEY).
GET /connector/{releaseID}/{file}?t=<link token>Изтегля инсталатора (application/x-msi, sphere-connector-<version>.msi). t е срок на валидност и HMAC; грешна или изтекла връзка връща 404.

Настройка и разпространение: Работа с Entrosity Sphere → Издания на конектора.

Чувствителни действия​

Окончателното изтриване на токен за регистриране (POST /tenants/{tenantID}/enrollment-tokens/{tokenID}/delete) е за глобалните администратори и изисква step_up_token: Hub го издава срещу паролата на администратора (POST /api/platform/v1/auth/step-up, продукт sphere, API на Hub).