前言:
前面在寫ONVIF Client Lab時提到,在開發ONVIF相關的Side Project,其實就是NVR。
我回看PRD日期,最早大概從2026-03-21開始,也就是3月底左右,到現在2026-06-01,約2個多月的時間,有空閒就開發它,目前推測進度大概70%左右。
因為好一段時間了,雖然還沒有成果,但我想可以先把目前的規劃、實做進行描述。
因為架構比預期大,之後打算用Gitlab Page或Wiki讓AI撰寫系統架構、設計、Models之類的。
發想:
首先,這個NVR預計會是雙授權型式,AGPL與Commercial。
對的,AGPL開源與商用雙授權。
AGPL允許在不改程式碼的情況下,或者開源的情況下可以修改與使用,甚至以安裝方式提供商用服務,唯一要求就是開源。
Commercial,提供商用,但我還沒想清楚到底怎麼商用法。
會特別提的原因是,程式碼是開源的,但上面包括License設計和實做,對的,你沒看錯,程式碼開源還包括License設計與實做在裡面 😆,這在看到時可能覺得疑惑,怎麼要註冊,但是又有程式碼,授權又是AGPL。
我第一份工作就是NVR,負責Linux平台和整合,對NVR有設計的遺憾。
我原本以為自從中國成為監控大國之後,監控產業大概都趴了,在上幾份工作時寫停車場系統才發現,NVR對於公司竟然還是香噴噴的,因此,AI開發計畫中,就有NVR在裡面。
NVR完成後不會是這個Side Project的結束,後面會延續進一步推進Analysis Service以及GIS Service,最終目標是做出Dashboard,能像之前美國國防部記者會時的操作界面,有個地圖(戰場/非戰場)會有圖釘標示哪裡有攻擊(事件),滑鼠移動過去後點擊,會出現當時的影片片段。
當然,無人機這麼熱,不湊熱度說不過去,對吧。
設計規劃:
這次實做花很多時間的原因是,設計的架構比預期大和複雜。
後端系統以微服務設計,分為4部份:
- Streammer: 接Camera串流、分發串流
- Recorder: 錄影寫檔案
- Manager: CRUD服務,REST API和資料管理
- Gateway: 前端應用程式的對接口,後端接Streammer、Recorder、Manager
微服務的底層設計邏輯是,各自處理各自的事務,所有事務獨立,體現在幾個點:
調Record、查Record Status、Disk Status,都由Recorder處理
Camera介接、串流,都由Streammer處理
DB設定更新、CRUD API,都由Manager處理
和Client對接,Client的Protocol轉換,StreamBus -> WebSocket、gRPC <-> WebSocket、Manager反向代理,都由Gateway處理
主要設計邏輯和核心協定:
微服務(Streammer、Recorder、Manager、Gateway)間透過3個主要協定通訊:
- gRPC: REST API與WebSocket類的API,Playback的串流都透過gRPC傳輸
- 自定義的StreamBus Protocol: RTSP串流的訂閱轉發通訊協定
- MQTT Protocol (EventBus): Event的訂閱轉發協定使用MQTT為基底
各個微服務設計特點:
Streammer:
Streammer主要功能是轉發,包括串流和Event(事件),串流轉發使用StreamBus,Event轉發使用EventBus。
Streammer串流轉發的設計受到Publish/Subscribe設計和mediamtx影響,當然還有AI的建議,Streammer內部使用c#的Channels實做,但額外設計3種對外接口,分別是Named Pipeline、TCP、UDP,Streammer內的串流擴展可直接在內部透過StreamBus實做模塊擴展,Streammer外可以透過TCP、UDP、Named Pipeline串接,Gateway與Recorder就是用外部串接方式和Streammer對接。
Streammer Event轉發使用MQTT為基底,設計上,本身是MQTT Server,也可以用外部MQTT Server,Event則透過MQTT推送到MQTT Server上。
Streammer有gRPC Service服務,主要用於傳入CMD,例如:ReloadCamera,gRPC有Event Trigger API,但Event Trigger透過MQTT注入更方便,兩種都有設計,主要透過MQTT。
Recorder:
Recorder主要功能是錄影寫檔案。
但因為以前整合時吃了太多磁碟IO的虧,Recorder核心設計包括IndexCache、RecCache以及IOWorker。
Recorder包括3個Cache,Playback用的錄影檔案Cache,Index讀寫的LRU Cache,預錄影的RingBuffer Cache。
Recorder在Cache下層寫入磁碟時,會透過IOWorker Pool,IOWorker能在appsettings.json內設定同時的Read IOWorker數量、Write IOWorker數量,所有IO都透過IOWorker Pool動作。
Recorder設定時指定多個實體路徑寫入,透過Consistent Hashing(一致性哈希)平均分散資料到實體路徑內。
保留軟體RAID(Erasure Code)實做設計。
Manager:
Manager提供CRUD,Camera的增/刪/查/找,使用者登入認證都在這裡。前端應用程式的API,主要都是對Manager。有個比較特殊的,ONVIF Discovery是在Manager觸發和搜尋。
目前設定都透過DB儲存,原則上至少支援SQLite和PostgreSQL,Microsoft SQL Server有支援,但問題在於,c# SQL Server的SQLClient目前不完全支援AoT。
Gateway:
Gateway顧名思義,是入口。Client端連入會是透過Gateway,Web版的網站程式也會放在Gateway。
Gateway對Client就2個協定,WebSocket和REST API,REST API主要是反向代理到Manager,其他都透過WebSocket,像是Streammer的StreamBus,StreamBus -> WebSocket,Recorder的gRPC API,WebSocket <-> Recorder gRPC API。
認證有2組:
使用者的認證以及微服務間的認證。
使用者認證就是透過Manager的Auth API進行認證後拿到JWT,然後後續不論是WebSocket或是其他REST API都透過這組JWT。
微服務間的認證,在每個服務的appsettings.json內會有個Internal API Key,要填入相同的密碼,服務間的gRPC會用Internal API Key加密Timestamp後送出,另一端會用Internal API Key解密,並判斷Timestamp是否在一段時間內(是的,每個服務所在的電腦,要對時,我記得會查30秒內吧)。
License設計:
License會以線上登錄序號的方式,登錄註冊後提供license.lic檔案,放入系統中作用。
目前這段細節我還沒想清楚,目前考慮鎖在Streammer就好,但考慮到叢集多電腦微服務運作,我還沒完全想清楚授權怎麼處理。
License預設會有2種,一種是已經完成的license.lic,另一種是USB License Key的形式,不論哪種,核心加密都使用AES + ECDSA簽章。
使用者和群組設計:
DB中,包括幾個跟User有關的Table,包括users, groups, permissions這3個主要的Table以及用於Mapping group和permission的group_permissions Mapping Table。
權限可以概略分2類,1類是NVR操作的使用者權限,一類是MQTT的服務權限。
包括NVR類的:nvr_admin, nvr_power_user, nvr_user, nvr_viewer
以及MQTT類的:mqtt_admin, mqtt_rw, mqtt_ro
權限會對應到group,因此Group包括:
admins, power_users, users, operators, mqtt_services, mqtt_clients
每個使用者都屬於特定1個群組,但群組可以包括多種權限。
直接的體現是,admin這個使用者是admins群組,admins群組的帳號可以同時登入MQTT Server和NVR Client,同樣的道理,mqtt_services群組的成員,只能登入MQTT Server,NVR Client是不能登入的。
Client設計:
Client應用程式預計為跨平台,會先提供Linux版和網頁版,使用UNO Platform開發。
AI規劃:
設計階段就在想,既然是全新開發NVR,那有沒有什麼新的想法能夠引入?
尤其是AI,既然AI這麼熱門,到底使用者對於AI的想像是什麼? 如何引入?
在和AI討論後,目前想定的設計分2塊,NVR階段的以及Dashboard(中控)階段的。
我對AI之於應用程式的想像是這樣,我要如何如何時,直接跟AI說或對話,AI直接幫我處理,以及AI能夠跟我說發生了什麼事情。
也就是說,延續監控產業的一脈路線,什麼是監控產業的一脈路線?
從最傳統的能錄影 -> 能根據時間調出錄像 -> 有Event -> 能智能的根據Event主動通知
那麼,當進入AI時代後,我對這一脈路線的想定是,Event的通知對象不再是人,而是AI,由AI主動分析Event,並提供給人狀況、建議行為。
因此,我把AI規劃分為低階跟高階,高階放在Dashboard(中控),低階下放在NVR內。
NVR內放的AI,能夠根據文字窗口給與指示,
例如:
給我看第三支Camera目前畫面。
播放第2支Camera昨天下午3:00的錄像。
幫我看看,這兩天有哪些Camera斷線過?
而高階的,則能夠根據Event進行細部推斷,
例如:
目前分析系統偵測到大廳有多人聚集,或者大廳人數眾多。
而兩者差異體現在2塊,1個是AI的智能程度,NVR原則上用的就指令遵循型,能夠提供Live、Playback的自動化操作,而Dashboard(中控)的,就可能需串接雲端,提供目前過往的Event資訊,或者觸發Event時打到雲端AI,讓雲端AI能有完整的Event進行判斷。
我們更白話的說,AI的判斷能力,取決於我們給哪些Event + AI的智能程度,低階的做單純的UI操作,不具備分析,高階的能獲得更多Event訊息,並能深入分析。
目前NVR階段,已能在UNO Platform上面透過按鈕觸發特定連續頁面操作。
Client實做進展:
目前已實做和串接部份,錄影進度條已經能正常顯示,Event能正常顯示,Device清單能正常顯示,錄影狀態串接中。
Device Search功能正常,但UI還需優化,Schedule UI和設定正常。
PTZ能夠功能正常,UI還需優化。
影像部份,Linux版本Live有畫面,但穩定性還有問題。
Client截圖:






















