From 78fc090360d447d71d3e22d1edf31ee86ab41986 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=95=9C=EC=84=B1=EC=9D=BC?= Date: Thu, 25 Jun 2026 16:37:57 +0900 Subject: [PATCH] =?UTF-8?q?=EC=B4=88=EA=B8=B0=20=EC=BB=A4=EB=B0=8B:=20?= =?UTF-8?q?=EC=8A=A4=ED=85=8C=EC=9D=B4=EC=85=98(=EC=B8=A1=EC=A0=90)=20?= =?UTF-8?q?=EA=B8=B0=EB=B0=98=20=EC=A3=BC=ED=96=89=EC=98=81=EC=83=81=20?= =?UTF-8?q?=ED=94=8C=EB=A0=88=EC=9D=B4=EC=96=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 클라이언트(React/Vite): Video.js 플레이어, 하단 스테이션바, POI/구조물 영상 오버레이, 카메라 파라미터 보정, 미니맵/RoutePanel - 서버(Express): Range 스트리밍, HLS 변환, 프레임 추출, tus 업로드, 주석 API - 최근 작업: 스테이션바 종점역 표출/양끝 정렬/미도착(재생불가) 표시, POI 라벨 '구분' 우선·컴팩트 팝업·겹침제외 토글·동일좌표 다중행, 진행방향(상/하) 우선 표출, 커서 배지 크기·픽셀 떨림 개선 Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude/settings.json | 14 + .gitignore | 36 + CLAUDE.md | 616 ++ PLAN.md | 282 + PROGRESS.md | 265 + README.md | 77 + VERIFICATION.md | 98 + .../2026-06-18_DefVideo-폴더구동-UI작업.md | 75 + agent-docs/2026-06-18_이슈별-해결정리.md | 108 + agent-docs/feature-folder-load.md | 358 + .../feature-stationbar-folder-driven.md | 64 + client/index.html | 19 + client/package.json | 39 + client/postcss.config.js | 6 + client/public/assets/background.jpg | Bin 0 -> 13278134 bytes client/public/assets/icons/ico_play.png | Bin 0 -> 4547 bytes client/public/assets/icons/ico_play_on.png | Bin 0 -> 4607 bytes .../public/assets/icons/icon-camera-body.png | Bin 0 -> 1061 bytes .../assets/icons/icon-camera-body_on.png | Bin 0 -> 1068 bytes client/public/assets/icons/icon-sturn.png | Bin 0 -> 1084 bytes client/public/assets/icons/icon-sturn_on.png | Bin 0 -> 1079 bytes client/public/assets/icons/icon_pause.png | Bin 0 -> 4245 bytes client/public/assets/icons/icon_pause_on.png | Bin 0 -> 4361 bytes client/public/assets/icons/icon_stop.png | Bin 0 -> 3450 bytes client/public/assets/icons/icon_stop_on.png | Bin 0 -> 3721 bytes client/public/assets/minimap.png | Bin 0 -> 509379 bytes .../bridge/bridge-passed-center.png | Bin 0 -> 718 bytes .../bridge/bridge-passed-left.png | Bin 0 -> 957 bytes .../bridge/bridge-passed-right.png | Bin 0 -> 961 bytes .../bridge/bridge-revisit-center.png | Bin 0 -> 208 bytes .../bridge/bridge-revisit-left.png | Bin 0 -> 526 bytes .../bridge/bridge-revisit-right.png | Bin 0 -> 505 bytes .../bridge/bridge-upcoming-center.png | Bin 0 -> 649 bytes .../bridge/bridge-upcoming-left.png | Bin 0 -> 930 bytes .../bridge/bridge-upcoming-right.png | Bin 0 -> 898 bytes .../route-segment/terminal/circle-passed.png | Bin 0 -> 1375 bytes .../route-segment/terminal/circle-revisit.png | Bin 0 -> 946 bytes .../terminal/circle-upcoming.png | Bin 0 -> 1352 bytes .../tunnel/tunnel-passed-center.png | Bin 0 -> 515 bytes .../tunnel/tunnel-passed-left.png | Bin 0 -> 2050 bytes .../tunnel/tunnel-passed-right.png | Bin 0 -> 2023 bytes .../tunnel/tunnel-revisit-center.png | Bin 0 -> 466 bytes .../tunnel/tunnel-revisit-left.png | Bin 0 -> 2019 bytes .../tunnel/tunnel-revisit-right.png | Bin 0 -> 2092 bytes .../tunnel/tunnel-upcoming-center.png | Bin 0 -> 466 bytes .../tunnel/tunnel-upcoming-left.png | Bin 0 -> 2019 bytes .../tunnel/tunnel-upcoming-right.png | Bin 0 -> 2092 bytes client/public/assets/title-panel-bg@2x.png | Bin 0 -> 570191 bytes client/src/App.tsx | 187 + client/src/components/AddAnnotationModal.tsx | 83 + client/src/components/ErrorBoundary.tsx | 22 + client/src/components/HelpOverlay.tsx | 40 + client/src/components/geo/GeoSearch.tsx | 267 + client/src/components/geo/StationVerify.tsx | 147 + client/src/components/overlay/MemoOverlay.tsx | 111 + .../components/overlay/RouteInfo.module.css | 117 + .../components/overlay/RouteInfoOverlay.tsx | 94 + client/src/components/overlay/RoutePanel.tsx | 363 + .../src/components/overlay/StationOverlay.tsx | 1637 +++ .../components/player/FrameCaptureButton.tsx | 15 + .../components/player/HlsConversionStatus.tsx | 63 + client/src/components/player/VideoPlayer.tsx | 458 + .../components/sidebar/AnnotationPanel.tsx | 86 + client/src/components/sidebar/CaptureList.tsx | 62 + client/src/components/sidebar/VideoList.tsx | 46 + client/src/hooks/useAnnotations.ts | 61 + client/src/hooks/useFrameStep.ts | 73 + client/src/hooks/useKeyboard.ts | 113 + client/src/hooks/useVideoPlayer.ts | 168 + client/src/index.css | 20 + client/src/main.tsx | 13 + client/src/stationbar/StationBar.module.scss | 43 + client/src/stationbar/StationBar.tsx | 782 ++ .../MileageMarker/MileageMarker.module.scss | 21 + .../MileageMarker/MileageMarker.tsx | 22 + .../PlaybackControls.module.scss | 307 + .../PlaybackControls/PlaybackControls.tsx | 98 + .../RouteSegment/RouteSegment.module.scss | 107 + .../components/RouteSegment/RouteSegment.tsx | 34 + .../TerminalMarker/TerminalMarker.module.scss | 8 + .../TerminalMarker/TerminalMarker.tsx | 28 + .../components/Timeline/Timeline.module.scss | 320 + .../components/Timeline/Timeline.tsx | 378 + .../TimelineCursor/TimelineCursor.module.scss | 75 + .../TimelineCursor/TimelineCursor.tsx | 20 + .../constants/routeSegmentAssets.ts | 18 + client/src/stationbar/mocks/mileage.ts | 15 + client/src/stationbar/mocks/route.ts | 164 + client/src/stationbar/mocks/routeInfo.ts | 6 + client/src/stationbar/mocks/segments.ts | 95 + client/src/stationbar/mocks/timeline.ts | 56 + client/src/stationbar/tokens.css | 26 + client/src/stationbar/types/timeline.ts | 106 + client/src/stationbar/utils/asset.ts | 8 + client/src/stationbar/utils/cssVars.ts | 13 + client/src/stationbar/utils/mileage.ts | 62 + client/src/stationbar/utils/mileageMarkers.ts | 26 + client/src/stationbar/utils/routeProgress.ts | 62 + client/src/stationbar/utils/segmentLabel.ts | 13 + client/src/store/annotationStore.ts | 25 + client/src/store/captureStore.ts | 23 + client/src/store/geoStore.ts | 113 + client/src/store/playerStore.ts | 56 + client/src/store/settingsStore.ts | 70 + client/src/types/dom.d.ts | 25 + client/src/types/geo.ts | 171 + client/src/types/player.ts | 16 + client/src/utils/frameCapture.ts | 21 + client/src/utils/geoData.ts | 848 ++ client/src/utils/geoProjection.ts | 427 + client/src/utils/geoSearch.ts | 255 + client/src/utils/timecode.ts | 28 + client/src/vite-env.d.ts | 3 + client/tailwind.config.js | 8 + client/tsconfig.json | 24 + client/tsconfig.node.json | 10 + client/vite.config.ts | 41 + .../2026-04-01_RoutePanel-미니맵-추가.md | 37 + .../2026-04-01_StationOverlay-렌더링분석.md | 32 + .../2026-04-01_StationOverlay-렌더링최적화.md | 52 + docs/history/2026-04-01_history-hooks-적용.md | 40 + ...-04-02_프레임동기화-렌더링최적화-터널링.md | 53 + ...026-06-15_동영상-로드실패-서버중지-복구.md | 27 + docs/history/2026-06-19_v2.0-import전환.md | 76 + docs/history/2026-06-19_시설종별-필터.md | 84 + docs/history/2026-06-22_POI투영오차-개선.md | 742 ++ ..._특허발굴-스테이션기반플레이어-HTML작성.md | 43 + ...2026-06-23_LX-한국국토정보공사-특허조사.md | 29 + ...26-06-23_드론경로-맨앞오차-슬라이더상한.md | 60 + .../2026-06-23_드론궤적-연속선-부드럽게.md | 32 + .../2026-06-23_선궤적-60fps보간-부드럽게.md | 35 + ...26-06-23_특허선행기술조사-글로벌+KIPRIS.md | 38 + .../2026-06-23_화면표시-기본값-반영.md | 30 + docs/history/2026-06-23_화면표시옵션-분리.md | 111 + .../2026-06-24_0926_교량-영상라벨-표출.md | 40 + ...06-24_0941_화면표시옵션-기본값버튼-툴팁.md | 47 + ...026-06-24_0948_POI거리필터-단일범위통합.md | 30 + ...회전시-선오버레이-지연어긋남-적응형평활.md | 39 + ...06-24_1002_회전종료후-선튐-에지보존평활.md | 39 + ...6-06-24_1019_라벨-재생즉시표시-증분게시.md | 41 + ...06-24_1026_라벨-영상첫프레임이후-게이트.md | 42 + ...토리파일명-시간추가-및-POI원근현상-분석.md | 33 + ...4_1051_라벨-멀리뒤로-가까이먼저-FOV진단.md | 31 + ...06-24_1106_오버레이-objectfit-cover정렬.md | 45 + .../2026-06-24_1117_1클릭-FOV초점-보정.md | 47 + ...026-06-24_1129_세로화각보정-sensorH전환.md | 35 + ...6-24_1137_POI높이-지면고도기준-기본전환.md | 35 + .../2026-06-24_1150_라벨정보-클릭팝업.md | 40 + ...6-06-24_1159_라벨정보-항상활성-호버커서.md | 38 + ...-06-24_1212_라벨팝업-다중-추적-클릭동작.md | 47 + .../2026-06-24_1213_폴더선택불가-회귀수정.md | 28 + .../2026-06-24_1220_팝업-라벨아래-글자클릭.md | 29 + ...026-06-24_1225_팝업-라벨사라짐동기-제거.md | 34 + ...6-06-24_1343_라벨-연속포즈투영-부드럽게.md | 36 + .../2026-06-24_1441_출입문-영상표출.md | 33 + ...2026-06-24_1453_POI팝업-원본CSV속성표시.md | 38 + .../2026-06-24_1500_팝업-KML속성만표시.md | 20 + ...2026-06-24_1603_KMZ직접로딩-CSV중복제거.md | 38 + ...24_1630_KMZ-KAKAO_RAIL-스테이션바라우팅.md | 36 + ...1647_새KML형식파싱+스테이션바구조물팝업.md | 43 + ..._1703_철도역-영상POI+스테이션바양쪽표출.md | 39 + .../2026-06-24_1749_POI라벨-구분title우선.md | 23 + ...758_라벨팝업-속도적응평활-1배속떨림제거.md | 33 + ...26-06-24_1806_평활튜닝-패널슬라이더노출.md | 24 + ...24_1921_스테이션바-구조물명2줄+양끝정렬.md | 34 + ...1933_스테이션바-첫마지막항목-바양끝스냅.md | 27 + ...테이션바라벨-아이콘가운데정렬+폰트복원.md | 23 + ...6-06-24_2004_측점-root허용+필수파일정리.md | 30 + ...6-06-24_2025_라벨폭1줄확대+팝업물결제거.md | 24 + ...032_스테이션바시종점-routejson-name분리.md | 35 + ...-startend역명+구조물스냅제거+종점안잘림.md | 28 + ...9_스테이션바-종점역-대전조차장-누락수정.md | 38 + ...0_스테이션바-첫끝역-양끝고정-및-pm2배포.md | 27 + ...06-25_1010_스테이션바-라벨-2줄-균등분할.md | 27 + ...30_POI라벨-구분-시설등급기타-컴팩트팝업.md | 26 + docs/발명신고서_측점표고정합_역투영보정.html | 313 + docs/스테이션바_대전조차장_미도착_표현안.png | Bin 0 -> 42435 bytes docs/스테이션바_미도착폭_3옵션.png | Bin 0 -> 44241 bytes docs/스테이션바_양끝정렬_3방식_비교.png | Bin 0 -> 61829 bytes .../스테이션바_재생불가_철재빗금_미리보기.png | Bin 0 -> 15221 bytes docs/특허_스테이션기반_주행영상_플레이어.html | 564 + docs/특허_추출_프롬프트.md | 48 + ecosystem.config.js | 28 + package-lock.json | 9667 +++++++++++++++++ package.json | 33 + pythonsource/advanced_tuner_v2.py | 560 + .../하행)회덕-대전조차장_POI_XY값.csv | 41 + .../하행)회덕-대전조차장_POI_위경도값.csv | 41 + ...)회덕-대전조차장_POI_위경도값_타원체고.csv | 41 + pythonsource/input/center.csv | 225 + pythonsource/streamlined_tuner.spec | 45 + server/nohup.out | 0 server/package.json | 31 + server/src/app.ts | 111 + server/src/config.ts | 15 + server/src/middleware/security.ts | 33 + server/src/routes/annotations.ts | 103 + server/src/routes/elevation.ts | 69 + server/src/routes/frame.ts | 57 + server/src/routes/geo.ts | 94 + server/src/routes/hls.ts | 182 + server/src/routes/meta.ts | 77 + server/src/routes/stream.ts | 16 + server/src/routes/upload.ts | 201 + server/src/services/ffmpeg.ts | 120 + server/src/services/geoMatch.ts | 522 + server/src/services/storage.ts | 149 + server/src/services/streaming.ts | 78 + server/tsconfig.json | 18 + shared/package.json | 10 + shared/src/index.ts | 1 + shared/src/types.ts | 75 + shared/tsconfig.json | 14 + tsconfig.json | 12 + 214 files changed, 27897 insertions(+) create mode 100644 .claude/settings.json create mode 100644 .gitignore create mode 100755 CLAUDE.md create mode 100755 PLAN.md create mode 100755 PROGRESS.md create mode 100755 README.md create mode 100755 VERIFICATION.md create mode 100644 agent-docs/2026-06-18_DefVideo-폴더구동-UI작업.md create mode 100644 agent-docs/2026-06-18_이슈별-해결정리.md create mode 100644 agent-docs/feature-folder-load.md create mode 100644 agent-docs/feature-stationbar-folder-driven.md create mode 100644 client/index.html create mode 100644 client/package.json create mode 100644 client/postcss.config.js create mode 100755 client/public/assets/background.jpg create mode 100755 client/public/assets/icons/ico_play.png create mode 100755 client/public/assets/icons/ico_play_on.png create mode 100755 client/public/assets/icons/icon-camera-body.png create mode 100755 client/public/assets/icons/icon-camera-body_on.png create mode 100755 client/public/assets/icons/icon-sturn.png create mode 100755 client/public/assets/icons/icon-sturn_on.png create mode 100755 client/public/assets/icons/icon_pause.png create mode 100755 client/public/assets/icons/icon_pause_on.png create mode 100755 client/public/assets/icons/icon_stop.png create mode 100755 client/public/assets/icons/icon_stop_on.png create mode 100755 client/public/assets/minimap.png create mode 100755 client/public/assets/route-segment/bridge/bridge-passed-center.png create mode 100755 client/public/assets/route-segment/bridge/bridge-passed-left.png create mode 100755 client/public/assets/route-segment/bridge/bridge-passed-right.png create mode 100755 client/public/assets/route-segment/bridge/bridge-revisit-center.png create mode 100755 client/public/assets/route-segment/bridge/bridge-revisit-left.png create mode 100755 client/public/assets/route-segment/bridge/bridge-revisit-right.png create mode 100755 client/public/assets/route-segment/bridge/bridge-upcoming-center.png create mode 100755 client/public/assets/route-segment/bridge/bridge-upcoming-left.png create mode 100755 client/public/assets/route-segment/bridge/bridge-upcoming-right.png create mode 100755 client/public/assets/route-segment/terminal/circle-passed.png create mode 100755 client/public/assets/route-segment/terminal/circle-revisit.png create mode 100755 client/public/assets/route-segment/terminal/circle-upcoming.png create mode 100755 client/public/assets/route-segment/tunnel/tunnel-passed-center.png create mode 100755 client/public/assets/route-segment/tunnel/tunnel-passed-left.png create mode 100755 client/public/assets/route-segment/tunnel/tunnel-passed-right.png create mode 100755 client/public/assets/route-segment/tunnel/tunnel-revisit-center.png create mode 100755 client/public/assets/route-segment/tunnel/tunnel-revisit-left.png create mode 100755 client/public/assets/route-segment/tunnel/tunnel-revisit-right.png create mode 100755 client/public/assets/route-segment/tunnel/tunnel-upcoming-center.png create mode 100755 client/public/assets/route-segment/tunnel/tunnel-upcoming-left.png create mode 100755 client/public/assets/route-segment/tunnel/tunnel-upcoming-right.png create mode 100755 client/public/assets/title-panel-bg@2x.png create mode 100644 client/src/App.tsx create mode 100644 client/src/components/AddAnnotationModal.tsx create mode 100644 client/src/components/ErrorBoundary.tsx create mode 100644 client/src/components/HelpOverlay.tsx create mode 100644 client/src/components/geo/GeoSearch.tsx create mode 100644 client/src/components/geo/StationVerify.tsx create mode 100644 client/src/components/overlay/MemoOverlay.tsx create mode 100644 client/src/components/overlay/RouteInfo.module.css create mode 100644 client/src/components/overlay/RouteInfoOverlay.tsx create mode 100644 client/src/components/overlay/RoutePanel.tsx create mode 100644 client/src/components/overlay/StationOverlay.tsx create mode 100644 client/src/components/player/FrameCaptureButton.tsx create mode 100644 client/src/components/player/HlsConversionStatus.tsx create mode 100644 client/src/components/player/VideoPlayer.tsx create mode 100644 client/src/components/sidebar/AnnotationPanel.tsx create mode 100644 client/src/components/sidebar/CaptureList.tsx create mode 100644 client/src/components/sidebar/VideoList.tsx create mode 100644 client/src/hooks/useAnnotations.ts create mode 100644 client/src/hooks/useFrameStep.ts create mode 100644 client/src/hooks/useKeyboard.ts create mode 100644 client/src/hooks/useVideoPlayer.ts create mode 100644 client/src/index.css create mode 100644 client/src/main.tsx create mode 100755 client/src/stationbar/StationBar.module.scss create mode 100755 client/src/stationbar/StationBar.tsx create mode 100755 client/src/stationbar/components/MileageMarker/MileageMarker.module.scss create mode 100755 client/src/stationbar/components/MileageMarker/MileageMarker.tsx create mode 100755 client/src/stationbar/components/PlaybackControls/PlaybackControls.module.scss create mode 100755 client/src/stationbar/components/PlaybackControls/PlaybackControls.tsx create mode 100755 client/src/stationbar/components/RouteSegment/RouteSegment.module.scss create mode 100755 client/src/stationbar/components/RouteSegment/RouteSegment.tsx create mode 100755 client/src/stationbar/components/TerminalMarker/TerminalMarker.module.scss create mode 100755 client/src/stationbar/components/TerminalMarker/TerminalMarker.tsx create mode 100755 client/src/stationbar/components/Timeline/Timeline.module.scss create mode 100755 client/src/stationbar/components/Timeline/Timeline.tsx create mode 100755 client/src/stationbar/components/TimelineCursor/TimelineCursor.module.scss create mode 100755 client/src/stationbar/components/TimelineCursor/TimelineCursor.tsx create mode 100755 client/src/stationbar/constants/routeSegmentAssets.ts create mode 100755 client/src/stationbar/mocks/mileage.ts create mode 100755 client/src/stationbar/mocks/route.ts create mode 100755 client/src/stationbar/mocks/routeInfo.ts create mode 100755 client/src/stationbar/mocks/segments.ts create mode 100755 client/src/stationbar/mocks/timeline.ts create mode 100755 client/src/stationbar/tokens.css create mode 100755 client/src/stationbar/types/timeline.ts create mode 100755 client/src/stationbar/utils/asset.ts create mode 100755 client/src/stationbar/utils/cssVars.ts create mode 100755 client/src/stationbar/utils/mileage.ts create mode 100755 client/src/stationbar/utils/mileageMarkers.ts create mode 100755 client/src/stationbar/utils/routeProgress.ts create mode 100755 client/src/stationbar/utils/segmentLabel.ts create mode 100644 client/src/store/annotationStore.ts create mode 100644 client/src/store/captureStore.ts create mode 100644 client/src/store/geoStore.ts create mode 100644 client/src/store/playerStore.ts create mode 100644 client/src/store/settingsStore.ts create mode 100644 client/src/types/dom.d.ts create mode 100644 client/src/types/geo.ts create mode 100644 client/src/types/player.ts create mode 100644 client/src/utils/frameCapture.ts create mode 100644 client/src/utils/geoData.ts create mode 100644 client/src/utils/geoProjection.ts create mode 100644 client/src/utils/geoSearch.ts create mode 100644 client/src/utils/timecode.ts create mode 100644 client/src/vite-env.d.ts create mode 100644 client/tailwind.config.js create mode 100644 client/tsconfig.json create mode 100644 client/tsconfig.node.json create mode 100644 client/vite.config.ts create mode 100644 docs/history/2026-04-01_RoutePanel-미니맵-추가.md create mode 100644 docs/history/2026-04-01_StationOverlay-렌더링분석.md create mode 100644 docs/history/2026-04-01_StationOverlay-렌더링최적화.md create mode 100644 docs/history/2026-04-01_history-hooks-적용.md create mode 100644 docs/history/2026-04-02_프레임동기화-렌더링최적화-터널링.md create mode 100644 docs/history/2026-06-15_동영상-로드실패-서버중지-복구.md create mode 100644 docs/history/2026-06-19_v2.0-import전환.md create mode 100644 docs/history/2026-06-19_시설종별-필터.md create mode 100644 docs/history/2026-06-22_POI투영오차-개선.md create mode 100644 docs/history/2026-06-22_특허발굴-스테이션기반플레이어-HTML작성.md create mode 100644 docs/history/2026-06-23_LX-한국국토정보공사-특허조사.md create mode 100644 docs/history/2026-06-23_드론경로-맨앞오차-슬라이더상한.md create mode 100644 docs/history/2026-06-23_드론궤적-연속선-부드럽게.md create mode 100644 docs/history/2026-06-23_선궤적-60fps보간-부드럽게.md create mode 100644 docs/history/2026-06-23_특허선행기술조사-글로벌+KIPRIS.md create mode 100644 docs/history/2026-06-23_화면표시-기본값-반영.md create mode 100644 docs/history/2026-06-23_화면표시옵션-분리.md create mode 100644 docs/history/2026-06-24_0926_교량-영상라벨-표출.md create mode 100644 docs/history/2026-06-24_0941_화면표시옵션-기본값버튼-툴팁.md create mode 100644 docs/history/2026-06-24_0948_POI거리필터-단일범위통합.md create mode 100644 docs/history/2026-06-24_0957_회전시-선오버레이-지연어긋남-적응형평활.md create mode 100644 docs/history/2026-06-24_1002_회전종료후-선튐-에지보존평활.md create mode 100644 docs/history/2026-06-24_1019_라벨-재생즉시표시-증분게시.md create mode 100644 docs/history/2026-06-24_1026_라벨-영상첫프레임이후-게이트.md create mode 100644 docs/history/2026-06-24_1043_히스토리파일명-시간추가-및-POI원근현상-분석.md create mode 100644 docs/history/2026-06-24_1051_라벨-멀리뒤로-가까이먼저-FOV진단.md create mode 100644 docs/history/2026-06-24_1106_오버레이-objectfit-cover정렬.md create mode 100644 docs/history/2026-06-24_1117_1클릭-FOV초점-보정.md create mode 100644 docs/history/2026-06-24_1129_세로화각보정-sensorH전환.md create mode 100644 docs/history/2026-06-24_1137_POI높이-지면고도기준-기본전환.md create mode 100644 docs/history/2026-06-24_1150_라벨정보-클릭팝업.md create mode 100644 docs/history/2026-06-24_1159_라벨정보-항상활성-호버커서.md create mode 100644 docs/history/2026-06-24_1212_라벨팝업-다중-추적-클릭동작.md create mode 100644 docs/history/2026-06-24_1213_폴더선택불가-회귀수정.md create mode 100644 docs/history/2026-06-24_1220_팝업-라벨아래-글자클릭.md create mode 100644 docs/history/2026-06-24_1225_팝업-라벨사라짐동기-제거.md create mode 100644 docs/history/2026-06-24_1343_라벨-연속포즈투영-부드럽게.md create mode 100644 docs/history/2026-06-24_1441_출입문-영상표출.md create mode 100644 docs/history/2026-06-24_1453_POI팝업-원본CSV속성표시.md create mode 100644 docs/history/2026-06-24_1500_팝업-KML속성만표시.md create mode 100644 docs/history/2026-06-24_1603_KMZ직접로딩-CSV중복제거.md create mode 100644 docs/history/2026-06-24_1630_KMZ-KAKAO_RAIL-스테이션바라우팅.md create mode 100644 docs/history/2026-06-24_1647_새KML형식파싱+스테이션바구조물팝업.md create mode 100644 docs/history/2026-06-24_1703_철도역-영상POI+스테이션바양쪽표출.md create mode 100644 docs/history/2026-06-24_1749_POI라벨-구분title우선.md create mode 100644 docs/history/2026-06-24_1758_라벨팝업-속도적응평활-1배속떨림제거.md create mode 100644 docs/history/2026-06-24_1806_평활튜닝-패널슬라이더노출.md create mode 100644 docs/history/2026-06-24_1921_스테이션바-구조물명2줄+양끝정렬.md create mode 100644 docs/history/2026-06-24_1933_스테이션바-첫마지막항목-바양끝스냅.md create mode 100644 docs/history/2026-06-24_1939_스테이션바라벨-아이콘가운데정렬+폰트복원.md create mode 100644 docs/history/2026-06-24_2004_측점-root허용+필수파일정리.md create mode 100644 docs/history/2026-06-24_2025_라벨폭1줄확대+팝업물결제거.md create mode 100644 docs/history/2026-06-24_2032_스테이션바시종점-routejson-name분리.md create mode 100644 docs/history/2026-06-24_2040_시종점-startend역명+구조물스냅제거+종점안잘림.md create mode 100644 docs/history/2026-06-25_0909_스테이션바-종점역-대전조차장-누락수정.md create mode 100644 docs/history/2026-06-25_0950_스테이션바-첫끝역-양끝고정-및-pm2배포.md create mode 100644 docs/history/2026-06-25_1010_스테이션바-라벨-2줄-균등분할.md create mode 100644 docs/history/2026-06-25_1130_POI라벨-구분-시설등급기타-컴팩트팝업.md create mode 100644 docs/발명신고서_측점표고정합_역투영보정.html create mode 100644 docs/스테이션바_대전조차장_미도착_표현안.png create mode 100644 docs/스테이션바_미도착폭_3옵션.png create mode 100644 docs/스테이션바_양끝정렬_3방식_비교.png create mode 100644 docs/스테이션바_재생불가_철재빗금_미리보기.png create mode 100644 docs/특허_스테이션기반_주행영상_플레이어.html create mode 100644 docs/특허_추출_프롬프트.md create mode 100755 ecosystem.config.js create mode 100644 package-lock.json create mode 100755 package.json create mode 100644 pythonsource/advanced_tuner_v2.py create mode 100644 pythonsource/input/building/하행)회덕-대전조차장_POI_XY값.csv create mode 100644 pythonsource/input/building/하행)회덕-대전조차장_POI_위경도값.csv create mode 100644 pythonsource/input/building/하행)회덕-대전조차장_POI_위경도값_타원체고.csv create mode 100644 pythonsource/input/center.csv create mode 100644 pythonsource/streamlined_tuner.spec create mode 100644 server/nohup.out create mode 100644 server/package.json create mode 100644 server/src/app.ts create mode 100644 server/src/config.ts create mode 100644 server/src/middleware/security.ts create mode 100644 server/src/routes/annotations.ts create mode 100644 server/src/routes/elevation.ts create mode 100644 server/src/routes/frame.ts create mode 100644 server/src/routes/geo.ts create mode 100644 server/src/routes/hls.ts create mode 100644 server/src/routes/meta.ts create mode 100644 server/src/routes/stream.ts create mode 100644 server/src/routes/upload.ts create mode 100644 server/src/services/ffmpeg.ts create mode 100644 server/src/services/geoMatch.ts create mode 100644 server/src/services/storage.ts create mode 100644 server/src/services/streaming.ts create mode 100644 server/tsconfig.json create mode 100644 shared/package.json create mode 100644 shared/src/index.ts create mode 100644 shared/src/types.ts create mode 100644 shared/tsconfig.json create mode 100755 tsconfig.json diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..2e3727a --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,14 @@ +{ + "permissions": { + "allow": [ + "Bash(cd ~/projects/gitea/b23042/import_data/v2.0/ 2>/dev/null && ls -la && echo \"===\" && ls -la \"하행\\)회덕-대전조차장 데이터\\(v2.0\\)\" 2>/dev/null | head -50)", + "Read(//home/hanmac/projects/gitea/b23042/import_data/v2.0/**)", + "Bash(ls node_modules/proj4)", + "Bash(cp /tmp/chk.mjs ./chk.mjs)", + "Bash(node ./chk.mjs)", + "Bash(rm -f ./chk.mjs)", + "Bash(ls -la \"/mnt/c/Users/User/Pictures/Screenshots/\" 2>/dev/null | tail -10 || echo \"no /mnt/c path\")", + "Read(//mnt/c/Users/User/Pictures/Screenshots/**)" + ] + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fed1682 --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +# 의존성 +node_modules/ + +# 빌드 산출물 +client/dist/ +server/dist/ +shared/dist/ +dist/ +*.tsbuildinfo + +# 파이썬 빌드 산출물 (exe/pkg/pyz 등) +pythonsource/build/ +pythonsource/dist/ +__pycache__/ +*.pyc + +# 런타임 저장소 (영상/HLS/프레임/썸네일/DB) +storage/ + +# 대용량 미디어/바이너리 +*.mp4 +*.MP4 +*.avi +*.mov +*.mkv +*.exe + +# 로그/환경 +*.log +.env +.env.* +npm-debug.log* + +# OS/에디터 +.DS_Store +Thumbs.db diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100755 index 0000000..20f2e0e --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,616 @@ +# CLAUDE.md — abcvideo 프로젝트 + +이 파일은 Claude Code가 abcvideo 프로젝트에서 작업할 때 참조하는 가이드입니다. + +--- + +## 응답/소통 규칙 (항상 적용) + +- **모든 답변은 한글로 작성한다.** (코드·로그·식별자 등 원문 유지가 필요한 부분은 예외) +- 보고는 결론 → 근거 → 다음 행동 순으로 간결하게. + +--- + +## 작업 완료 시 필수 — 히스토리 기록 + +작업(대화 세션)이 끝날 때 반드시 아래 형식으로 히스토리 파일을 작성한다. + +``` +파일 경로: docs/history/YYYY-MM-DD_HHMM_{작업명}.md +``` + +필수 항목 (누락 시 Stop 훅이 응답을 차단함): + +```markdown +**소요 시간**: X분 +**Context 사용량**: input Xk / output Xk tokens +``` + +- 날짜는 오늘 날짜(YYYY-MM-DD), 시간은 작업 완료 시각 24시간제(HHMM), 작업명은 작업 내용을 한글 또는 영문으로 간략히 +- 같은 날 여러 작업이면 각각 별도 파일 (예: `2026-04-01_1430_StationOverlay-분석.md`) +- 소요 시간: 대화 시작부터 작업 완료까지의 실제 경과 시간 +- Context 사용량: 이 대화의 토큰 사용량 (모를 경우 추정값 기재) + +--- + +## 에이전트 협업 규칙 + +### 필수 파일 + +| 파일 | 용도 | 누가 관리 | +|------|------|----------| +| `CLAUDE.md` | 프로젝트 가이드 (아키텍처, 규칙, 기술 스택) | 사용자/아키텍트 | +| `PLAN.md` | 전체 구현 계획 + 각 단계별 세부 태스크 | 계획 수립 시 작성, 에이전트가 필요 시 업데이트 | +| `PROGRESS.md` | 각 단계의 진행 상태 + 완료/미완료/이슈 기록 | 작업하는 에이전트가 실시간 업데이트 | + +### 에이전트 작업 시작 프로토콜 + +모든 에이전트는 작업 시작 시 반드시 아래 순서를 따른다: + +``` +1. CLAUDE.md 읽기 → 프로젝트 규칙/아키텍처 파악 +2. PLAN.md 읽기 → 전체 계획에서 자신이 담당할 단계 확인 +3. PROGRESS.md 읽기 → 이전 단계 완료 여부, 현재 상태, 알려진 이슈 확인 +4. 작업 시작 전 PROGRESS.md에 자신의 단계를 "🔄 진행 중"으로 업데이트 +5. 작업 완료 후 PROGRESS.md에 결과 기록 (완료 항목, 남은 이슈, 다음 단계 참고사항) +``` + +### PLAN.md 구조 + +```markdown +# PLAN.md +## 단계 N: 단계 이름 +### 목표 +### 세부 태스크 +- [ ] 태스크 1 +- [ ] 태스크 2 +### 산출물 (완료 기준) +### 다음 단계 의존성 +``` + +- 각 단계는 독립적으로 실행 가능한 단위로 분할 +- 태스크는 체크박스(`- [ ]` / `- [x]`)로 관리 +- 완료 기준(산출물)이 명확해야 다음 에이전트가 판단 가능 + +### PROGRESS.md 구조 + +```markdown +# PROGRESS.md +## 현재 상태 요약 +- 마지막 완료 단계: N +- 현재 진행 단계: N+1 +- 블로커: (있으면 기록) + +## 단계별 진행 기록 +### 단계 N: 단계 이름 +- 상태: ✅ 완료 | 🔄 진행 중 | ⏳ 대기 | ❌ 실패 +- 완료일: YYYY-MM-DD +- 완료 항목: + - 항목 1 + - 항목 2 +- 미완료/이슈: + - 이슈 설명 +- 다음 단계 참고: + - 후속 에이전트가 알아야 할 사항 +``` + +- 에이전트는 작업 중 **의미 있는 마일스톤마다** PROGRESS.md를 업데이트 +- 실패 시 원인과 시도한 방법을 기록하여 다음 에이전트가 같은 실수를 반복하지 않도록 함 +- 이전 에이전트가 남긴 "다음 단계 참고"를 반드시 확인 후 작업 시작 + +### 에이전트 간 인계 규칙 + +1. **이전 단계 산출물 검증**: 코드가 빌드/실행 가능한 상태인지 확인 후 작업 시작 +2. **기존 코드 존중**: 이전 에이전트가 작성한 코드를 이유 없이 대폭 변경하지 않음 +3. **충돌 방지**: 같은 파일을 동시에 수정하는 병렬 에이전트 실행 금지 +4. **이슈 에스컬레이션**: 블로커 발견 시 PROGRESS.md에 기록하고 사용자에게 보고 + +--- + +## 프로젝트 개요 + +웹 브라우저(PC)에서 **2GB 이상의 대용량 동영상**을 안정적으로 재생하는 특화 기능 탑재 플레이어. +단순 재생을 넘어 **프레임 추출, 단위 이동, 텍스트 오버레이** 등 영상 분석/편집 보조 도구로 기능. + +### 핵심 요구사항 + +1. 2GB 이상 동영상 안정 재생 (서버 파일 + 로컬 파일 모두) +2. 프레임 단위 추출 (정확도 우선) +3. 입력 단위 기준 앞뒤 이동 (프레임 / 초 / 장면) +4. 영상 위 텍스트 입력 (자막형 + 메모형 병행 지원) +5. 확장 가능한 플러그인 아키텍처 + +### 설계 결정 (2026-03-24 확정) + +| 항목 | 결정 | 비고 | +|------|------|------| +| 사용자 모델 | **단일 사용자 도구** | 인증/세션/큐 불필요, 구현 단순화 | +| 로컬 파일 | **업로드 없이 직접 재생** | File API → `URL.createObjectURL()` | +| 프레임 정확도 | **표준 수준** | CFR: `1/fps` 산술, VFR: best-effort | +| HLS 변환 전 재생 | **원본 즉시 재생** | Range Request로 바로 재생, HLS는 백그라운드 변환 | +| 브라우저 지원 | **PC 웹 우선** | Chrome/Firefox/Edge, iOS Safari 무시 | + +--- + +## 아키텍처 결정 (ADR) + +### 재생 이중 경로 + +``` +서버 파일: GET /api/stream/:videoId (Range Request) → 즉시 재생 + POST /api/hls/:videoId/convert → 백그라운드 HLS 변환 + HLS 준비 완료 시 → hls.js로 전환 (seek 안정성 향상) + +로컬 파일: File API → URL.createObjectURL() →