【自動整理】ストック素材のダウンロードを自動整理するChrome拡張機能「Stockpile」を作った

ツール

はじめに

映像制作やコンテンツ制作をしていると、MotionElementsやAudiioといったストック素材サイトから大量のファイルをダウンロードすることがあります。気づけばダウンロードフォルダは BGM、効果音、動画素材、テンプレートファイルでカオス状態に…。

「またあの素材どこにダウンロードしたっけ…」

この問題を解決するために、StockpileというChrome拡張機能を作りました。

Chrome Web Storeからインストール

何を作ったか

Stockpileは、ストック素材サイトからのダウンロードを自動的に整理してくれる拡張機能です。

主な機能:

  • 自動フォルダ振り分け: ダウンロードを Stockpile/[サイト名]/[カテゴリ]/ に自動保存
  • メタデータ抽出: ページからタイトル、タグ、再生時間などを自動取得
  • ダウンロード履歴: 検索・フィルタリング可能な履歴管理
  • エクスポート機能: JSON/CSV形式でバックアップ

対応サイト:

なぜ作ったか

課題

映像編集の仕事をしていると、1つのプロジェクトで数十〜数百のストック素材をダウンロードすることがあります。

  • 動画素材
  • BGM
  • 効果音
  • モーショングラフィックステンプレート
  • LUTファイル

これらが全て「ダウンロード」フォルダに一緒くたに放り込まれる。ファイル名も ME_12345678_preview.mp4 のような意味不明な名前。後から「あの曲なんだっけ」と探すのが本当に大変でした。

既存のソリューション

フォルダを手動で作って整理する方法もありますが、ダウンロードのたびに手作業でフォルダに移動するのは面倒すぎる。ダウンロードマネージャー系の拡張機能も試しましたが、ストック素材サイト特有の「カテゴリ情報」や「メタデータ」を活用した整理には対応していませんでした。

「じゃあ作るか」と。

開発で苦労した点

1. Manifest V3への対応

Chrome拡張機能のManifest V3は、V2と比べて制約が多くなっています。特にバックグラウンドページが廃止され、Service Workerに移行したことで、いくつかの設計変更が必要でした。

// manifest.json
{
  "manifest_version": 3,
  "background": {
    "service_worker": "background/service-worker.js",
    "type": "module"
  }
}

Service Workerは必要なときだけ起動し、アイドル状態になると停止します。そのため、ダウンロード待ちのメタデータを一時的に保持する方法として、変数ではなく chrome.storage.local を使う必要がありました。

2. ダウンロードURLのマッチング問題

これが一番苦労した部分です。

ストック素材サイトでは、ダウンロードボタンをクリックしてから実際のファイルがダウンロードされるまでに、複数のリダイレクトが発生することがあります。

クリック → API呼び出し → 認証 → CDNリダイレクト → 実際のダウンロード

Content Scriptで取得した「クリック時のURL」と、chrome.downloads.onDeterminingFilenameで受け取る「実際のダウンロードURL」が一致しないケースが頻発しました。

最終的に、複数のマッチング戦略をフォールバックで実装することで解決しました。

3. 動的コンテンツへの対応

MotionElementsやAudiioはSPAライクな構造で、ページ遷移なしにコンテンツが切り替わります。また、ダウンロードボタンが動的に生成されることも。

MutationObserverを使って、DOMの変更を監視し、新しく追加されたダウンロードリンクを検出するようにしました。

4. XHR/Fetchのインターセプト

一部のダウンロードは、通常のリンククリックではなく、JavaScriptで動的に発火されます。これに対応するため、XHRとFetchをラップして監視する必要がありました。

技術選定

フレームワークを使わない選択

PopupやOptionsページのUIには、ReactやVueなどのフレームワークを使わず、Vanilla JavaScriptで実装しました。

理由:

  • 拡張機能のサイズを最小限に抑えたかった
  • UIがそこまで複雑ではない
  • ビルドプロセスなしでデバッグしたかった

結果的に、全体で数十KBに収まり、インストール後の動作も軽快です。

学びと気づき

Chrome拡張機能は「3つの世界」を跨ぐ

  • Content Script: Webページのコンテキストで動作
  • Service Worker: バックグラウンドで動作
  • Popup/Options: 独立したページとして動作

これらの間のデータのやり取りは chrome.runtime.sendMessagechrome.storage を介して行う必要があり、最初は戸惑いました。しかし一度理解すると、責務の分離が明確で設計しやすいと感じました。

ユーザーの行動は予測できない

「ダウンロードボタンをクリックする」という単純な行動にも、様々なパターンがあります。全てのケースに対応するのは難しいですが、主要なユースケースをカバーしつつ、エッジケースでもクラッシュしないよう防御的なコードを心がけました。

i18nは最初から入れておくべき

日本語と英語の両対応を後から追加したのですが、最初からi18nを意識して実装しておけばよかったと反省。Chromeの chrome.i18n APIは使いやすいので、最初から対応しておくことをおすすめします。

おわりに

自分が欲しいものを自分で作る。プログラマーの特権ですね。

Stockpileを使い始めてから、ダウンロードフォルダのカオスが解消され、素材を探す時間が大幅に減りました。

もし同じような課題を抱えている方がいれば、ぜひ使ってみてください。

Chrome Web Store: https://chromewebstore.google.com/detail/stockpile-download-organi/dghocnhifhkndkmolgkhcibnkapikjil

GitHub: https://github.com/atani/stockpile-extension

タイトルとURLをコピーしました