
2026/01/11 11:57
**Show HN:VAM Seek – 2次元ビデオナビゲーショングリッド、15 KB、サーバー負荷ゼロ**
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
VAM Seek – 軽量2Dビデオシークグリッドライブラリ
VAM Seekは、従来の1次元シークバーをインタラクティブなサムネイルグリッドに置き換える約15 KBのJavaScriptライブラリで、任意の動画を直感的に視覚的にナビゲートできるようにします。
コア機能
- クライアント側フレーム抽出:HTML5 Canvas API を使用 – サーバー CPU は不要、CDN 帯域幅ゼロ、完全プライバシー(動画はブラウザーを離れません)。
- LRU キャッシュ:高速アクセスのために最大200フレームを保存。
- 滑らかなマーカーアニメーション:60 fps で
を利用。requestAnimationFrame - VAM アルゴリズム:グリッド座標から正確なタイムスタンプ計算。
API
// 初期化例 const seek = new VAMSeek({ video: document.getElementById('video'), container: document.getElementById('seekContainer'), columns: 3, // デフォルト secondsPerCell: 5, // デフォルト onSeek: (time) => console.log(time) }); // メソッド seek.seekTo(time); // 指定時間へジャンプ seek.moveToCell(col, row); // マーカーをグリッドセルへ移動 seek.configure({ columns }); // 実行時に列数変更 seek.destroy(); // 後片付け
統合とサポート
- CDN のワンライナーまたは npm インストール。
- Vanilla JS、React、Vue で動作(デモアダプターあり)。
- デモ例は
ディレクトリに配置。examples/
バックエンド (FastAPI)
- デモフロントエンドを配信し、ヘルスチェック、グリッド設定、位置計算、デモ用動画アップロードを処理。
- クライアント抽出が利用できない場合は FFmpeg を使用してサムネイルをオンデマンド生成。
ブラウザ互換性
| Browser | Minimum Version |
|---|---|
| Chrome | 80+ |
| Firefox | 75+ |
| Safari | 14+ |
| Edge | 80+ |
| モバイルブラウザー(Chrome/Firefox/Safari) | ≥80 |
キーボードショートカット:矢印キー、スペース、Home/End でマーカーを移動。
ライセンス
- 個人・教育・研究利用は無料。
- 商用利用には有料ライセンスが必要 –
までお問い合わせください。info@haasiy.jp
開発歴史
2025‑01‑10 にモジュラー FastAPI バックエンド、クライアント側抽出、VAM マーカー移動、LRU キャッシュ、および CORS 対応を含めてリリース。
ディレクトリ構成
dist/ # 単独 JS バンドル docs/ INTEGRATION.md examples/ # Vanilla、React、Vue のデモページ backend/ # FastAPI コード frontend/ # デモフロントエンド資産
本文
VAM Seek – 2D ビデオセークマーカー
概要
ストリーミングサイト向けの軽量 2D ビデオセークグリッドライブラリです。1 次元のスクロールバーではなく、サムネイルグリッドを視覚的に利用して動画をナビゲートします。クライアント側でフレーム抽出と滑らかなマーカーアニメーションを実装しています。
- 盲目的なスクラブは不要です。すべてのシーンが一目で分かります。
なぜ VAM Seek なのか?
| 従来のセークバー | VAM Seek |
|---|---|
| 1 D タイムライン、試行錯誤型 | 2 D グリッド、即座に視覚的ナビゲーション |
| サーバー生成サムネイル | クライアント側 Canvas 抽出 |
| 重いインフラ | サーバー負荷ゼロ(約15 KB JS) |
| 複雑な統合 | 1 行でセットアップ |
キーワード: ビデオプレイヤー、ビデオセーク、サムネイルグリッド、動画ナビゲーション、HTML5 video、JavaScript ライブラリ、動画ストリーミング、メディアプレイヤー、動画コントロール、動画サムネイル、セークバー代替、動画 UX
クイックスタート(外部サイト向け)
<!-- 1. スクリプトを追加 --> <script src="https://cdn.jsdelivr.net/gh/unhaya/vam-seek/dist/vam-seek.js"></script> <!-- 2. 動画に接続 --> <script> VAMSeek.init({ video: document.getElementById('myVideo'), container: document.getElementById('seekGrid'), columns: 5, secondsPerCell: 15 }); </script>
詳細は
docs/INTEGRATION.md をご覧ください。
主な機能
- クライアント側フレーム抽出 – サーバー CPU 使用量ゼロ
- LRU キャッシュ – メモリに200フレームまで保持
- 滑らかなマーカーアニメーション –
で60 fpsrequestAnimationFrame - VAM アルゴリズム – 正確なタイムスタンプ計算
- フレームワーク対応 – React、Vue、Vanilla JS のサンプルを含む
プライバシーとアーキテクチャ
動画はブラウザ内に留まります。従来のサムネイルシステムでは動画をサーバーへアップロードし、FFmpeg で処理・サムネイル保存・CDN 配信を行いますが、これはコストや時間、プライバシーリスクが高いです。
| 従来 | VAM Seek |
|---|---|
| 動画をサーバーへアップロード | ブラウザ内に留める |
| サーバー側 FFmpeg 処理 | クライアント側 Canvas API |
| ディスクにサムネイル保存 | フレームをメモリキャッシュ |
| CDN 帯域費用 | サーバーコストゼロ |
| プライバシーリスク | 完全プライベート |
すべてのフレーム抽出はユーザー側のブラウザで Canvas API を利用して行われます。ページを閉じると、データは完全に消去され、サーバーへ送信されることはありません。
ディレクトリ構成
VAM_web/ ├── dist/ # 配布用ファイル │ └── vam-seek.js # 独立型ライブラリ(約15 KB) ├── docs/ # ドキュメント │ └── INTEGRATION.md # API 統合ガイド ├── examples/ # 統合作品例 │ ├── basic-integration.html # Vanilla JS サンプル │ ├── react-integration.jsx # React コンポーネント & フック │ └── vue-integration.vue # Vue 3 コンポーネント ├── backend/ # FastAPI デモバックエンド(演示用) │ ├── main.py # エントリポイント、静的ファイル配信 │ ├── requirements.txt # Python 依存関係 │ ├── core/ │ │ ├── grid_calc.py # VAM グリッド計算 │ │ └── video_utils.py # FFmpeg 処理 │ ├── models/ │ │ └── schemas.py # リクエスト/レスポンスモデル │ ├── routers/ │ │ ├── grid.py # /api/grid/* エンドポイント │ │ └── video.py # /api/video/* エンドポイント │ ├── uploads/ # アップロード動画(gitignore) │ └── thumbnails/ # 生成サムネイル(gitignore) ├── frontend/ # デモフロントエンド │ ├── index.html # メイン UI と埋め込み JS │ └── assets/ │ └── marker.svg # グリッドマーカーアイコン ├── .gitignore └── README.md
ライブラリ利用者向け
インストールオプション
-
CDN(推奨)
<script src="https://cdn.jsdelivr.net/gh/unhaya/vam-seek/dist/vam-seek.js"></script> -
npm (示しません)
基本使用例
const vam = VAMSeek.init({ video: document.getElementById('video'), container: document.getElementById('grid'), columns: 5, secondsPerCell: 15, onSeek: (time, cell) => { console.log(`シーク先:${time}s`); } }); // API vam.seekTo(120); // 2:00 にシーク vam.moveToCell(2, 3); // 列2、行3へ移動 vam.configure({ columns: 8 }); // 設定を更新 vam.destroy(); // 後片付け
設定表
| オプション | 型 | デフォルト | 説明 |
|---|---|---|---|
| HTMLVideoElement | 必須 | ターゲット動画要素 |
| HTMLElement | 必須 | グリッドを配置するコンテナ |
| number | 3 | 列数(3〜10) |
| number | 5 | セルあたりの秒数 |
| number | 200 | LRU キャッシュサイズ |
| function | null | シーク時コールバック |
デモ開発者向け
必要条件
- Python 3.9+
- FFmpeg(PATH にあること)
設定手順
cd backend pip install -r requirements.txt python main.py
http://localhost:8000 をブラウザで開いてください。
API エンドポイント
| メソッド | パス | 説明 |
|---|---|---|
| GET | / | フロントエンド配信 |
| GET | /api/health | ヘルスチェック |
| POST | /api/grid/config | グリッド寸法計算 |
| POST | /api/grid/position | 位置からタイムスタンプ算出 |
| POST | /api/video/upload | 動画アップロード(デモ用) |
技術詳細
フレーム抽出(クライアント側)
// 1. 隠し video 要素作成 const video = document.createElement('video'); video.src = 'video.mp4'; // 2. タイムスタンプへシーク video.currentTime = 15.0; // 3. seeked イベントでキャプチャ video.addEventListener('seeked', () => { const canvas = document.createElement('canvas'); ctx.drawImage(video, 0, 0); const dataUrl = canvas.toDataURL('image/jpeg', 0.8); }); // 4. LRU キャッシュに保存(最大200フレーム) frameCache.put(videoSrc, timestamp, dataUrl);
VAM アルゴリズム
function calculateTimestamp(x, y, gridWidth, gridHeight, duration, secondsPerCell) { const rowIndex = Math.floor(y / gridHeight * rows); const colContinuous = x / gridWidth * columns; const cellIndex = rowIndex * columns + colContinuous; return Math.min(cellIndex * secondsPerCell, duration); }
キーボードショートカット
| キー | 動作 |
|---|---|
| Arrow | セル単位でマーカー移動 |
| Space | 再生/一時停止 |
| Home | 最初のセルへ |
| End | 最後のセルへ |
対応ブラウザ
- Chrome 80+
- Firefox 75+
- Safari 14+
- Edge 80+
- モバイルブラウザ
ライセンス
個人・教育・研究利用は無料です。商用利用には有料ライセンスが必要です。お問い合わせ:
info@haasiy.jp.
開発履歴
| 日付 | マイルストーン |
|---|---|
| 2025‑01‑10 | FastAPI バックエンド、クライアント側抽出、VAM マーカー移動、LRU キャッシュ、スクロール修正、同一オリジン CORS 等を実装 |
| 2025‑01‑10 | ライブラリ公開 – 独立型 、統合ドキュメント、React/Vue サンプル |
クレジット
VAM Desktop アプリケーションのアルゴリズムをベースにしています:
–vam5.70/utils/video_utils.pycalculate_x_continuous_timestamp
–vam5.70/gui/preview/core/grid_calculator.pyGridCalculator