Skip to content

amariichi/VideoDepthViewer3D

Repository files navigation

VideoDepthViewer3D

Image Image

English | 日本語


English

Overview

VideoDepthViewer3D turns a video into an interactive 3D view in real time. The browser plays the video while a local Python process estimates depth with Depth Anything 3 (DA3METRIC-LARGE). You can view the result on a normal monitor, in side-by-side stereo, with WebXR, or on a Looking Glass display.

How it works

  • The browser displays the original video at its native quality whenever it supports the codec. If it cannot decode an iPhone HEVC video, the backend prepares a high-quality H.264 display copy while keeping the original for depth processing.
  • The local backend estimates depth and sends only the depth result to the viewer.
  • The viewer reconstructs a 3D surface and keeps it synchronized with the video.
  • Automatic performance modes adjust depth quality for the available GPU, CPU, and connection while prioritizing smooth playback.

See OPTIMIZATION_DETAILS.md for implementation, calibration, and performance-measurement details.

Setup & Run

  1. Install dependencies (uv):

    uv venv .venv
    uv sync --locked --extra dev --extra inference
  2. One-click Run (Recommended):

    ./start.sh

    This starts both the backend (port 8000) and frontend (port 5173).

    start.sh is for Linux, macOS, WSL, or Git Bash. On native Windows PowerShell, use the two portable commands under Manual Run below in separate terminals.

    [!NOTE] First Run: The application downloads the Depth Anything 3 model (approximately 1.3 GB). Depth processing starts after the download and model loading finish, so please allow some extra time.

    [!IMPORTANT] Restarting the App: Stop the existing start.sh with Ctrl+C before starting it again. Only run one copy at a time. The browser app always uses port 5173; refresh the page after the restarted app is ready.

  3. Manual Run (Alternative):

    • Backend:
      uv run --locked --extra inference python scripts/run_backend.py
    • Frontend:
      cd webapp
      npm ci
      npm run dev

    Then open http://localhost:5173.

Both development servers bind to the local computer by default. This is the safest setting for normal desktop use.

Use a phone to choose and control a video

An iPhone, iPad, or Android device can send a video from its library to the processing PC. The phone gets a compact page with a local video preview, upload progress, play/pause, and seeking. The PC automatically opens the transferred video and remains the only device that runs depth inference or enters SBS, Looking Glass, and WebXR modes.

The PC is still needed to operate SBS, Looking Glass, or WebXR, so the phone and PC are normally used together on the same trusted network. LAN mode below is the recommended setup. Tailscale is optional.

Same trusted Wi-Fi (simplest)

Use this only on a home or other trusted private network.

  1. On Linux, macOS, WSL, or Git Bash, start the app in LAN mode:

    ./start.sh --lan

    On native Windows PowerShell, use the two Manual Run terminals above, but start the frontend with:

    npm run dev -- --host 0.0.0.0
  2. Keep using http://localhost:5173 on the PC. On the phone, open one of the Network URLs printed by Vite, such as http://192.168.1.20:5173. 0.0.0.0 is a listen setting, not an address to open in the browser.

  3. Allow TCP 5173 from the trusted LAN if the PC firewall blocks it. On Windows, choose Private networks if a firewall prompt appears. On Ubuntu with UFW, first check whether it is active:

    sudo ufw status

    If it is active, allow only your LAN subnet. Replace the example subnet when your network uses a different address range:

    sudo ufw allow from 192.168.1.0/24 to any port 5173 proto tcp comment 'VideoDepthViewer3D LAN'

Only the frontend is exposed to the LAN; the Python backend stays on loopback and is reached through the frontend proxy. LAN mode uses plain HTTP, so do not use it on public or guest Wi-Fi and do not forward port 5173 from the router.

Optional: use an existing Tailnet

If the PC and phone already use Tailscale, Serve can be used instead of LAN mode. This keeps the frontend on loopback and provides a private HTTPS address, but the PC viewer is still required.

  1. Install Tailscale on the PC and phone, and sign both devices into the same tailnet. Do not use Tailscale Funnel for this workflow.

  2. Start VideoDepthViewer3D on the PC and leave it running. Open the desktop viewer at http://localhost:5173. Use the normal startup, without --lan.

  3. In another PC terminal, use Tailscale Serve to publish only the loopback frontend to the tailnet. On Windows, open the terminal as Administrator. On other systems, use elevated privileges only if Tailscale asks for them.

    tailscale serve --bg --https=443 5173

    On first use, Tailscale may ask you to enable HTTPS certificates for the tailnet. Follow the URL it prints to approve this.

    The command prints a private HTTPS URL similar to https://your-pc.your-tailnet.ts.net. You can also see it with tailscale serve status.

  4. Open that HTTPS URL on the phone. The mobile remote is selected automatically. Choose a MOV, MP4, M4V, 3GP, WebM, or another video format supported by the backend.

  5. The preview starts from the phone's local file while one source copy is sent to the PC. Keep the browser page in the foreground until Transfer complete appears. The already-open PC viewer attaches automatically.

  6. Use the phone preview to play, pause, or seek. Enter SBS, Looking Glass, or WebXR from the PC browser when required.

TCP 443 is the simplest choice. If it is already used by another Serve route, choose another available HTTPS port and use that same port in the access policy and stop command. Port 5173 does not need to be granted: Serve forwards the chosen tailnet port to loopback locally.

The app has no separate user login. Treat the tailnet access policy as the security boundary and allow only trusted users or devices to reach this port. Any allowed client can replace the current video session.

Only one video session is active at a time; choosing another video replaces the previous session. A browser without HEVC support automatically asks the backend for an H.264 playback copy. This one-time preparation can take longer for 2K or 4K video, but depth is still decoded from the original source. If device detection is unusual, append ?mode=remote on the phone or ?mode=viewer on the PC.

Tailscale Serve keeps the Python backend on loopback and carries /api and WebSocket traffic through the frontend proxy. To stop only this HTTPS listener later, run tailscale serve --https=443 off (replace 443 if you chose another port). Existing Serve routes on other ports remain separate. tailscale serve reset clears every Serve route on the machine and should not be used when other routes need to remain active.

Using a Looking Glass

What you need

  • A Looking Glass connected and enabled as a desktop display.
  • Looking Glass Bridge installed for Windows, macOS, or Linux.
  • Chrome or another Chromium-based browser is recommended. Firefox can also be used, but you may need to move the presentation window to the Looking Glass yourself. Safari is not supported.

On a Windows host, use the native Windows setup for Looking Glass (Bridge, browser, frontend, and backend) rather than WSL. Generic WebXR headsets such as Meta Quest through Meta Quest Link are different: the Windows browser and XR runtime own the headset session, so the application servers may run either natively on Windows or in WSL as long as the page is opened in the Windows browser through localhost.

Start in this order

  1. Connect and turn on the Looking Glass.
  2. Start Looking Glass Bridge and wait until it recognizes the display. Leave Bridge running while you use the viewer.
  3. Start VideoDepthViewer3D using the setup instructions above (./start.sh on Bash, or the manual commands on Windows PowerShell), then open http://localhost:5173. For the most reliable startup, Bridge should already be running before this page is opened or reloaded.
  4. Select Open Video. Wait until both the video and the 3D view are moving in the browser. The first run takes longer while the depth model is downloaded and loaded.
  5. Select Enter Looking Glass and allow the browser to open and place the presentation window. If the browser does not place it automatically, move that window to the Looking Glass display.
  6. On the Looking Glass display, move the mouse pointer into the presentation window and double-click inside it. The window enters full-screen mode and the correct 3D view appears.
  7. The status changes to Active when the device is ready. Select Exit Looking Glass to return to normal monitor viewing.

On macOS, keep the browser in a normal desktop window rather than macOS full-screen mode while starting Looking Glass, so the presentation window can open on the external display.

Looking Glass controls

  • Mouse wheel / Hologram Zoom: Zoom the hologram without changing its focus. Scrolling back through 1× returns to the fitted full-video size.
  • Drag with either mouse button: Pan the image. This does not rotate the scene.
  • Click without dragging: Use the selected point as the depth focus. Zoom stays unchanged, and the selected focus remains locked until you resume automatic placement. An unusually distant selection asks for a second click in the same area to protect against accidental background clicks.
  • Auto Depth Placement: Recommended and enabled by default. It follows the area currently visible after zooming and panning, brings distant scenes forward, and moves excessively close content back to keep it visible. A scene change or an unsafe foreground can release a manual focus lock.
  • Resume Auto: Release a click-selected focus lock and immediately return to automatic placement for the currently visible area.
  • Focus Trim: Fine-tune depth placement after automatic placement or a click.
  • Reset Zoom / Pan: Restore the fitted size and centered position.

Auto Source View is the recommended framing mode. It fits the complete video into the connected display and keeps the video borders straight. A wide video on a portrait device such as Looking Glass Go is therefore shown with empty space above and below; this is expected and avoids cropping the source.

Troubleshooting

  • Bridge unavailable: Start Looking Glass Bridge, confirm that it detects the display, then select Enter Looking Glass again.
  • Blocked: Allow pop-ups and window-management permission for localhost:5173, then try again. On macOS, also leave browser full-screen mode.
  • Unverified: The presentation window opened, but device calibration was not received. Check the video/USB connections and confirm that Bridge sees the display.
  • The presentation does not show the correct 3D view: Confirm that the presentation window is on the Looking Glass display, move the pointer into that window, and double-click inside it to enter full-screen mode.
  • Black, stale, or incorrectly placed image: Select Exit Looking Glass, make sure Bridge is already running, hard-reload the browser page (Ctrl+Shift+R on Windows/Linux or Cmd+Shift+R on macOS), reopen the video, wait until the video and 3D view are moving, and enter Looking Glass again.
  • Image is too large or off-center: Scroll out or select Reset Zoom / Pan. Keep Auto Depth Placement enabled unless you want to hold a manually selected focus.
  • After using Looking Glass, reload the page before starting the experimental generic VR mode.

Implementation and calibration details are kept in OPTIMIZATION_DETAILS.md.

Video Source and Local Cache

When you select Open Video, the browser plays the selected file and makes a temporary copy available to the local Python backend for depth processing. With the standard localhost setup, the video does not leave your computer and is not uploaded to an external service. The application does not keep the entire video in RAM.

Temporary source files are stored below tmp/sessions/. In the standard setup, an older session is removed when a new one is created, so only the latest source copy remains. In LAN mode, the phone sends that copy directly to the PC over the local network. With Tailscale Serve, it crosses the encrypted tailnet instead. Neither method sends the video to an application cloud service. Other remote configurations require their own server and security setup.

Display Modes

  • Normal (PC 2D/3D): Three.js draws video + depth mesh on the page.
  • SBS Stereo (0DOF): Shows left- and right-eye images side by side without head tracking. Use Swap L/R if the eye order is reversed on your display.
  • VR: Shows the 3D video in a WebXR headset. This mode is experimental.
  • Looking Glass: Sends the reconstructed video to a connected Looking Glass. See Using a Looking Glass for setup, controls, and troubleshooting.

Viewer Controls

  • Projection: Keep pinhole for the most natural geometry. Use relief only when you want a stylized or compatibility view.
  • Framing: Auto Source View is the recommended default. It fits the whole source and avoids the fan-shaped look caused by an unsuitable camera position. The wheel zooms around the pointer, either mouse button can drag to pan, and a double-click resets zoom and pan. Select Free Orbit when you want to rotate the scene.
  • Min View FOV Y / Source FOV Y: These are advanced lens/framing controls. Most videos should be left at their automatic/default values.
  • Orbit Distance / Model Z Offset: Auto Source View manages these values and disables their sliders. Select Free Orbit to place the camera and model manually.
  • Looking Glass: Use the dedicated controls described in Using a Looking Glass. The default automatic framing and depth placement are recommended for normal viewing.
  • Manual target tris: Advanced mesh-density control. Higher values can show more depth detail but require more GPU work.
  • Creative controls: Z Scale, Z Bias, Z Gamma, and Plane Scale shape the stylized relief view. They are not needed for the recommended pinhole mode.

Automatic Performance Modes

  • Auto Smooth: Targets 30 applied depth FPS and starts with the smallest depth raster and mesh-density budget.
  • Auto Balanced (default): Targets 30 applied depth FPS with a medium depth raster and log8 transport.
  • Auto Quality: Targets 24 FPS, starts at the configured maximum inference resolution and linear16, then reduces precision before spatial quality when the network is limiting.
  • Manual / Creative: Disables automatic quality changes and honors the backend environment settings and manual mesh-density slider.

Auto Balanced is the recommended starting point. Automatic modes adjust depth resolution, transfer size, and mesh density to keep playback smooth; they do not reduce RGB playback quality. The separate codec fallback may create a high-quality H.264 copy only when the browser cannot play the source directly. The achieved depth FPS cannot exceed the source video's FPS. Use Manual / Creative only when you want to tune the advanced controls yourself.

Advanced Configuration

Most users should start with Auto Balanced and leave these values unchanged. For manual tuning, you can use backend environment variables and frontend URL parameters.

For a full breakdown of optimization strategies and telemetry knobs, see OPTIMIZATION_DETAILS.md.

Backend Environment Variables:

Variable Default Description
VIDEO_DEPTH_INFER_WORKERS Windows: 2; others: 3 Concurrent inference tasks. Increase only after verifying GPU/VRAM headroom.
VIDEO_DEPTH_DECODER_WORKERS 4 Parallel software decoders. Increase carefully on many-core CPUs; each decoder also uses FFmpeg frame/slice threads.
VIDEO_DEPTH_DOWNSAMPLE 1 Depth downsample factor. Set 2 or 4 to reduce bandwidth and raise FPS.
VIDEO_DEPTH_PROCESS_RES 640 Max inference resolution. Lower (e.g., 384) for speed at cost of detail.
VIDEO_DEPTH_SOURCE_FOV_Y 50 Fallback source vertical FOV when the video has no camera intrinsics.
VIDEO_DEPTH_METRIC_REFERENCE_FOCAL_PX 300 DA3Metric canonical focal reference. Change only for a model with a different convention.
VIDEO_DEPTH_MODEL_ID depth-anything/DA3METRIC-LARGE Hugging Face model ID.
VIDEO_DEPTH_DEVICE auto Selects CUDA/ROCm-compatible, Intel XPU, Apple MPS, then CPU. Set an explicit PyTorch device to override.
VIDEO_DEPTH_HOST 127.0.0.1 Backend bind address. Keep the loopback default for normal local use.
VIDEO_DEPTH_PORT 8000 Backend listen port.
VIDEO_DEPTH_CACHE 8 Recent inferred-depth result cache size.
VIDEO_DEPTH_COMPRESSION 0 Zlib level (0–9). 0 disables compression and is recommended for localhost latency.
VIDEO_DEPTH_ENCODING log8 Manual-mode transport: log8 (half payload) or linear16 (maximum precision).
VIDEO_DEPTH_OPTIMIZATION_MODE balanced Initial backend mode: smooth, balanced, quality, or manual. The frontend selection takes over when streaming starts.
VIDEO_DEPTH_PROFILE_TIMING False Enable detailed timing logs.
VIDEO_DEPTH_LOG_LEVEL WARNING Log level (DEBUG, INFO, WARNING, ERROR). Set to INFO to see stats.
DA3_LOG_LEVEL WARN Depth Anything 3 log level. Set to INFO only when per-frame inference diagnostics are needed.
VIDEO_DEPTH_DATA_ROOT tmp/sessions Cache root for backend source copies. The default root is cleared before a new session; custom roots require VIDEO_DEPTH_CLEAR_CACHE=1 for automatic cleanup.
VIDEO_DEPTH_CLEAR_CACHE False Allow cache cleanup even when VIDEO_DEPTH_DATA_ROOT is not the default tmp/sessions.
UV_CACHE_DIR uv cache path (e.g., .uv-cache) to avoid download timeouts.

Frontend URL Parameters:

  • ?maxInflight=N: initial/manual concurrent-request limit (default 8). Automatic modes replace it from the inference-worker count.
  • ?debug=true: Enable verbose logging (Health stats, Perf metrics) in browser console.

Tests and Generated Media for Contributors

The repository does not require checked-in or copyrighted test videos. With FFmpeg and ffprobe available, generate the deterministic short fixture set and run both test suites:

uv run --locked --extra dev python scripts/generate_test_media.py --profile fast
uv run --locked --extra dev pytest -q
cd webapp
npm ci
npm test

Generated videos and their probed manifest.json are written below tmp/test-media/, which is ignored by Git. The fast profile covers CFR with audio, anamorphic SAR, portrait video, rotation metadata, and VFR/B-frames. For local resolution/FPS/codec sweeps (up to 4K and optional H.265/VP9/AV1), use:

uv run --locked --extra dev python scripts/generate_test_media.py --profile full

Unsupported optional encoders are reported as skipped. The fast H.264 cases are required and generation fails visibly if they cannot be produced or probed. The test suites also verify metric-scale invariance, known-K inverse projection, off-axis stereo math, SAR display geometry, and rotation direction.

For an optional real-model hardware report (not part of CPU CI), run:

uv run --locked --extra dev --extra inference python scripts/benchmark_pipeline.py \
  --process-res 640 --downsample 2 --encoding log8 \
  --output tmp/benchmark-balanced.json

The JSON records hardware/software versions, warmup/measured frame counts, per-frame data, p50/p95 stage latency, sequential FPS, metric focal scale, and payload bandwidth. Pass --video path/to/video.mp4 to benchmark private media without adding it to the repository.

Optimization Details

See OPTIMIZATION_DETAILS.md for optimization internals and telemetry.

License & Acknowledgements

This project is licensed under the Apache License 2.0. See LICENSE for details.

  • Depth Anything 3: This project utilizes the Depth Anything 3 model for depth estimation. Depth Anything 3 is licensed under the Apache License 2.0.
  • Three.js: Licensed under the MIT License.
  • FastAPI: Licensed under the MIT License.

日本語

概要

VideoDepthViewer3Dは、動画をリアルタイムで立体表示するビューアです。 ブラウザで動画を再生しながら、ローカルのPythonプロセスが Depth Anything 3 (DA3METRIC-LARGE) で奥行きを推定します。通常のモニター、SBS立体視、WebXR、Looking Glassで 結果を表示できます。

仕組み

  • ブラウザがコーデックに対応している場合は、元動画を本来の画質で表示します。 iPhoneのHEVC動画をPCブラウザが再生できない場合だけ、元動画を深度処理用に保持した まま、高品質なH.264表示用コピーを自動作成します。
  • ローカルのバックエンドが奥行きを推定し、深度データだけをビューアへ渡します。
  • ビューアは動画と同期する3Dの面を組み立てます。
  • 自動パフォーマンスモードが、使用中のGPU、CPU、通信環境に合わせて深度品質を 調整し、滑らかな再生を優先します。

実装、校正、性能計測の詳細は OPTIMIZATION_DETAILS.mdを参照してください。

セットアップと実行

  1. 依存関係のインストール (uv):
    uv venv .venv
    uv sync --locked --extra dev --extra inference
  2. ワンクリック起動(推奨):
    ./start.sh

このスクリプトは、バックエンド (port 8000) とフロントエンド (port 5173) の両方を起動します。

start.shはLinux、macOS、WSL、Git Bash用です。WindowsのPowerShellから 直接起動する場合は、下記の個別に起動する場合にある2つのコマンドを 別々のターミナルで実行してください。

Note

初回起動時: Depth Anything 3モデル(約1.3 GB)をダウンロードします。 ダウンロードとモデル読み込みが終わってから深度処理が始まるため、少し時間が かかります。

Important

アプリの再起動について: 先に実行中のstart.shをCtrl+Cで停止してから、 もう一度起動してください。複数同時に起動しないでください。ブラウザ画面は常に 5173番ポートを使うため、再起動後にページを更新します。

  1. 個別に起動する場合:
    • バックエンド:
      uv run --locked --extra inference python scripts/run_backend.py
    • フロントエンド:
      cd webapp
      npm ci
      npm run dev
    ブラウザで http://localhost:5173 にアクセスします。

バックエンドとフロントエンドは、デフォルトではこのPCからだけ接続できるアドレスへ bindします。通常のデスクトップ利用では、これが最も安全な設定です。

スマートフォンから動画を選択・操作する

iPhone、iPad、Android端末からPCへ動画を送れます。スマートフォンには、端末内 ファイルの動画プレビュー、転送進捗、再生・一時停止・シークだけを備えたコンパクトな 画面が開きます。深度推定とSBS、Looking Glass、WebXRへの切り替えはPCだけが 担当します。

SBS、Looking Glass、WebXRの開始にはPC側の操作が必要なので、通常はスマートフォンと PCを同じ場所、同じ信頼できるネットワーク内で使います。下記のLAN接続を推奨します。 Tailscaleは必須ではありません。

同じ信頼できるWi-Fiで使う(最も簡単)

自宅など、信頼できるプライベートネットワーク内だけで使用してください。

  1. Linux、macOS、WSL、Git Bashでは、LANモードで起動します。

    ./start.sh --lan

    WindowsのPowerShellでは、上記の個別に起動する場合と同じように2つの ターミナルを使い、フロントエンドの起動コマンドだけを次のようにします。

    npm run dev -- --host 0.0.0.0
  2. PCでは引き続きhttp://localhost:5173を使います。スマートフォンでは、Viteが Networkとして表示したURL(例: http://192.168.1.20:5173)を開きます。 0.0.0.0は待ち受け設定であり、ブラウザで開くアドレスではありません。

  3. PCのファイアウォールで遮断される場合は、信頼できるLANからのTCP 5173だけを 許可します。Windowsで確認画面が表示された場合は、プライベートネットワーク だけを選びます。UbuntuでUFWを使っている場合は、最初に有効か確認します。

    sudo ufw status

    有効な場合は、LANのsubnetだけを許可します。ネットワークのアドレス範囲が異なる 場合は、次の例にあるsubnetを置き換えてください。

    sudo ufw allow from 192.168.1.0/24 to any port 5173 proto tcp comment 'VideoDepthViewer3D LAN'

LANへ公開するのはフロントエンドだけです。Pythonバックエンドはloopbackのままにし、 フロントエンドのproxy経由で接続します。LANモードは通常のHTTP通信なので、公共・ ゲストWi-Fiでは使わず、ルーターから5173番ポートをインターネットへ転送しないで ください。

任意: 既存のTailnetを使う

PCとスマートフォンですでにTailscaleを使っている場合は、LANモードの代わりにServeを 利用できます。フロントエンドをloopbackのまま維持して非公開のHTTPS URLを作れますが、 表示モードを操作するPCビューアは引き続き必要です。

  1. PCとスマートフォンへTailscaleをインストールし、同じtailnetへログインします。 この使い方ではTailscale Funnelを使用しないでください。

  2. PCでVideoDepthViewer3Dを起動したままにし、PCブラウザでは http://localhost:5173を開きます。--lanを付けず、通常どおり起動します。

  3. PCの別ターミナルで Tailscale Serveを使い、 loopbackのフロントエンドだけをtailnetへ公開します。Windowsでは管理者権限の ターミナルを使ってください。他のOSでは、Tailscaleから求められた場合だけ 管理者権限を使います。

    tailscale serve --bg --https=443 5173

    初回は、tailnetでHTTPS証明書を有効にするよう求められることがあります。 表示されたURLを開いて許可してください。

    https://your-pc.your-tailnet.ts.netのような非公開HTTPS URLが表示されます。 tailscale serve statusでも確認できます。

  4. スマートフォンでそのHTTPS URLを開きます。モバイル用画面へ自動的に切り替わる ので、MOV、MP4、M4V、3GP、WebMなど、バックエンドが読める動画を選びます。

  5. スマートフォン内の元ファイルからすぐプレビューを始め、同時にPCへ一度だけ 転送します。Transfer completeと表示されるまではブラウザを前面に保って ください。PCで開いてあるビューアが転送後の動画へ自動的に切り替わります。

  6. スマートフォン側の動画で再生・一時停止・シークを行えます。SBS、Looking Glass、 WebXRは必要に応じてPCブラウザから開始します。

TCP 443を使うのが最も簡単です。すでに別のServe routeが443番を使っている場合は、 空いている別のHTTPS portを選び、access policyと停止コマンドにも同じportを指定します。 5173番を許可する必要はありません。Serveが選択したtailnet側のportからPC内部の loopbackへ転送します。

このアプリには独自のユーザーログイン機能がありません。tailnetのaccess policyを アクセス制限として使い、信頼できるuserまたはdeviceだけにこのportを許可してください。 許可された端末からは、現在の動画セッションを置き換えることができます。

有効な動画セッションは常に1つで、別の動画を選ぶと前のセッションを置き換えます。 PCブラウザがHEVCに対応していない場合はH.264表示用コピーを自動作成します。2K/4K 動画ではこの初回準備に時間がかかることがありますが、深度は元動画から推定します。 端末判定が合わない場合は、スマートフォンで?mode=remote、PCで?mode=viewerを URL末尾へ付けて明示できます。

Tailscale ServeではPythonバックエンドをloopbackのまま維持し、/apiとWebSocketを フロントエンド経由で転送します。後でこのHTTPS listenerだけを停止する場合は tailscale serve --https=443 offを実行します(別のportを選んだ場合は443を置き換えて ください)。他portのServe routeは維持されます。tailscale serve resetはそのPCの 全Serve routeを消すため、他のrouteを残したい場合は使用しないでください。

Looking Glassで使う

必要なもの

  • デスクトップディスプレイとして接続・有効化したLooking Glass。
  • Windows、macOS、Linux用の Looking Glass Bridge
  • ChromeなどのChromium系ブラウザを推奨します。Firefoxも利用できますが、 表示用ウィンドウを自分でLooking Glassへ移動する必要がある場合があります。 Safariには対応していません。

Windows上でLooking Glassを使う場合は、WSLではなく、Bridge、ブラウザ、フロント エンド、バックエンドをWindowsネイティブで起動する構成を使用してください。 Meta Quest Linkなどの一般的なWebXRは、Windows側のブラウザとXRランタイムが ヘッドセットとのセッションを担当します。そのため、アプリのサーバーはWindowsと WSLのどちらで起動しても、Windows側ブラウザからlocalhostでページを開けば利用 できます。

この順番で起動してください

  1. Looking Glassを接続して電源を入れます。
  2. Looking Glass Bridgeを起動し、ディスプレイが認識されるまで待ちます。 ビューアの使用中はBridgeを終了しないでください。
  3. 上記のセットアップ手順(Bashでは./start.sh、Windows PowerShellでは個別起動)で VideoDepthViewer3Dを起動し、http://localhost:5173を開きます。安定して 起動するため、ブラウザでページを開く、または再読み込みする前にBridgeを 起動しておくことを推奨します。
  4. Open Videoで動画を選びます。ブラウザ上で動画と3D表示の両方が 動き始めるまで待ってください。初回は深度モデルのダウンロードと読み込みに 時間がかかります。
  5. Enter Looking Glassを選び、ブラウザのポップアップとウィンドウ配置を 許可します。自動配置されない場合は、開いた表示用ウィンドウをLooking Glassへ 移動してください。
  6. Looking Glassディスプレイ上の表示用ウィンドウへマウスカーソルを移動し、 その画面内をダブルクリックします。表示用ウィンドウが全画面になり、正常な 3D表示に切り替わります。
  7. デバイスの準備が完了するとステータスがActiveになります。 Exit Looking Glassで通常のモニター表示へ戻れます。

macOSでは、Looking Glassを開始するときにブラウザをmacOSのフルスクリーン表示に せず、通常のデスクトップウィンドウで使用してください。外部ディスプレイへ表示用 ウィンドウを開けるようになります。

Looking Glassの操作

  • マウスホイール / Hologram Zoom: ピント位置を変えずに拡大・縮小します。 1×を通過するように戻すと、動画全体が入る初期サイズに合わせやすくなります。
  • 左右どちらかのボタンでドラッグ: 表示位置を上下左右へ移動します。 シーンは回転しません。
  • ドラッグせずにクリック: 選んだ点を奥行きの基準(ピント位置)にします。 ズームは変わらず、Resume Autoを選ぶまでピント位置を保持します。極端に遠い 点を選んだ場合は、背景への誤クリックを防ぐため、少し間を空けて同じ付近をもう 一度クリックすると確定します。
  • Auto Depth Placement: デフォルトのまま有効にすることを推奨します。 ズームと移動後に現在見えている範囲へ追従し、遠いシーンを手前へ寄せ、近すぎる 部分を見える範囲へ戻します。シーン切り替えや危険な手前表示では、手動のピント 固定を自動的に解除することがあります。
  • Resume Auto: クリックで固定したピントを解除し、その時点で見えている範囲の 自動配置へ戻します。
  • Focus Trim: 自動配置またはクリック後の奥行きを微調整します。
  • Reset Zoom / Pan: 拡大率と表示位置を初期状態へ戻します。

通常はAuto Source Viewを推奨します。接続したディスプレイに動画全体を収め、 動画の四辺をまっすぐに保ちます。Looking Glass Goのような縦長デバイスで横長動画を 表示すると上下に余白ができますが、元動画を切り取らずに全体を表示するための正常な 動作です。

困ったときは

  • Bridge unavailable: Looking Glass Bridgeを起動し、デバイスが認識されている ことを確認してから、もう一度Enter Looking Glassを選びます。
  • Blocked: localhost:5173のポップアップとウィンドウ管理を許可してから 再試行します。macOSではブラウザのフルスクリーン表示も解除してください。
  • Unverified: 表示用ウィンドウは開きましたが、デバイスの情報を取得できて いません。映像・USBケーブルと、Bridge上のデバイス認識を確認してください。
  • 正常な3D表示にならない: 表示用ウィンドウがLooking Glassディスプレイ上に あることを確認し、そのウィンドウ内へマウスカーソルを移動してダブルクリックし、 全画面表示にしてください。
  • 真っ黒、更新されない、位置がおかしい: Exit Looking Glassを選び、Bridgeが 起動済みであることを確認してブラウザをハードリロードします(Windows/Linuxは Ctrl+Shift+R、macOSはCmd+Shift+R)。動画をもう一度開き、動画と3D表示の両方が 動き始めてからLooking Glassへ入り直してください。
  • 大きすぎる、または中央からずれた: ホイールで縮小するか、 Reset Zoom / Panを選びます。手動でピントを固定したい場合を除き、 Auto Depth Placementは有効のままにしてください。
  • Looking Glassを使用した後に実験的な通常VRモードを開始する場合は、先にページを 再読み込みしてください。

内部の実装や校正方法は OPTIMIZATION_DETAILS.mdにまとめています。

動画と一時ファイル

Open Videoで動画を選ぶと、ブラウザが元動画を再生し、深度処理用の一時コピーを ローカルのPythonバックエンドへ渡します。標準のlocalhost構成では、動画がPCの外や 外部サービスへアップロードされることはありません。動画全体をメモリへ保持する 方式でもありません。

一時ファイルはtmp/sessions/以下に保存されます。標準構成では、新しいセッションの 開始時に以前のセッションを削除するため、最新の動画コピーだけが残ります。 LANモードでは、元動画のコピーがローカルネットワーク内でスマートフォンからPCへ直接 送られます。Tailscale Serveを使う場合は、暗号化されたtailnetを通ります。どちらも アプリのクラウドサービスへ動画を送信しません。それ以外のリモート構成には、別途 サーバーとセキュリティの設定が必要です。

表示モード

  • 通常 (PC 2D/3D): Three.js が動画と深度メッシュを描画。
  • SBS Stereo (0DOF): 左目用と右目用の映像を横に並べます。頭の動きには 追従しません。左右が逆に見える場合はSwap L/Rを有効にします。
  • VR: WebXR対応ヘッドセットへ3D動画を表示します。現在は実験的な機能です。
  • Looking Glass: 再構成した動画を接続中のLooking Glassへ表示します。 セットアップ、操作、トラブル対処は Looking Glassで使うを参照してください。

ビューア設定

  • Projection: 最も自然な形状になるpinholeを推奨します。意図的にデフォルメした 表示や互換性が必要な場合だけreliefを使用します。
  • Framing: Auto Source Viewが推奨のデフォルトです。動画全体を画面へ収め、 不適切なカメラ位置による扇形の見え方を避けます。ホイールでカーソル周辺を 拡大・縮小し、左右どちらかのボタンでドラッグすると移動、ダブルクリックで 拡大率と位置を戻せます。シーンを回転したい場合はFree Orbitを選びます。
  • Min View FOV Y / Source FOV Y: レンズと画角の高度な設定です。通常の動画では 自動値・デフォルト値のまま使用してください。
  • Orbit Distance / Model Z Offset: Auto Source Viewでは自動管理されるため、 スライダーは無効です。カメラとモデルの位置を手動調整する場合はFree Orbitを 選びます。
  • Looking Glass: 専用操作は Looking Glassの操作を参照してください。通常はデフォルトの 自動画角調整と自動奥行き配置を推奨します。
  • Manual target tris: メッシュ密度の高度な設定です。値を上げると奥行きの細部を 表現しやすくなりますが、GPU負荷も増えます。
  • クリエイティブ設定: Z ScaleZ BiasZ GammaPlane Scaleは、 relief表示を意図的に変形するための設定です。推奨のpinholeでは不要です。

自動パフォーマンスモード

  • Auto Smooth: 適用済みdepth 30 FPSを目標に、最小のdepth rasterとmesh密度から開始します。
  • Auto Balanced(デフォルト): 30 FPSを目標に、中程度のdepth rasterとlog8転送を使います。
  • Auto Quality: 24 FPSを目標に、設定上限の推論解像度とlinear16から開始し、ネットワークが律速すると空間解像度より先に精度を下げます。
  • Manual / Creative: 自動変更を停止し、環境変数と手動mesh設定を尊重します。

最初はAuto Balancedを推奨します。自動モードは、滑らかな表示を保つために深度の 解像度、転送量、メッシュ密度を調整します。ブラウザで再生する元のRGB動画の画質は 下げません。別系統のcodec fallbackは、ブラウザが元動画を直接再生できない場合だけ 高品質なH.264コピーを作成します。深度FPSは元動画のFPSを超えません。各項目を自分で 調整したい場合だけManual / Creativeを選んでください。

高度な設定

通常はAuto Balancedから始め、以下の値は変更しないことを推奨します。手動調整が 必要な場合は、バックエンドの環境変数とフロントエンドのURLパラメータを使用できます。

最適化の仕組みや計測項目の詳しい解説は OPTIMIZATION_DETAILS.md を参照してください。

バックエンド環境変数:

変数名 デフォルト 説明
VIDEO_DEPTH_INFER_WORKERS Windows: 2; その他: 3 同時推論タスク数。GPU/VRAMの余裕を確認できた場合だけ増やしてください。
VIDEO_DEPTH_DECODER_WORKERS 4 software decoder並列数。各decoderもFFmpeg内部threadを使うため、多core CPUで慎重に増やしてください。
VIDEO_DEPTH_DOWNSAMPLE 1 深度マップのダウンサンプル係数。2 または 4 で帯域削減と FPS 向上。
VIDEO_DEPTH_PROCESS_RES 640 推論の最大解像度。値を下げると高速化するがディテール低下。
VIDEO_DEPTH_SOURCE_FOV_Y 50 カメラ内部パラメータがない動画で使うsource垂直FOV。
VIDEO_DEPTH_METRIC_REFERENCE_FOCAL_PX 300 DA3Metricの基準焦点距離。異なる規約のモデル以外では変更不要。
VIDEO_DEPTH_MODEL_ID depth-anything/DA3METRIC-LARGE Hugging Face のモデル ID。
VIDEO_DEPTH_DEVICE auto CUDA/ROCm互換、Intel XPU、Apple MPS、CPUの順に自動選択。PyTorch deviceを明示して上書き可能。
VIDEO_DEPTH_HOST 127.0.0.1 backendのbindアドレス。通常のローカル利用では変更しないでください。
VIDEO_DEPTH_PORT 8000 backendの待受port。
VIDEO_DEPTH_CACHE 8 直近の推論済みdepth結果cache数。
VIDEO_DEPTH_COMPRESSION 0 Zlib圧縮レベル(0–9)。0は圧縮無効で、localhostの低遅延用途に推奨。
VIDEO_DEPTH_ENCODING log8 Manualモードの転送形式。log8(半分の転送量)またはlinear16(最大精度)。
VIDEO_DEPTH_OPTIMIZATION_MODE balanced 初期モード。smoothbalancedqualitymanual。ストリーミング開始後はフロントエンド選択が優先されます。
VIDEO_DEPTH_PROFILE_TIMING False 詳細なタイミングログを有効化。
VIDEO_DEPTH_LOG_LEVEL WARNING log level(DEBUG、INFO、WARNING、ERROR)。統計表示にはINFOを使用。
DA3_LOG_LEVEL WARN Depth Anything 3のlog level。frame単位の推論診断が必要な場合だけINFOに設定。
VIDEO_DEPTH_DATA_ROOT tmp/sessions backend source copyのroot。default rootは新session前に削除され、custom rootの自動削除にはVIDEO_DEPTH_CLEAR_CACHE=1が必要です。
VIDEO_DEPTH_CLEAR_CACHE False VIDEO_DEPTH_DATA_ROOT がデフォルト以外でもキャッシュ削除を許可します。
UV_CACHE_DIR uv のキャッシュパス(例: .uv-cache)。ダウンロード失敗を防止。

フロントエンド URL パラメータ:

  • ?maxInflight=N: 初期値またはManual時の同時request上限(デフォルト8)。自動modeでは推論worker数から再設定されます。

コントリビューター向けテストと自動生成動画

著作権のあるテスト動画をリポジトリへ同梱する必要はありません。 FFmpeg と ffprobe が利用できる環境で、短い決定論的fixtureとテストを次のように実行できます。

uv run --locked --extra dev python scripts/generate_test_media.py --profile fast
uv run --locked --extra dev pytest -q
cd webapp
npm ci
npm test

生成動画と実測メタデータの manifest.json は、Git対象外の tmp/test-media/ に保存されます。fast は音声付きCFR、アナモルフィック SAR、縦動画、回転メタデータ、VFR/B-frameを網羅します。4Kまでの解像度、 24/30/60fps、H.264/H.265/VP9/AV1をローカルで比較する場合は次を使います。

uv run --locked --extra dev python scripts/generate_test_media.py --profile full

任意コーデックのエンコーダーがない場合はskip理由を表示します。fastの H.264ケースは必須で、生成またはffprobe検証に失敗した場合は明示的に失敗します。 テストではmetric尺度不変性、既知Kの逆投影、off-axis stereo数式、SAR表示寸法、回転方向も検証します。

実モデルを使う任意のハードウェア計測(CPU CI対象外)は次で実行できます。

uv run --locked --extra dev --extra inference python scripts/benchmark_pipeline.py \
  --process-res 640 --downsample 2 --encoding log8 \
  --output tmp/benchmark-balanced.json

JSONにはハードウェア/ソフトウェア版、warmup/計測frame数、frame別データ、 stage別p50/p95、逐次FPS、metric焦点倍率、payload帯域が記録されます。 --video path/to/video.mp4で非公開動画もリポジトリへ追加せず計測できます。

最適化ドキュメント

最適化の仕組みや計測項目の詳しい解説は OPTIMIZATION_DETAILS.md を参照してください。

License & Acknowledgements

This project is licensed under the Apache License 2.0. See LICENSE for details.

  • Depth Anything 3: This project utilizes the Depth Anything 3 model for depth estimation. Depth Anything 3 is licensed under the Apache License 2.0.
  • Three.js: Licensed under the MIT License.
  • FastAPI: Licensed under the MIT License.

About

Real-time 3D video player powered by Depth Anything 3. Stream MP4s to WebXR/VR with metric depth estimation.

Resources

License

Stars

107 stars

Watchers

1 watching

Forks

Packages

 
 
 

Contributors