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

Archive

수만 개의 사진·영상을 빠르게 조회·재생하면서 삭제/태그/이동으로 관리하고, 중복(완전 동일 + 유사)을 찾아 제거하는 크로스플랫폼 데스크톱 앱.

  • 플랫폼: Windows x64 / Windows ARM64 / macOS (Intel + Apple Silicon)
  • 배포: 포터블(무설치) 우선 — exe 옆 data/ 폴더가 있으면 포터블 모드로 동작
  • 스택: Tauri v2 (Rust) + SolidJS + SQLite + ffmpeg 사이드카
  • 소스: 로컬 디스크, OS 마운트 드라이브(UNC/SMB), 앱내 FTP/SFTP/WebDAV (시놀로지 등)

개발

요구사항: Node 22+, Rust stable(1.95+), (Windows) WebView2 런타임 — Win10/11 기본 탑재.

이 PC 주의사항: VS Community 2026에는 MSVC 데스크톱 라이브러리가 없어 rustc가 링크에 실패한다(LNK1104: msvcrt.lib). 반드시 VS Build Tools 2026의 vcvars64 환경에서 cargo를 실행해야 하며, 아래 스크립트가 이를 대신 처리한다.

npm install
scripts\dev.cmd       :: 개발 실행 (vcvars64 + tauri dev)
scripts\test.cmd      :: 코어 크레이트 헤드리스 테스트 (vcvars64 + cargo test)

Windows ARM64 크로스컴파일은 로컬에 ARM64 MSVC 라이브러리가 없어 CI에서만 검증된다. 로컬에서 하려면 VS Installer에서 "MSVC ARM64/AArch64 빌드 도구" 컴포넌트를 설치할 것.

구조

src/                  SolidJS 프론트엔드 (3-pane UI, 가상 그리드)
src-tauri/            Tauri 셸 (커맨드, 데이터 디렉터리, 미디어 서버 기동)
  crates/
    archive-db        SQLite 스키마·마이그레이션·단일 writer 스레드
    archive-vfs       VFS 추상화 (local / sftp / ftp / webdav)
    archive-indexer   스캔·해시·썸네일·중복탐지 엔진
    archive-media     localhost HTTP 미디어 서버 (Range 스트리밍, ffmpeg 잡)

배포

Windows 포터블 (무설치)

scripts\fetch-ffmpeg.ps1 -Target win64     :: ffmpeg 사이드카 다운로드
npm run tauri build -- --no-bundle          :: 릴리스 빌드
scripts\package-portable.ps1 -Target x64    :: Archive-<ver>-windows-x64.zip 생성

zip을 풀고 Archive.exe를 실행하면 됩니다. exe 옆 data\ 폴더에 인덱스·썸네일이 저장되므로 폴더째 옮겨도 동작합니다. WebView2 런타임(Win10/11 기본 탑재)이 필요합니다.

macOS (universal)

CI(macos-14)에서 scripts/fetch-ffmpeg-macos.ps1로 arm64+x64 ffmpeg를 lipo 결합한 뒤 tauri build --target universal-apple-darwin으로 .dmg를 만듭니다. 배포 시 Apple Developer ID 서명·공증이 필요하며, 미서명 빌드는 첫 실행 시 우클릭 → 열기로 Gatekeeper를 통과시켜야 합니다.

Windows ARM64: CI에서 크로스컴파일로 검증됩니다(로컬은 ARM64 MSVC 툴체인 필요).

유지보수

앱 시작 시 백그라운드로 DB 백업(archive.db.bak, VACUUM INTO), 30일 지난 삭제 항목 하드 퍼지, 썸네일 캐시 LRU 정리(기본 상한 4GB)를 수행합니다.

설계 문서: 계획서 참조 (~/.claude/plans/reflective-watching-toucan.md).

S
Description
No description provided
Readme
893 KiB
Languages
Rust 58.9%
TypeScript 32.9%
CSS 3.8%
PowerShell 3.4%
JavaScript 0.7%
Other 0.3%