8 Commits
Author SHA1 Message Date
ncakanghanandClaude Opus 5 4be0235d2f 지문을 오디오 우선으로 — 네트워크 소스에서 읽는 양을 크게 줄인다
CI / windows-x64 (push) Canceled after 0s
CI / windows-arm64-cross (push) Canceled after 0s
CI / windows-arm64-native (push) Canceled after 0s
CI / macos (push) Canceled after 0s
26,000편(26TB, SMB) 라이브러리에서 지문 생성이 하루에 10%밖에 진행되지 않았다.
원인은 구조다: 프레임 지문을 만들려고 **파일을 처음부터 끝까지 읽는다**(실측 96.8%).
동시 실행을 2→8로 올려도 차이가 없었다 — 대역 병목이라 읽는 양을 줄이는 것 말고는 방법이 없다.

오디오 지문은 `-vn`으로 영상 청크를 건너뛰어 파일의 일부만 읽는다(컨테이너별 실측):
  mp4 0.4% · mov 0.4% · ts 0.3% · mkv 1.6%   ← 전체 패스 96.8%

그래서 3단계로 나눴다.
- ① 오디오 지문을 전 파일에 먼저 (sig_state=3). 26TB가 아니라 100~400GB를 읽는다.
- ② 저장된 지문으로 후보 쌍을 뽑아 걸린 파일을 표시 (sig_state=4). 파일을 읽지 않는다.
- ③ 프레임은 우선순위대로 — 오디오 짝 있음(4) → 소리 없음(0) → 짝 없음(3).
     중복일 가능성이 높은 것부터 처리하므로 결과가 며칠이 아니라 몇 분 뒤부터 나온다.

후보 판정은 탐지와 같은 함수(candidates_from_tokens)를 쓴다 — 규칙이 갈라지면
"지문 단계에서는 후보였는데 탐지에서는 아니다"는 설명 불가능한 상태가 생긴다.

측정으로 정한 것들:
- 오디오만으로는 그룹이 **0개**다(시각 확인이 프레임을 요구한다). ②③이 없으면 무의미하다.
- 오디오는 배속·피치 변화에 무너진다. 216개 토큰 중 공통:
    워터마크 216 · 레터박스 216 · 재인코딩 211 · 중간자르기 22/59
    1.25배속 3 · 피치+6% 8 · atempo1.05 40/205
  배속 사본은 프레임 경로가 뒤에서 채운다(그쪽에 배속 후보 로직이 있다).
  근거를 tests/audio_speed_evidence.rs에 고정했다.
- 절감 크기는 중복률에 비례한다. 픽스처는 10편 중 8편이 파생 사본이라 20%만 줄지만,
  실제 라이브러리에서 짝이 5%면 26TB가 1.4TB가 된다. 그 비율은 ②가 로그로 알려준다.

함께 고친 것 — 편집 백업이 영구히 쌓이던 문제
- 자르기·반전은 원본을 .archive_trash/edits에 남기는데 지우는 코드가 없었다.
  되돌리기는 최근 배치만 보므로 그 창을 벗어난 백업은 되돌릴 수도 없이 자리만 차지했다.
  미디어 드라이브에 쌓이므로 영상 라이브러리에서는 수십 GB가 된다.
- 창(20배치)을 벗어난 것만 지운다. 앱 시작 시·편집할 때마다·사이드바 버튼으로 돈다.
- 백업이 사라진 배치는 되돌리기 후보에서 뺀다 — Ctrl+Z가 조용히 실패하면 이유를 알 수 없다.
- 사이드바 정리 영역에 「편집 백업 N개 · N MB」로 용량을 노출한다.

빌드: profile.dev에서 의존성 디버그 정보를 뺐다(PDB 200여 개가 시간·디스크를 크게 먹는다).
자체 크레이트는 line-tables-only — 패닉 위치는 그대로 안다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 18:04:23 +09:00
ncakanghanandClaude Opus 5 8aa74c1a8d 영상 중복 탐지 완성 + 간단 편집(회전·자르기) + 동시 재생 + 별점·태그 세트
CI / windows-x64 (push) Canceled after 0s
CI / windows-arm64-cross (push) Canceled after 0s
CI / windows-arm64-native (push) Canceled after 0s
CI / macos (push) Canceled after 0s
중복 탐지
- 이미지 근접쌍 밴드 색인 + 스트리밍 클러스터, 후보 검증(타일 다수결·크롭 해시)
- 색 지문으로 색만 다른 오탐 제거, 회전·반전본 탐지(8변형 질의, 선택 옵션)
- 오디오 지문(chromaprint)을 같은 디코드 패스에서 뽑아 레터박스 사본을 잡는다.
  배경음만 같은 남남은 시각 확인 패스(트림 축 프레임 거리)로 걸러낸다 — 실측 9 vs 29.
- 비교 재생(CompareView): 여러 사본을 offset 정렬해 나란히 재생
- 지문 생성 속도 조절(느림·보통·빠름) — 재시작 없이 반영

간단 편집 (원본을 직접 고침, Ctrl+Z로 되돌림)
- 회전·반전: JPEG은 EXIF 방향 태그 2바이트만, MP4는 회전 행렬만 — 화질 손실 0.
  방향값 전이표는 군의 성질(90도x4=제자리)로 검산하고, 실제 화소를 transpose=1과
  비교해 "시계 방향"이 정말 시계인지 확인한다.
- 자르기: 화면 좌표 기준(회전 메타가 붙어 있어도 어긋나지 않는다)
- 구간 자르기: 스트림 복사라 무손실. 필름스트립 타임라인 + 손잡이 끌기 + 구간 미리보기.
- 되돌릴 수 없는 편집(자르기·반전)은 원본을 .archive_trash/edits로 옮겨 보관
- 편집이 수정시각을 바꾸지 않는다 — 기본 정렬이 촬영일이라 항목이 튀면 다시 찾아야 한다

동시 재생
- 고른 영상을 최대 9개 격자에 놓고 함께 재생. 소리는 한 칸만.
- 실시간 변환이 필요한 코덱은 2개까지만 — 그 이상은 ffmpeg가 기계를 멈춘다

그 외
- 별점(스냅샷 flags 남는 비트에 얹어 항목당 바이트 증가 0)
- 태그: 검색 없이 클릭으로 붙이기, 세트+단축키, 이름 수정 시 붙은 항목에 전파
- 파일 로깅(tracing-appender) — 릴리스는 콘솔이 없어 stdout만으로는 원인을 못 찾았다
- ARM64 크로스 컴파일 스크립트(관리자 권한 없이 VS 카탈로그에서 조립)
- DB 마이그레이션 v7~v10

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 16:18:24 +09:00
강 한andClaude Fable 5 2bb1711ffa 재실행 시 영상 재처리로 인한 멈춤 완화 — ffmpeg/ffprobe 저우선순위 + 백업 하루 1회
증상: 영상이 많은 라이브러리에서 첫 로딩이 오래 걸리고, 다 불러온 뒤
재실행하면 멈춤. 원인은 미완료 영상 썸네일 백로그가 시작 시
enqueue_pending으로 재개되는데, ffmpeg/ffprobe가 '자식 프로세스'라
스레드 저우선순위(이전 수정)를 상속받지 못해 NORMAL로 전 코어를 포화시켜
WebView UI가 멈춘 것. (재실행 시 전체 재스캔은 없음 — 자동스캔은 dev 전용,
워처도 시작 시 스캔 안 함. 재처리는 미완료 썸네일 재개일 뿐.)

- ffmpeg::command(): Windows CREATE_NO_WINDOW에 BELOW_NORMAL_PRIORITY_CLASS 추가,
  Unix는 pre_exec로 setpriority(nice+10). 검증: 스캔 중 ffmpeg/ffprobe
  PriorityClass=BelowNormal 관측(ffmpeg 406, ffprobe 46 샘플).
- 시작 유지보수 스레드도 저우선순위로, DB 백업(VACUUM INTO=전체 복제)은
  24시간 내 백업 있으면 건너뜀 — 대용량 라이브러리 재실행 부하/디스크 낭비 감소.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 20:05:41 +09:00
강 한andClaude Fable 5 8ba0c24ce8 중복 탐지 범위 선택 추가 — 현재 폴더/소스 또는 전체
기존엔 항상 라이브러리 전체를 대상으로 했다. 이제 중복 검토 패널에서
현재 보고 있는 뷰(폴더=하위 포함 / 소스)로 범위를 좁힐 수 있고,
폴더/소스 뷰에서는 기본값이 '현재 위치'다. 전체/검색/태그/스마트 뷰는
전체 라이브러리로 고정.

- dedupe::Scope { All | Source | Folder{recursive} } 도입, load_files/run에 적용
  (folder_snapshot과 동일한 경로 프리픽스 스코핑)
- start_dedupe에 folder_id/recursive 파라미터 추가
- DedupePanel: view() 기반 범위 세그먼트 컨트롤
- 테스트: folder_scope_restricts_detection (folderA=1그룹, 전체=2그룹, 누출 없음)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 19:57:40 +09:00
강 한andClaude Fable 5 31a0487419 폴더 추가 시 UI 멈춤 수정 — 백그라운드 워커 저우선순위 + JPEG DCT 축소 디코드
원인: 실사진(수십 MP) 스캔 시 메타 추출(rayon)과 썸네일 워커가
NORMAL 우선순위로 전 코어를 포화시켜 WebView UI 스레드를 굶김.
풀해상도 JPEG 디코드는 파일당 ~72MB를 할당해 병렬 시 메모리 대역폭까지 포화.

- prio 모듈: 현재 스레드 우선순위 낮추기(Win BELOW_NORMAL / macOS nice+5),
  메타 전용 저우선순위 rayon 풀(코어-1, 전역 풀과 분리)
- 썸네일 워커 스레드·스캔 스레드를 저우선순위로 → CPU 포화 시 UI 우선 스케줄
- meta 이미지/영상 추출을 저우선순위 풀에서 실행
- JPEG는 jpeg-decoder DCT 축소 디코드(1/8 등) 사용:
  24MP 기준 풀디코드 63ms/72MB → 축소 38ms/1MB (1.7배·메모리 ~70배 절감),
  RGB24/L8만 처리하고 그 외(CMYK)는 기존 경로로 폴백

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 14:19:18 +09:00
강 한andClaude Opus 4.8 b4b1ef3241 소스 제외(인덱스에서 제거) 기능 추가
- 사이드바 소스 행 hover 시 ✕ 버튼 → 확인 후 인덱스/폴더/태그/썸네일
  캐시 제거. 디스크의 실제 파일은 삭제하지 않음.
- 로컬: 파일 워처 해제. 원격: 연결 해제 + 자격증명(키체인/볼트) 삭제.
- maintenance::remove_source (defer_foreign_keys로 자기참조 FK 처리),
  스캔 중 제외 방지, 제외한 소스를 보던 중이면 전체 뷰로 전환.

Rust 테스트: 실제 파일 보존 + 인덱스/썸네일 제거 검증 통과.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 13:41:15 +09:00
강 한andClaude Opus 4.8 5a7952bd2d 후속 개선: 원격 썸네일·자동재연결, RAW 썸네일, 마퀴 선택, 이동 강건성
P1 원격 소스 UX:
- remote_thumbs: VFS 다운로드로 원격 썸네일 생성(이미지 EXIF 내장 우선,
  영상은 미디어서버 bridge URL로 ffmpeg Range 추출)
- 앱 시작 시 키체인 자격증명으로 원격 소스 자동 재연결
- fileops: physical_move에 Windows 공유위반 재시도

P3 그리드/포맷:
- RAW(cr2/nef/arw/dng 등) 내장 JPEG 프리뷰 추출 썸네일(scan_largest_jpeg)
- 그리드 마퀴(드래그 사각형) 다중선택
- .gitattributes 줄바꿈 정규화

Rust 테스트 51개 통과.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 22:10:53 +09:00
강 한andClaude Opus 4.8 394d1b9805 Archive v0.1.0 — 사진/영상 라이브러리 관리 프로그램
Tauri v2 + SolidJS + SQLite + ffmpeg 사이드카로 구현한 크로스플랫폼
사진·영상 관리 앱. 로컬/NAS(SFTP·WebDAV·FTP) 소스, 가상 그리드,
인앱 재생, 태그/이동/삭제/undo, 중복 탐지, 포터블 배포.

- archive-db: SQLite 스키마·마이그레이션·단일 writer 스레드 + FTS5 trigram
- archive-vfs: VFS 4백엔드(local/sftp/ftp/webdav) + 자격증명(키체인/볼트)
- archive-indexer: 스캔·해시·썸네일·중복탐지·태그·파일작업·유지보수
- archive-media: localhost HTTP 미디어 서버(Range) + ffmpeg 스트림 잡
- 프론트: 3-pane UI, justified 가상 그리드, 라이트박스, 중복 검토 패널

Rust 테스트 49개 통과. CI: win x64/arm64 포터블 zip + macOS universal dmg.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 22:04:06 +09:00