SCM: macOS의 모든 사진과 비디오 프레임에 대한 AI 검색 기능
요약
SCM은 macOS의 모든 사진 및 비디오 프레임을 대상으로 하는 심층 AI 검색 기능을 제공합니다. 로컬 우선(Local-first) 방식으로 작동하며, 추론 과정 전체가 Mac 기기 내에서 이루어져 높은 개인 정보 보호를 보장합니다. 일반 언어 설명만으로도 장면을 분석하고 텍스트, 음성까지 검색할 수 있습니다.
핵심 포인트
- macOS 전용: 로컬 환경에서 모든 미디어 파일에 대한 AI 검색 제공
- 로컬 우선(Local-first): 데이터가 기기를 벗어나지 않아 높은 개인 정보 보호 보장
- 다중 모드 검색: 비전, OCR, Whisper를 통해 사진/비디오의 장면, 텍스트, 대화 내용까지 검색 가능
- 사용 편의성: 모든 쿼리를 저장하고 관리하는 사용자만의 탭 및 프롬프트 기능 제공
SCM — Screen Memories
macOS의 모든 폴더에 있는 사진과 비디오 프레임 전체를 대상으로 하는 심층 AI 검색 기능입니다.
로컬 우선(Local-first) 방식 — 계정, 클라우드, 업로드 없음. 추론(Inference)은 Mac에서 실행됩니다.
차별점(What makes it different)
- 생각하는 것처럼 검색 — 일반 언어로 추억을 설명하면, 로컬 비전 모델이 나머지 작업을 수행합니다.
- 비디오의 순간까지 — 장면(scenes)은 분할되고 임베딩되므로, 단순히 파일이 아닌 특정 샷으로 이동할 수 있습니다.
- 텍스트와 대화도 가능 — 보이는 텍스트에 대한 OCR; Whisper를 통한 정확한 발언 내용 검색, 각각 독립적인 모드로 작동합니다.
- 사용자만의 탭과 프롬프트 — 모든 쿼리를 탭으로 저장할 수 있으며, 스크린샷 및 이메일 탭은 토글(toggle)이 가능합니다.
- 자가 유지 라이브러리 — 감상한 폴더는 자동 가져오기(auto-import)되고, 콘텐츠 해시(content hashes) 중복 제거가 이름 변경을 수행하며, 모델 전환 시 백그라운드에서 검색을 방해하지 않고 재임베딩됩니다.
- 진정한 개인 정보 보호 — 미디어 파일은 절대 기기를 벗어나지 않습니다. 가중치(Weights)는 한 번만 다운로드하면 이후 모든 작업은 오프라인으로 진행됩니다.
다섯 가지 검색 방법 (Five ways to search)
<div align="center"> <img src="Asset/tabs.png" alt="Search modes: Files, Scenes, Dialogue, OCR, LLMs" width="700" /> </div>| 모드 | 검색 가능 항목 |
|---|---|
| Files | 의미에 따른 전체 사진/비디오 — 파일 이름과 구문(phrase) 부스트를 사용한 비전 랭크(vision rank) 기능 |
| ... |
요구 사항 (Requirements)
- macOS (electron-builder로 패키징됨; 메뉴 바/트레이 기능은 macOS 전용)
- Bun — 이 프로젝트는 패키지 매니저와 실행기로
bun을 사용합니다 - 설치된 Node 모듈:
bun install - 모델을 처음 사용할 때 가중치(기본 CLIP의 경우 약 435MB)를 다운로드하며, 그 이후부터는 완전히 오프라인으로 작동합니다.
다운로드
가장 쉬운 설치 방법은 Homebrew를 이용하는 것입니다 (Apple Silicon, macOS 12 이상). 이 tap은 모든 설치 및 업그레이드 시마다 macOS 격리 플래그(quarantine flag)를 자동으로 제거하므로, 앱을 실행할 때 수동으로 Gatekeeper 단계를 거칠 필요가 없습니다:
brew tap allenv0/scm
brew trust allenv0/scm
brew install --cask allenv0/scm/scm
업그레이드도 동일한 방식으로 진행됩니다:
brew upgrade --cask allenv0/scm/scm
최소 권한 원칙을 선호하십니까? 전체 tap 대신 cask만 신뢰할 수 있습니다:
brew tap allenv0/scm
brew trust --cask allenv0/scm/scm
brew install --cask scm
이 tap은 allenv0/homebrew-scm에 위치합니다.
개발
bun run dev # 렌더러 번들을 빌드한 후 Electron 앱을 실행합니다
bun start # 재빌드 없이 Electron 앱을 실행합니다
bun run build # 렌더러 번들만 dist/에 다시 빌드합니다
앱 패키징하기 (DMG / ZIP)
bun run dist # 키체인에 ID가 있는 경우 서명됩니다
bun run dist:unsigned # 코드 서명 검색을 건너뜁니다
이 명령어는 두 단계를 순차적으로 실행합니다:
vite build— React 렌더러를dist/에 컴파일합니다 (src/ 아래의 모든 변경 사항을 가져옵니다).electron-builder --mac— 앱을 패키징합니다. 최신dist/번들을main.js,preload.js,main-lib/, 그리고indexer/와 함께 묶고 (파일 목록은package.json의build.files에 설정되어 있음), 설치 프로그램을 생성합니다.
출력: 설치 프로그램은 dist-app/에 위치합니다 (이는 package.json의 build.directories.output 참조). SCM-0.2.4.dmg와 SCM-0.2.4.zip을 찾아보세요.
기능
파일
타이핑을 시작하면 즉각적인 파일명-키워드 사전 검사(pre-pass)가 진행된 후, 비전 모델(vision model)이 작동합니다. 결과는 이미지 임베딩(image embeddings)과 코사인 유사도(cosine similarity)로 점수화되며, 게이티드 구문 및 파일명 부스트(gated phrase and filename boosts), 모델별 보정된 정직성 하한선(honesty floor), 그리고 근접 중복 다양성 필터(near-duplicate diversity filter)가 적용됩니다. 모든 타일에는 "매칭 이유" 배지(시각적 매치 / 파일명 매치 / …)와 컴포넌트별 점수 분석이 담긴 호버 툴팁이 표시됩니다. CJK 쿼리는 중첩된 빅그램(overlapping bigrams)으로 검색합니다("台北車站"는 "台北", "車站"과도 매칭됨).
장면 (Scenes)
모든 비디오의 모든 장면 세그먼트가 점수화되므로, 히트(hit)는 정확한 샷에 위치합니다. 타일에는 장면 포스터와 시간 코드 배지(timecode badge)가 표시되며, 영상을 열면 해당 순간으로 바로 이동합니다. 노이즈 게이트(noise gate) 기능은 무의미한 내용을 그리드에 가득 채우는 대신 "장면 매치 없음"을 반환하며, 각 비디오는 최대 3개의 장면만 기여합니다.
OCR
각 이미지의 OCR 텍스트에서 문구 토큰이 문자 그대로 보이는 분량을 매칭합니다. 파일명은 무시되며 비전 모델이 관여하지 않으므로, AI 엔진이 예열 중이거나 오프라인 상태일 때도 작동합니다. 매칭된 단어는 타일과 라이트박스(lightbox)에서 호박색으로 상자 처리됩니다.
대화 (Dialogue)
Whisper 전사(transcripts)를 기반으로 정확한 문자 그대로의 검색을 수행하며, 임베딩이나 임계값(thresholds)이 필요 없고 AI 엔진이 다운되어도 작동합니다. 결과는 세 가지 등급으로 제공됩니다: 정확한 문장 (하나의 발화 내 연속된 구문), 정확한 단어 (하나의 발화 또는 ≤8초 범위 내 모든 단어), 그리고 발화된 단어 (동일 비디오 내 모든 단어). 매칭되는 단어는 음성 스니펫(speech snippet)에 하이라이트되며, 결과를 열면 해당 문장으로 바로 이동합니다.
LLMs (Ask)
선택적 활성화 기능입니다. 설정 → LLMs Chat에서 활성화하기 전까지는 아무것도 다운로드되거나 실행되지 않습니다. llama.cpp 사이드카(sidecar)가 루프백(loopback)을 통해 앱이 이미 추출한 증거(대화 내용, OCR 텍스트, 파일명 키워드 히트)를 기반으로 질문에 답변하며, 클릭 가능한 번호가 매겨진 인용문과 함께 토큰별로 스트리밍되고 실시간 tok/s 판독기가 표시됩니다. 선행 /screenshots, /videos, /email은 코퍼스(corpus)를 좁히고; Stop은 부분적인 답변을 유지하며; 증거가 없을 경우 모델이 실행되기 전에 프로세스가 단축됩니다.
| Chat model | 크기 | 참고 사항 |
|---|---|---|
| Qwen3 1.7B (기본값) | ~1.1GB | 일상적인 채팅에 빠름; 8GB Mac에 적합 |
| Llama 3.2 3B | ~2GB | 더 강력한 긴 답변; 여유 공간 필요 |
탭 및 라이브러리 보기
- 내장 브라우즈 탭: 전체, 비디오 외에 스크린샷과 이메일이 있으며, 후자는 설정(Settings) → 스마트 탭에서 토글 가능합니다. 비디오를 선택하면 자동으로 장면 모드(Scenes mode)가 활성화됩니다.
- 모든 검색 쿼리를 탭으로 저장: 검색창 아래의 고정 핀 모양 버튼은 현재 프롬프트와 해당 모드(파일/장면/OCR/대화)를 저장하며, 최대 20개의 탭을 지원하고 이름 변경이 가능하며, 저장된 대로 정확하게 복원됩니다.
- 재배치 가능한 단축키(기본값: ⌘1–⌘5) 뒤에 다섯 가지 의미론적 보기(semantic views)가 있으며, 추가로 ⌘I는 가져오기/AI 인사이트(import / AI Insights), ⌘, 는 설정용입니다.
- 검색은 선택된 탭에 머무름: 스크린샷, 이메일, 비디오 또는 저장된 모든 탭을 선택하면 결과가 해당 범위로 필터링됩니다. 즉, 범위를 먼저 지정하고 검색합니다. LLM 채팅에서도 같은 아이디어가 명시적입니다:
/screenshots,/videos,/email과 같이 시작하는 접두사는 모델이 실행되기 전에 코퍼스(corpus)를 좁힙니다.
이메일 탭
OCR 텍스트에 이메일 주소가 포함된 사진을 표시합니다. 이는 중첩된 보기(overlapping view)로, 사진은 원래의 카테고리를 유지합니다. 감지 기능은 OCR에 내성이 있어 단어 상자 전반에 걸쳐 Tesseract가 분리한 주소들을 재조립하고, 쉼표-점 노이즈(
ONNX Runtime을 통해 네 가지 전환 가능한 모델 사용; 활성화된 모델은 라이브러리별로 선택됩니다:
| Model | Role | Speed (CPU) | Download |
|---|---|---|---|
| CLIP ViT-L/14@336 (default) | 최고의 실제 비디오 장면 검색 기능 | ~480–570ms/img | ~435MB |
| ... | |||
| Switching models re-embeds the whole library: the flip lands instantly with the tail filled in the background, and search falls back to filename keywords until it completes. Per-model text-mean centering de-biases text embeddings so similarity scores stay honest across models. |
비디오 검색 파이프라인
ffmpeg는 각 비디오를 스캔하여 샷 경계를 찾고, 설정(Settings) → 비디오 검색(Video Search)에서 지정한 밀도로 샘플링된 세그먼트 계획을 구축합니다. 모든 프리셋은 사용하기 전에 측정된 시간과 디스크 비용을 보여줍니다:
| Preset | Seconds per point | Segment budget |
|---|---|---|
| Eco | 60 | 4–32 |
| ... | ||
| 각 세그먼트는 중간 프레임을 임베드하고 포스터를 유지합니다. 샷 계획은 파일별로 캐시됩니다(경로 + 크기 + mtime + 설정 지문). 따라서 재가져오기는 감지 단계를 완전히 건너뜁니다. |
대화 녹취록 작성: Whisper tiny.en (~150MB, default) 또는 base.en (~300MB) — 전환 시 모든 비디오를 다시 녹취합니다. 전체 비디오는 세 프레임(20/50/80%)을 평균하여 임베드됩니다. GIF는 중간 프레임의 평균을 임베드합니다.
OCR
Tesseract는 비전 모델과 분리된 자체 워커(worker)에서 실행됩니다. 영어는 항상 활성화되어 있으며, 설정(Settings) → 사진 검색(Photo Search)에서 35개 이상의 언어를 토글할 수 있습니다 (기본값: 간체 중국어 + 전통 중국어, 일본어, 한국어). 각 언어 팩은 한 번 다운로드하면(~2.4–5MB; 기본 세트의 경우 약 17MB) 모든 것이 오프라인으로 작동합니다. 단어 상자(Word boxes)는 텍스트와 함께 저장되어 일치하는 부분이 제자리에 하이라이트되며, CJK 텍스트는 공백 없이 연결되고 단어 상자에 분산된 이메일 조각은 재조립됩니다.
가져오기 및 라이브러리 관리(Import & library management)
- 가져오기(Import): ⌘I, 드래그 앤 드롭 또는 감시 폴더(watched folders)를 통해 가능합니다. 폴더를 가져오면 해당 폴더를 감시하기 시작하며 (실시간
fs.watch및 매번 실행 시 재동기화), 문제가 있는 파일은 최대 3회 재시도한 후 변경될 때까지 감시 동기화에서 제외됩니다. - 이름에 관계없는 중복 제거(Rename-proof dedupe): 모든 파일은 복사 전에 콘텐츠 해시(SHA-256)가 생성되며, 존재하지 않는 확장자는 MIME 스니핑을 통해 정규화됩니다.
- 명명된 임베딩 버전(Named embedding versions) (설정 → 라이브러리): 검색 가능한 전체 상태의 시점별 스냅샷입니다. 여기에는 인덱스, 모든 모델의 임베딩 빈(embedding bins), 장면 및 스크립트 사이드카 등이 포함되며, 복원 기능(자동 백업 먼저)과 '새 시작 위험 구역(Fresh Start danger zone)'이 있습니다. 최대 용량: 10개.
- 모든 것은
~/Library/Application Support/scm(MEMORIES_DATA_DIR가 이를 재정의함) 아래에 존재합니다: 인덱스 JSON, 모델별 Float32 임베딩 빈, 장면 및 스크립트 사이드카, 썸네일, 포스터 등.
구축을 통한 개인 정보 보호(Privacy by construction)
- 렌더러는 격리된
app://번들입니다 —contextIsolation, OS 샌드박스, 그리고'self'에 고정된 CSP(Content Security Policy)를 사용하며 (표시 유형의 경우 Google Fonts CDN을 사용하고 오프라인 시 모노스페이스 대체품 사용). - 메인 프로세스 워커만 무언가(thing)당 한 번 다운로드합니다: 비전 가중치(Hugging Face), OCR 언어 팩(Tesseract CDN), Whisper 가중치, 그리고 — 옵트인한 경우에만 — llama.cpp 사이드카 및 GGUF 채팅 모델(GitHub + Hugging Face). 이들은 다운로드 시 sha256으로 검증됩니다.
- 미디어는 앱 관리 라이브러리로 복사되어 디스크에서 스트리밍됩니다. 텔레메트리 없음, 계정 없음, 업로드 없음.
설정 및 다듬기(Settings & polish)
macOS 스타일의 설정 시트가 열 개의 패널(라이브러리, 모양, 그리드, 스마트 탭, 사진 검색, 비디오 검색, LLMs 채팅, 전역 단축키, 키보드, 메뉴 막대)로 구성되어 있습니다. 핵심 요소 주변에는 라이트/다크/시스템 테마, 라이트박스를 위한 CRT 화면 효과, 6개의 대체 앱 아이콘, 메뉴 바 전용 모드, 기록 가능한 전역 단축키, 첫 실행 온보딩 투어, 글로벌 일시 정지 기능이 있는 백그라운드 작업 트레이(장면 / 스크립트 / OCR), 그리고 버전 및 인덱싱된 비디오 개수를 표시하는 상태 표시줄이 있습니다.
참고 사항
- 첫 빌드는 느립니다: electron-builder는 첫 실행 시 Electron 바이너리와 ffmpeg를 다운로드하며, 이후 빌드는 훨씬 빠릅니다.
- 코드 서명: 키체인에 Apple Developer ID가 구성되어 있지 않으면 DMG 빌드가 unsigned 상태로 생성됩니다. 앱은 여전히 로컬에서 실행되지만, macOS에서는 처음 실행할 때 마우스 오른쪽 버튼 클릭 → 열기(Open)를 요구할 수 있습니다.
- 재빌드는 변경 사항을 자동으로 반영합니다:
main.js,preload.js,main-lib/, 그리고indexer/가 소스에서 패키징(캐싱되지 않음)되기 때문에, 이들 중 어느 것을 편집한 후bun run dist를 실행하면 새로운 패키지가 생성됩니다.
테스트
AI 자동 생성 콘텐츠
본 콘텐츠는 HN AI Posts의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기