feat: 독립 카메라에 ONVIF PTZ 지원 추가 (프린터실 카메라 등록)

extra-cameras API/UI에 ptz·onvifPort 필드 추가하고, 프린터실 머큐시스 MC230
카메라를 PTZ 지원 독립 카메라로 등록.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PppKcQmeTJDQCpfcgKietu
This commit is contained in:
kim
2026-09-18 00:31:38 +09:00
co-authored by Claude Sonnet 5
parent 145f4e698f
commit d34dd10ba7
3 changed files with 19 additions and 3 deletions
+13 -1
View File
@@ -378,7 +378,19 @@
"channelStream": {
"3": 1
},
"extraCameras": []
"extraCameras": [
{
"id": 1000,
"label": "프린터실",
"host": "192.168.0.32",
"rtspPort": 554,
"username": "octoprint",
"password": "vault:nvr.extraCameras.1000.password",
"rtspPath": "/stream1",
"ptz": true,
"onvifPort": 2020
}
]
},
"writer": {
"providers": {}
+3 -1
View File
@@ -322,7 +322,7 @@ export function registerNvrRoutes(app: Express): void {
app.post('/api/nvr/extra-cameras', (req: Request, res: Response) => {
const user = (req as any).user;
if (!user) return res.status(401).json({ error: 'Unauthorized' });
const { label, host, rtspPort, username, password, rtspPath } = req.body || {};
const { label, host, rtspPort, username, password, rtspPath, ptz, onvifPort } = req.body || {};
if (!String(host || '').trim()) return res.status(400).json({ error: 'host is required' });
const cm = getConfig();
const cfg = cm.getConfig() as any;
@@ -338,6 +338,8 @@ export function registerNvrRoutes(app: Express): void {
username: String(username || '').trim(),
password: String(password || ''),
rtspPath: String(rtspPath || '/stream1').trim(),
ptz: ptz === true,
onvifPort: onvifPort ? Number(onvifPort) : 80,
};
cm.updateConfig({ nvr: { ...nvr, extraCameras: [...list, entry] } } as any);
res.json({ success: true, id: nextId });
+3 -1
View File
@@ -516,9 +516,11 @@ async function addExtraCamera(){
const username=prompt('RTSP 사용자명', 'camera');
const password=prompt('RTSP 비밀번호', '');
const rtspPath=prompt('RTSP 경로(메인 스트림)', '/stream1');
const ptz=confirm('이 카메라가 팬/틸트(PTZ)를 지원하나요?');
const onvifPort=ptz?(prompt('ONVIF 포트', '2020')||'2020'):'80';
try{
const r=await fetch('/api/nvr/extra-cameras',{method:'POST',headers:authH({'Content-Type':'application/json'}),
body:JSON.stringify({label,host,rtspPort:Number(rtspPort)||554,username,password,rtspPath})});
body:JSON.stringify({label,host,rtspPort:Number(rtspPort)||554,username,password,rtspPath,ptz,onvifPort:Number(onvifPort)||80})});
const d=await r.json();
if(!r.ok||!d.success) throw new Error(d.error||'추가 실패');
loadChannels();