Sign inSign up

gafda/vidupe-net

By gafda

โ€ขUpdated 5 months ago

High-performance video duplicate finder.

Image
Content management system
1

987

gafda/vidupe-net repository overview

โ Vidupe.Net

GitHub

High-performance video duplicate finder โ€” powered by .NET 10, Blazor Server, FFmpeg, and optional GPU acceleration (NVIDIA CUDA ยท AMD ROCm/OpenCL ยท Intel OpenCL ยท CPU fallback).

๐Ÿ‘ค Developer: @gafdaโ 
๐Ÿ“„ License: GPL v3


main

โ What is Vidupe.Net?

Vidupe.Net scans your video library and surfaces near-duplicate files through seven complementary algorithms:

AlgorithmSpeedAccuracyDescription
CLIPโ˜…โ˜…โ˜†โ˜†โ˜†โ˜…โ˜…โ˜…โ˜…โ˜…+Semantic visual matching via CLIP ViT-B/32 (ONNX, GPU recommended)
LPIPSโ˜…โ˜…โ˜†โ˜†โ˜†โ˜…โ˜…โ˜…โ˜…โ˜…Deep perceptual distance via AlexNet backbone (ONNX, GPU recommended)
SSIMโ˜…โ˜…โ˜…โ˜†โ˜†โ˜…โ˜…โ˜…โ˜…โ˜†Structural Similarity Index (GPU-accelerable via ILGPU)
pHashโ˜…โ˜…โ˜…โ˜…โ˜…โ˜…โ˜…โ˜…โ˜†โ˜†DCT perceptual hash โ€” fast structural fingerprinting
dHashโ˜…โ˜…โ˜…โ˜…โ˜…โ˜…โ˜…โ˜…โ˜†โ˜†Gradient-based difference hash โ€” robust to scaling
Histogramโ˜…โ˜…โ˜…โ˜…โ˜…โ˜…โ˜…โ˜†โ˜†โ˜†Color distribution correlation
MSEโ˜…โ˜…โ˜…โ˜…โ˜…โ˜…โ˜†โ˜†โ˜†โ˜†Mean Squared Error โ€” pixel-level comparison

Results appear in a clean browser UI with side-by-side previews, metadata comparison, and one-click delete or ignore actions. Everything is cached in SQLite so repeated scans are instant.


โ Image tags

Tags follow semantic versioningโ  (X.Y.Z).

TagArchitectureDescription
latestamd64 + arm64Multi-arch alias for the most recent stable release
1.8.0amd64 + arm64Current stable release

Both tags are multi-arch manifest lists โ€” Docker and Podman automatically pull the correct image for your host architecture. Use an exact X.Y.Z tag for reproducible deployments; latest is convenient for quick testing.


โ Origin & Credits

Vidupe.Net is an independent implementation inspired by the original vidupeโ  created by Kristian Koskimรคki.

While this is a completely separate codebase written in .NET, it honors the legacy of the original tool by continuing its mission to provide a powerful, open-source solution for video library management. We are grateful for the conceptual foundation laid by the original project.


โ Quick start

# Docker
docker run -d \
  --name vidupe \
  -p 8080:8080 \
  -v /path/to/your/videos:/videos:rw \
  -v vidupe-data:/data \
  gafda/vidupe-net:1.8.0

# Podman
podman run -d \
  --name vidupe \
  -p 8080:8080 \
  -v /path/to/your/videos:/videos:rw \
  -v vidupe-data:/data \
  gafda/vidupe-net:1.8.0

Then open http://localhost:8080โ  in your browser, add /videos as a scan folder, and start scanning.


โ Docker Compose

โ Basic (CPU only)
services:
  vidupe:
    image: gafda/vidupe-net:1.8.0
    container_name: vidupe
    ports:
      - "8080:8080"
    volumes:
      # Your video library (read-only is enough for scanning but not for removal)
      - /path/to/videos:/videos:ro
      # Add as many source directories as you need
      # - /mnt/nas/clips:/clips:ro
      # Persistent cache database and settings
      - vidupe-data:/data
    environment:
      - Vidupe__DataDirectory=/data
    restart: unless-stopped

volumes:
  vidupe-data:

โ GPU Acceleration

Vidupe.Net uses two independent GPU systems โ€” ILGPU (pHash DCT, SSIM) and ONNX Runtime (CLIP, LPIPS). The container image is GPU-agnostic โ€” GPU drivers are injected at runtime by the host toolkit. Add the relevant section to your Compose service and choose only one.

โ NVIDIA (CUDA)

Docker: Install nvidia-container-toolkitโ .
Podman: Install nvidia-ctk CDIโ .

# Docker Compose
services:
  vidupe:
    image: gafda/vidupe-net:1.8.0
    container_name: vidupe
    ports:
      - "8080:8080"
    volumes:
      - /path/to/videos:/videos:ro
      - vidupe-data:/data
    environment:
      - Vidupe__DataDirectory=/data
    restart: unless-stopped
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]

volumes:
  vidupe-data:
# Podman (CDI-based, no compose changes needed)
podman run -d --name vidupe -p 8080:8080 \
  --device nvidia.com/gpu=all \
  -v /path/to/videos:/videos:ro \
  -v vidupe-data:/data \
  gafda/vidupe-net:1.8.0

Verify GPU access:

# Docker
docker run --rm --gpus all nvidia/cuda:12.6.0-base-ubuntu24.04 nvidia-smi
# Podman
podman run --rm --device nvidia.com/gpu=all nvidia/cuda:12.6.0-base-ubuntu24.04 nvidia-smi

โ AMD (ROCm / OpenCL)

Prerequisite: AMDGPU kernel module and ROCm runtime on the host.
Desktop cards RX 5000+ work with the open-source amdgpu driver.

services:
  vidupe:
    image: gafda/vidupe-net:1.8.0
    container_name: vidupe
    ports:
      - "8080:8080"
    volumes:
      - /path/to/videos:/videos:ro
      - vidupe-data:/data
    devices:
      - /dev/kfd:/dev/kfd
      - /dev/dri:/dev/dri
    group_add:
      - video
      - render
    environment:
      - Vidupe__DataDirectory=/data
    restart: unless-stopped

volumes:
  vidupe-data:
# Podman equivalent
podman run -d --name vidupe -p 8080:8080 \
  --device /dev/kfd --device /dev/dri \
  --group-add video --group-add render \
  -v /path/to/videos:/videos:ro \
  -v vidupe-data:/data \
  gafda/vidupe-net:1.8.0

โ Intel (Arc / Iris / integrated graphics, OpenCL)

Prerequisite: i915 or xe kernel driver and Intel compute runtime (intel-opencl-icd) on the host.

services:
  vidupe:
    image: gafda/vidupe-net:1.8.0
    container_name: vidupe
    ports:
      - "8080:8080"
    volumes:
      - /path/to/videos:/videos:ro
      - vidupe-data:/data
    devices:
      - /dev/dri:/dev/dri
    group_add:
      - video
      - render
    environment:
      - Vidupe__DataDirectory=/data
    restart: unless-stopped

volumes:
  vidupe-data:
# Podman equivalent
podman run -d --name vidupe -p 8080:8080 \
  --device /dev/dri \
  --group-add video --group-add render \
  -v /path/to/videos:/videos:ro \
  -v vidupe-data:/data \
  gafda/vidupe-net:1.8.0

โ Force CPU mode (disable GPU)

Set Vidupe__PreferCpu=true to disable GPU detection entirely:

environment:
  - Vidupe__DataDirectory=/data
  - Vidupe__PreferCpu=true

โ Volumes

PathPurposeNotes
/dataSQLite cache DB + settingsMust be persistent โ€” mount a named volume or host path
/videos (or any path)Video source directoriesRead-only (:ro) is sufficient for scanning; add as many as needed. Read-Write (:rw) if intended to delete files.
# Named volume (recommended)
-v vidupe-data:/data

# Host path (alternative)
-v /home/user/.vidupe:/data

โ Environment variables

VariableDefaultDescription
Vidupe__DataDirectory/dataDirectory for the SQLite cache and settings file
Vidupe__PreferCpufalseSet to true to skip GPU detection and use CPU only

โ Accessing over the network

By default Vidupe.Net listens on port 8080. Map it to any host port:

# Access on port 80
-p 80:8080

# Bind only to localhost (reverse-proxy setup)
-p 127.0.0.1:8080:8080

For HTTPS, place a reverse proxy (e.g. Caddy, Nginx, Traefik) in front and forward requests to port 8080.


โ Mounting network shares (NAS / SMB / NFS)

Pre-mount the share on the host, then bind-mount the directory into the container:

# Mount a Samba share on the host first
sudo mount -t cifs //192.168.1.100/videos /mnt/nas-videos \
  -o username=user,password=pass,vers=3.0

# Then reference the host mount in Docker Compose
volumes:
  - /mnt/nas-videos:/nas-videos:ro

Alternatively, use Docker named volumes with the local driver:

volumes:
  nas-videos:
    driver: local
    driver_opts:
      type: cifs
      o: "username=user,password=pass,vers=3.0"
      device: "//192.168.1.100/videos"

โ Upgrading

# Docker
docker pull gafda/vidupe-net:1.8.0
docker compose up -d

# Podman
podman pull gafda/vidupe-net:1.8.0
podman stop vidupe && podman rm vidupe
# Re-run with same volumes (data is preserved)

The SQLite cache and settings in /data are forward-compatible between minor versions. A fresh scan after upgrading reuses all cached metadata.


โ Troubleshooting

SymptomSolution
Page does not loadCheck docker logs vidupe โ€” FFmpeg or port conflict
GPU not detectedVerify host drivers and toolkit, then check logs for ILGPU/ONNX output
CLIP/LPIPS on CPU despite GPUONNX Runtime CUDA needs CUDA Toolkit 12.x + cuDNN 9.x on the host (injected via nvidia-ctk)
Scan finds no videosConfirm the volume mount path is correct with docker exec vidupe ls /videos
Volumes empty on Podman + SELinux (Fedora, Bazzite, RHEL)Add :z to each -v flag to relabel the mount: -v /path/to/videos:/videos:ro,z
Very slow first scanExpected โ€” subsequent scans use cache and are near-instant
Out of memory on large librariesRaise the container memory limit; the app will auto-pause and resume
# Stream live logs
docker logs -f vidupe
podman logs -f vidupe

# Open a shell inside the container
docker exec -it vidupe /bin/bash
podman exec -it vidupe /bin/bash

โ Architecture and technical notes

  • Runtime: .NET 10, published as a self-contained single-file binary
  • UI: Blazor Interactive Server (WebSocket-based, no npm/webpack)
  • Cache: SQLite in WAL mode โ€” safe for concurrent reads across scans
  • GPU (ILGPU): CUDA โ†’ OpenCL โ†’ CPU fallback for pHash DCT and SSIM
  • GPU (ONNX Runtime): CUDA โ†’ ROCm โ†’ CPU fallback for CLIP and LPIPS neural networks
  • FFmpeg: Bundled via the ffmpeg apt package โ€” supports all common codecs
  • Container: GPU-agnostic image; NVIDIA/AMD/Intel drivers injected at runtime via host toolkit
  • pHash Pre-filter: Optional per-position pHash pre-filter with adjustable threshold (0โ€“64 bits) rejects dissimilar pairs before the selected algorithm runs. Enable or disable in Advanced Settings

Vidupe.Net โ€” find the duplicates, reclaim the space.

Tag summary

Content type

Image

Digest

sha256:1b6d256d4โ€ฆ

Size

809.1 MB

Last updated

5 months ago

docker pull gafda/vidupe-net