Skip to content

Desktop app for comparing two videos side by side with synchronized playback, trimming, and combined export. Built with Tauri + React + FFmpeg.

License

Notifications You must be signed in to change notification settings

vMyth/video-compare

Repository files navigation

Video Compare

A desktop application for comparing two videos side by side with synchronized playback, trimming, and combined export.

Features

Core Features

  • Side-by-Side Video Viewing: Load two videos and view them simultaneously
  • Synchronized Playback: Both videos play perfectly in sync with shared controls
  • Video Trimming: Automatically trim longer videos to match duration (front or back trim)
  • Combined Export: Export both videos as a single side-by-side video using FFmpeg

Playback Controls

  • Play/Pause: Space bar or click the play button
  • Seek: Click anywhere on the progress bar or use arrow keys (5 second jumps)
  • Frame-by-Frame Navigation: Step through frames with , and . keys
  • Mute/Unmute: Press M to toggle audio

Additional Features

  • Drag & Drop: Drop video files directly onto the video slots
  • Swap Videos: Press S to swap left and right videos
  • Video Info Overlay: Press I to show resolution and duration overlay
  • Audio Source Selection: Choose audio from Video 1, Video 2, or no audio in export
  • Export Presets: Choose encoding speed (ultrafast to slow) and quality
  • Real-time Export Progress: Live progress bar with percentage during export
  • Cancel Export: Stop export at any time (partial file is deleted)
  • Loading States: Visual feedback while videos load
  • Error Handling: Clear error messages when video loading fails

Keyboard Shortcuts

Key Action
Space Play/Pause
Seek back 5 seconds
Seek forward 5 seconds
, Previous frame
. Next frame
M Toggle mute
S Swap videos
I Toggle info overlay

Tech Stack

  • Frontend: React 19 + TypeScript + Tailwind CSS v4
  • Backend: Tauri 2.0 (Rust)
  • State Management: Zustand
  • Video Processing: FFmpeg (bundled as sidecar)

Installation

Download Pre-built Installer

Download the latest release from the Releases page:

  • Windows: Video Compare_x.x.x_x64-setup.exe (NSIS installer)
  • Windows MSI: Video Compare_x.x.x_x64_en-US.msi

Build from Source

Prerequisites

Steps

  1. Clone the repository

    git clone https://github.com/vMyth/video-compare.git
    cd video-compare
  2. Install dependencies

    npm install
  3. Download FFmpeg

    Download the FFmpeg binary for your platform and place it in src-tauri/binaries/:

    • Windows: Name it ffmpeg-x86_64-pc-windows-msvc.exe
    • macOS (Intel): Name it ffmpeg-x86_64-apple-darwin
    • macOS (Apple Silicon): Name it ffmpeg-aarch64-apple-darwin
    • Linux: Name it ffmpeg-x86_64-unknown-linux-gnu
  4. Run in development mode

    npm run tauri dev
  5. Build for production

    npm run tauri build

    The installers will be generated in src-tauri/target/release/bundle/

Usage

Loading Videos

  1. File Picker: Click "Select Video 1" or "Select Video 2" buttons
  2. Drag & Drop: Drop video files directly onto the left or right video slot

Playback

  • Videos are automatically synchronized
  • Controls are disabled until both videos are loaded
  • Use keyboard shortcuts or on-screen controls

Trimming

When videos have different durations:

  1. Trim Mode: Choose "Trim Front" or "Trim Back" to align videos
  2. Enable/Disable: Toggle trimming on or off
  3. The longer video is automatically trimmed to match the shorter one

Exporting

  1. Click "Export Side-by-Side" button
  2. Configure export settings:
    • Preset: ultrafast (fast encoding) to slow (better compression)
    • Quality: 0-51 CRF value (lower = better quality, larger file)
    • Audio Source: None, Video 1, or Video 2
  3. Choose save location
  4. Monitor progress with real-time percentage
  5. Cancel anytime if needed

Supported Video Formats

The application supports all video formats that FFmpeg can process:

  • MP4, MKV, AVI, MOV, WebM
  • H.264, H.265/HEVC, VP9, AV1
  • And many more

Export Settings

The exported video uses:

  • Resolution: 1280x720 (640x720 per video, scaled and padded)
  • Codec: H.264 (libx264)
  • Audio Codec: AAC (when audio source is selected)

Project Structure

video-compare/
├── src/                          # React frontend
│   ├── app/
│   │   └── App.tsx               # Main app component
│   ├── features/
│   │   ├── video-player/
│   │   │   ├── components/
│   │   │   │   ├── SyncedVideoPlayer.tsx  # Main video display
│   │   │   │   └── VideoControls.tsx      # Playback controls
│   │   │   └── hooks/
│   │   │       └── useVideoSync.ts        # Sync logic
│   │   ├── file-picker/
│   │   │   └── components/
│   │   │       └── FilePicker.tsx         # File selection
│   │   ├── trim/
│   │   │   └── components/
│   │   │       ├── TrimControls.tsx       # Trim UI
│   │   │       ├── TrimSlider.tsx         # Trim range slider
│   │   │       └── TrimNumberInput.tsx    # Manual trim input
│   │   └── export/
│   │       ├── components/
│   │       │   └── ExportModal.tsx        # Export dialog
│   │       └── hooks/
│   │           └── useExport.ts           # Export logic
│   ├── stores/
│   │   └── videoStore.ts          # Zustand state
│   ├── services/
│   │   └── tauri.ts               # Tauri helpers
│   └── main.tsx                   # Entry point
├── src-tauri/                     # Rust backend
│   ├── src/
│   │   └── lib.rs                 # FFmpeg commands
│   ├── binaries/                  # FFmpeg sidecar
│   ├── capabilities/              # Tauri permissions
│   ├── icons/                     # App icons
│   ├── Cargo.toml                 # Rust dependencies
│   └── tauri.conf.json            # Tauri config
├── package.json
└── README.md

Development

Available Scripts

Command Description
npm run dev Start Vite dev server
npm run build Build frontend for production
npm run tauri dev Run app in development mode
npm run tauri build Build production installers
npm run tauri icon <path> Generate app icons from image

Architecture

  • State Management: Zustand store manages video paths, durations, trim settings, and playback state
  • Video Sync: Custom hook using requestAnimationFrame keeps both videos synchronized
  • FFmpeg Integration: Rust backend spawns FFmpeg as a sidecar process with progress streaming
  • Drag & Drop: Uses Tauri's native file drop events with position-based hit detection

Troubleshooting

Videos not loading

Make sure the asset protocol is enabled in tauri.conf.json:

"security": {
  "assetProtocol": {
    "enable": true,
    "scope": ["**"]
  }
}

FFmpeg not found

Ensure the FFmpeg binary is in src-tauri/binaries/ with the correct platform-specific name:

"bundle": {
  "externalBin": ["binaries/ffmpeg"]
}

Export fails

  • Check that both videos are loaded
  • Ensure you have write permission to the output directory
  • Try a different output location

Controls are disabled

Playback controls require both videos to be loaded. Load a second video to enable controls.

Security

The application uses minimal permissions:

  • shell:allow-spawn/kill: Required for FFmpeg process
  • dialog:allow-open/save: Required for file pickers
  • fs:read-all: Required to load videos from any location

CSP is configured to prevent script injection (no unsafe-eval in production).

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

About

Desktop app for comparing two videos side by side with synchronized playback, trimming, and combined export. Built with Tauri + React + FFmpeg.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages