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_limit | POST /streams: достигнато е ограничението на конектора или на видеорекордера за основни потоци или възпроизвеждания и никой неизползван поток на живо не може да спре, за да освободи място (Ограничения). |
nvr_offline | POST /streams, PTZ, търсене на записи: видеорекордерът не е свързан или не е online (също и докато конекторът му е офлайн). POST /nvrs/{nvrID}/tune-live: видеорекордерът не е свързан. |
camera_disabled | POST /streams: камерата е изключена. |
connector_offline | POST /nvrs/{nvrID}/test, POST /nvrs/{nvrID}/tune-live: конекторът на видеорекордера не е свързан. |
nvr_address_taken | Добавяне или промяна на видеорекордер: конекторът вече управлява видеорекордер на този хост и порт. |
connector_has_nvrs | Премахване на конектор, който още управлява видеорекордери. |
Всички кодове: Кодове на грешки.
Гледане на видео
Видеото не минава през API: API дава сесия на зрител с краткотраен токен, а браузърът възпроизвежда потока от медийния сървър по WebRTC (WHEP).
-
Отваряне:
POST /tenants/{tenantID}/streamsсcamera_idи:- на живо:
kind: "live"(по подразбиране) иprofilesub(по подразбиране, за решетки) илиmain(пълна резолюция); - запис:
kind: "playback",startиend(следstart, най-много 24 часа по-късно,startне в бъдещето).
Отговорът (201) е
StreamSession: неговиятid(сесията на зрителя), медийниятpath,whep_url,tokenиtoken_expires_at(пет минути) иstateиerrorна потока. - на живо:
-
Възпроизвеждане: изпратете WebRTC предложението (offer) към
whep_url(WHEP) сAuthorization: Bearer <token>. Токенът се проверява при отварянето на WHEP сесията и само за този път. -
Поддържане:
POST /tenants/{tenantID}/streams/{streamID}/keepaliveна всеки 15 секунди. Той връща отново сесията с текущото състояние и нов токен (използвайте го, ако плейърът трябва да се свърже отново). Зрител без keepalive от 45 секунди се премахва. -
Затваряне:
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}/test | sphere.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_live | NvrLiveTuneResult: {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, сpreset1–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– защо не (също когато видеорекордерът е приел стойност, която не е запазил). 422validationза другkeyframe_seconds, 409nvr_offline, когато видеорекордерът не е свързан, 409connector_offline, когато конекторът му е офлайн (Видеорекордери). - Паролите на видеорекордерите са само за запис:
POST /nvrsиPUT /nvrs/{nvrID}/credentialsги приемат и те никога не се връщат.
Обновления на живо
Приложението получава обновления на живо като server-sent events:
POST /auth/sse-token {"tenant_id": …}връща токен, валиден 60 секунди, обвързан с тенанта и сесията.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=¬es= | 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).