プログラミング
Show HN: macOS上のあらゆる写真と動画の全フレームを対象としたAI検索
Show HN: AI search for every photo and every frame of video on macOS (github.com)
要約
macOS向けのローカルファーストなAI検索ツール「SCM」が紹介されています。このツールは、写真や動画のフレーム全体、テキスト、さらには動画内の音声まで、ローカル環境でAIを用いて検索できます。プライバシーを重視し、データはユーザーのMacから外部に送信されません。
全文翻訳
SCM — macOS上のあらゆるフォルダにある写真と動画の全フレームを対象とした、ディープAI検索スクリーンメモリーズ。ローカルファースト — アカウント不要、クラウド不要、アップロード不要。推論はあなたのMacで実行されます。
何が違うのか
思考のように検索 — 平易な言葉で記憶を記述してください。ローカルのビジョンモデルが残りを処理します。
動画、瞬時まで — シーンはセグメント化され埋め込まれるため、ファイルだけでなく、その瞬間に到達できます。
テキストと対話も — 表示されているテキストに対するOCR。Whisperによる正確な音声検索。それぞれが独自のモードとして機能します。
あなたのタブ、あなたのプロンプト — 任意のクエリをタブとして保存できます。スクリーンショットとメールのタブは切り替え可能です。
自己維持ライブラリ — ウォッチフォルダは自動インポートされ、コンテンツハッシュはリネームを重複排除し、モデルの切り替えは検索をブロックすることなくバックグラウンドで再埋め込みを行います。
真にプライベート — あなたのメディアはマシンから離れることはありません。ウェイトは一度ダウンロードするだけです。それ以降はすべてオフラインです。
検索方法 5つのモード
Files (ファイル)
意味による写真/動画全体を検索 — ビジョンランクにファイル名とフレーズブーストを追加
Scenes (シーン)
動画内の瞬間を検索 — そのショットにジャンプ
OCR
画像とフレーム内の表示テキストを検索、文字通り一致 (Tesseract; eng + 35言語トグル)
Dialogue (対話)
動画内の正確な発話単語 (Whisper)、段階的な正確性
LLMs (opt-in)
Macが既に抽出した対話、OCR、ファイル名に対するローカルチャット — 引用付き回答
要件
macOS (electron-builderでパッケージ化。メニューバー/トレイ機能はmacOSのみ)
Bun — プロジェクトはパッケージマネージャーおよびランナーとしてbunを使用
インストール済みNodeモジュール: bun install
モデルの初回使用時にそのウェイト (~435MB、デフォルトのCLIP用) をダウンロードします。その後は完全にオフラインです。
ダウンロード
最も簡単なインストール方法はHomebrewです (Apple Silicon, macOS 12+)。
タップのCaskは、すべてのインストールとアップグレードでmacOSのクォーランティンフラグを自動的にクリアするため、アプリは手動のGatekeeper手順なしで起動します。
brew tap allenv0/scm
brew trust allenv0/scm
brew install --cask allenv0/scm/scm
アップグレードも同様の動作を維持します:
brew upgrade --cask allenv0/scm/scm
最小権限を優先しますか? タップ全体ではなく、Caskのみを信頼します:
brew tap allenv0/scm
brew trust --cask allenv0/scm/scm
brew install --cask scm
タップは allenv0/homebrew-scm にあります。
開発
bun run dev # レンダラーバンドルをビルドし、Electronアプリを起動
bun start # 再ビルドせずにアプリを起動
bun run build # レンダラーバンドルのみを dist/ にビルド
アプリパッケージ (DMG / ZIP) のビルド
bun run dist # キーチェーンにIDがあれば署名されます
bun run dist:unsigned # コード署名検出をスキップ
これは2つのステップを順次実行します:
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 を探してください。
機能
Files (ファイル)
タイピングを開始すると、即座にファイル名キーワードの事前パスが実行され、その後ビジョンモデルが引き継がれます。結果は画像埋め込みに対するコサイン類似度でスコアリングされ、フレーズとファイル名のブースト、モデルごとに調整された正直さのフロア、ニアデュプリケート多様性フィルターが適用されます。各タイルには「なぜ一致したか」のバッジ (Visual match / Filename match / …) と、コンポーネントごとのスコアの内訳を示すホバーツールチップが表示されます。CJKクエリは重複するビッググラムとして検索されます ("台北車站" は 台北, 車站 とも一致します)。
Scenes (シーン)
すべての動画のすべてのシーンセグメントがスコアリングされるため、ヒットはその正確なショットに到達します。タイルにはタイムコードバッジ付きのシーンポスターが表示され、動画を開くとその瞬間にジャンプします。ノイズゲートは、グリッドをガベージで氾濫させる代わりに「シーン一致なし」を返します。各動画は最大3つのシーンを提供します。
OCR
各画像のOCRテキストに表示されるクエリトークンのフラクションと文字通り一致します。ファイル名は無視され、ビジョンモデルは関与しないため、AIエンジンがウォームアップ中またはオフラインでも機能します。一致した単語はタイルとライトボックスでアンバー色で囲まれます。
Dialogue (対話)
Whisperトランスクリプトに対する正確な文字通りの検索 — 埋め込みなし、しきい値なし、AIエンジンがダウンしていても機能します。結果は3つのティアで提供されます: Exact line (1つの発話内の連続したフレーズ)、Exact words (1つの発話内のすべての単語、または≤8秒のウィンドウ)、Words spoken (同じ動画内のすべての単語)。一致した単語はスピーチスニペットでハイライトされ、結果を開くとその行に直接シークします。
LLMs (Ask)
オプトイン — 設定 → LLMs Chat で有効にするまで、何もダウンロードまたは実行されません。ループバックにバインドされたllama.cppサイドカーが、アプリが既に抽出した証拠 (対話ライン、OCRテキスト、ファイル名キーワードヒット) から、クリック可能な番号付き引用付きで、ライブtok/s表示とともにトークンごとにストリーミングされる質問に回答します。/screenshots, /videos, /email で始まるものはコーパスを絞り込みます。Stop は部分的な回答を保持します。空の証拠は、モデルが実行される前にショートサーキットします。
チャットモデル サイズ メモ
Qwen3 1.7B (デフォルト) ~1.1GB 高速な日常チャット。8GB Macに適合
Llama 3.2 3B ~2GB より強力な長文回答。ヘッドルームが必要
タブとライブラリビュー
組み込みブラウズタブ: All, Videos、および ScreenshotsとEmail。後者2つは設定 → Smart Tabs で切り替え可能です。Videosを選択すると、Scenesモードが自動的に有効になります。任意のクエリをタブとして保存: 検索バーの下のピンピルは、現在のプロンプトをそのモード (Files/Scenes/OCR/Dialogue) と共に保存します。最大20個のタブをリネーム可能で、それぞれが保存されたとおりに正確に復元されます。再マッピング可能なショートカット (デフォルトで⌘1–⌘5) の背後にある5つのセマンティックビュー、および⌘I import / AI Insights、⌘, for Settings があります。検索は選択されたタブに留まります: Screenshots, Email, Videos、または保存されたタブのいずれかを選択すると、結果はそのタブにフィルタリングされます。まずスコープを設定し、次に検索します。LLMsチャットでは、同じアイデアが明示的です。/screenshots, /videos, /email で始まるものは、モデルが実行される前にコーパスを絞り込みます。
Emailタブ
表示されているOCRテキストにメールアドレスが含まれる写真をサーフェス表示します。重複表示 (写真はそのカテゴリも保持します)。検出はOCRに耐性があります。Tesseractが単語ボックスを横断してアドレスを再構築し、カンマフォー ドットノイズ ("gmail,com")、分割TLD ("gmail. com")、括弧による難読化 ("allen [at] gmail [dot] com")、および口述アドレス ("allen at gmail dot com") を処理します。タイルには連絡先ストリップが表示され、展開するとコピーまたは作成できます。
Screenshotsタブ
スクリーンショットの分類はリネームに耐性があります。4つのシグナル、優先順位順: 手動オーバーライド (タイルを右クリック) → ファイル名語彙 (20以上の言語で30以上のローカライズされたOSスクリーンショット名) → PNG/JPEGメタデータプローブ (PNGテキストチャンク / EXIF UserCommentから "screenshot" を読み取るため、リネームされた Bildschirmfoto も分類されます) → ソースフォルダヒント。それ以外のすべてはProjectsに配置されます。
ビジョンモデル
ONNX Runtimeを介して切り替え可能な4つのモデル。アクティブなモデルはライブラリごとに選択されます:
Model (モデル) Role (役割) Speed (CPU) Download
CLIP ViT-L/14@336 (デフォルト) Best real-world video scene-search ~480–570ms/img ~435MB
SigLIP-2-B/16 Fastest bulk import ~50–100ms/img ~412MB
SigLIP-2-L/16@256 High-detail (1024-dim) — small objects, signs, on-screen text ~200ms/img ~850MB
SigLIP-B/16@384 Maximum detail ~480ms/img ~214MB
モデルを切り替えるとライブラリ全体が再埋め込みされます。切り替えは即座に完了し、テールはバックグラウンドで埋め込まれ、検索は完了するまでファイル名キーワードにフォールバックします。モデルごとのテキスト平均中心化は、テキスト埋め込みのバイアスを解除するため、モデル間で類似性スコアが正直に保たれます。
動画検索パイプライン
ffmpegは各動画をスキャンしてショット境界を検出し、設定 → Video Search で選択した密度にサンプリングされたセグメントプランを構築します。各プリセットは、コミットする前に測定された時間とディスクコストを示します:
Preset (プリセット) Seconds per point (秒/ポイント) Segment budget (セグメント予算)
Eco 60 4–32
Balanced (デフォルト) 30 8–128
Detailed 15 12–256
Ultra 5 16–1024
Ultra Pro 2.5 24–2048 (確認が必要)
各セグメントは中間フレームを埋め込み、ポスターを保持します。ショットプランはファイルごとにキャッシュされます (パス + サイズ + mtime + 設定フィンガープリント)。そのため、再インポートは検出を完全にスキップします。
対話トランスクリプション: Whisper tiny.en (~150MB、デフォルト)