destrobe


Namedestrobe JSON
Version 1.0.0 PyPI version JSON
download
home_pageNone
SummaryCross-platform CLI tool for reducing video strobing and flicker while preserving audio and sync
upload_time2025-08-16 01:26:08
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseNone
keywords video flicker strobe photosensitive epilepsy accessibility cli
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # destrobe

**CLI tool for reducing video strobing and flicker**

A cross-platform Python CLI that reduces strobing/flicker in videos while preserving audio and sync. Designed to be simple, fast, and safe-by-default for photosensitivity concerns.

## ⚠️ Important Safety Notice

**destrobe reduces flashing but cannot guarantee complete removal of all photosensitive triggers.** Always preview content first if you have photosensitive epilepsy or similar conditions. Use at your own discretion.

### ⚠️ Example Files Warning

**The example videos in the `examples/` directory contain rapid flashing and strobing effects that may trigger photosensitive epilepsy or seizures.** These files are included specifically to demonstrate destrobe's flicker reduction capabilities on challenging content. **DO NOT VIEW the original files directly if you have photosensitive epilepsy or related conditions.** Only view the processed versions (e.g., `examples/porygon_ULTRA.preview.mp4`) which have had the flashing significantly reduced.

## Quick Start

```bash
# Install with pipx (recommended)
pipx install destrobe

# Basic usage - process a video with default settings
destrobe run input.mp4

# Preview before processing (recommended)
destrobe preview input.mp4

# Batch process a directory
destrobe run /path/to/videos --recursive

# Use stronger filtering
destrobe run input.mp4 --preset strong
```

## Features

- **Three filtering methods**: Temporal median (`median3`), motion-aware smoothing (`ema`), and flash detection/capping (`flashcap`)
- **Safe presets**: `safe`, `balanced`, and `strong` configurations for different needs
- **Audio preservation**: Automatically remux original audio using FFmpeg when available
- **Batch processing**: Process individual files or entire directories recursively
- **Preview mode**: Generate side-by-side comparisons before full processing
- **Quality metrics**: Measure flicker reduction and structural similarity
- **Performance monitoring**: Built-in benchmarking and progress tracking
- **Cross-platform**: Works on macOS, Linux, and Windows

## Installation

### Using pipx (Recommended)

```bash
# Install from PyPI (simplest)
pipx install destrobe

# Or install from GitHub (latest development version)
pipx install git+https://github.com/samjhill/destrobe.git
```

### Using pip

```bash
# Install from PyPI
pip install destrobe

# Or install from GitHub
pip install git+https://github.com/samjhill/destrobe.git
```

### From Source

```bash
git clone https://github.com/samhilll/destrobe.git
cd destrobe
pip install -e .
```

### Requirements

- Python 3.10+
- FFmpeg (optional, for audio remux)
- Dependencies: OpenCV, NumPy, scikit-image, typer, rich, tqdm

## Usage

### Basic Commands

#### Process Videos

```bash
# Process single file
destrobe run video.mp4

# Process multiple files
destrobe run video1.mp4 video2.mkv video3.avi

# Process directory (non-recursive)
destrobe run /path/to/videos

# Process directory recursively
destrobe run /path/to/videos --recursive
```

#### Preview Mode

```bash
# Create 10-second preview starting at 30 seconds
destrobe preview video.mp4

# Custom preview settings
destrobe preview video.mp4 --seconds 15 --start 00:01:30 --method ema
```

#### Analyze Metrics

```bash
# Show flicker metrics
destrobe metrics video.mp4

# Output as JSON
destrobe metrics video.mp4 --json
```

### Filtering Methods

#### `median3` (Default)
Temporal median filter using 3-frame window. Excellent for removing isolated flashes while preserving motion.

```bash
destrobe run video.mp4 --method median3
```

#### `ema` (Exponential Moving Average)
Motion-aware temporal smoothing. Adapts filtering strength based on detected motion.

```bash
destrobe run video.mp4 --method ema --strength 0.7
```

#### `flashcap` (Flash Detection & Capping)
Detects sudden brightness spikes and caps them. Best for content with known flash patterns.

```bash
destrobe run video.mp4 --method flashcap --flash-thresh 0.10
```

### Presets

#### `safe` (Recommended for sensitive viewers)
- Method: `flashcap`
- Strength: 0.7
- Flash threshold: 0.10

```bash
destrobe run video.mp4 --preset safe
```

#### `balanced` (Default)
- Method: `median3`
- Balanced between quality and flicker reduction

```bash
destrobe run video.mp4 --preset balanced
```

#### `strong` (Maximum reduction)
- Method: `ema`
- Strength: 0.75
- More aggressive filtering

```bash
destrobe run video.mp4 --preset strong
```

### Advanced Options

```bash
destrobe run input.mp4 \
  --method median3 \
  --strength 0.6 \
  --flash-thresh 0.12 \
  --outdir processed \
  --ext .mp4 \
  --logfile metrics.jsonl \
  --benchmark \
  --threads 4 \
  --overwrite
```

#### Output Control
- `--outdir`: Output directory (default: `destrobed`)
- `--ext`: Output file extension (default: `.mp4`)
- `--overwrite`: Allow overwriting existing files
- `--no-audio`: Skip audio remux (video only)

#### Performance & Logging
- `--benchmark`: Show processing speed and system info
- `--logfile`: Save detailed metrics to JSONL file
- `--threads`: Number of processing threads

#### Other Options
- `--no-warn`: Skip photosensitivity warning
- `--recursive`: Process directories recursively

## Output

### File Naming
By default, processed files are saved with method suffix:
- `input.mp4` → `destrobed/input.median3.mp4`
- `input.mp4` → `destrobed/input.ema.mp4` (when using EMA)
- `input.mp4` → `destrobed/input.flashcap.mp4` (when using flashcap)

### Console Output
```
→ SailorMoon_EP01.mp4 → destrobed/SailorMoon_EP01.median3.mp4
  FI: 0.082 → 0.041 (-50.0%), SSIM: 0.967
  Performance: 58.2 fps
```

### Metrics Logging
When using `--logfile`, detailed metrics are saved as JSON Lines:

```json
{
  "file": "input.mp4",
  "output": "destrobed/input.median3.mp4", 
  "method": "median3",
  "flicker_before": 0.082,
  "flicker_after": 0.041,
  "ssim": 0.967,
  "fps": 58.2,
  "duration_s": 132.4,
  "audio_remuxed": true
}
```

## Performance

Typical performance on modern hardware:

| Resolution | Method | Apple M1 | Intel i7 | Notes |
|------------|--------|----------|----------|-------|
| 1080p | median3 | ~80 fps | ~60 fps | Real-time+ |
| 1080p | ema | ~90 fps | ~70 fps | Fastest |
| 1080p | flashcap | ~75 fps | ~55 fps | Most thorough |
| 4K | median3 | ~25 fps | ~18 fps | Usable |

Performance can be improved by:
- Using `--threads` to match your CPU cores
- Processing shorter segments for very large files
- Using `ema` method for fastest processing

## Technical Details

### Algorithms

#### Temporal Median Filter (`median3`)
- Uses 3-frame sliding window
- Computes per-pixel median on luminance channel
- Preserves chroma from center frame
- Excellent for isolated flashes, minimal motion blur

#### Exponential Moving Average (`ema`)
- Motion-aware temporal smoothing
- Adapts alpha based on inter-frame motion
- Higher motion = less smoothing (preserves action scenes)
- Good balance of speed and quality

#### Flash Detection & Capping (`flashcap`)  
- Detects sudden luminance spikes
- Caps detected flashes by blending with neighbors
- Applies mild temporal smoothing to other frames
- Best for known problematic content

### Quality Metrics

#### Flicker Index (FI)
Median of frame-to-frame luminance deltas. Lower values indicate less flicker.

#### Structural Similarity (SSIM)
Measures how well the processed video preserves the original's structure. Values near 1.0 indicate high quality preservation.

### Audio Handling
- Original audio is preserved via FFmpeg remux when available
- Falls back to video-only output if FFmpeg is missing
- No re-encoding of audio streams (fast and lossless)

## Troubleshooting

### FFmpeg Not Found
```bash
# Install FFmpeg
# macOS
brew install ffmpeg

# Ubuntu/Debian
sudo apt install ffmpeg

# Windows
# Download from https://ffmpeg.org/download.html
```

### Slow Processing
- Use `--threads N` where N is your CPU core count
- Try `ema` method for fastest processing
- Process shorter clips first to test settings
- Consider reducing input resolution for very large files

### Poor Quality Results
- Try different methods: `median3` for flashes, `ema` for general smoothing
- Adjust `--strength` (lower = less filtering)
- Use `--preview` to test settings before full processing
- Check `--flash-thresh` for flashcap method

### Large File Sizes
- Output uses same codec as input when possible
- Use `--ext .mp4` for better compression
- Original audio is copied without re-encoding

## Development

### Running Tests

```bash
# Install development dependencies
pip install -e .[dev]

# Run tests
pytest

# Run with coverage
pytest --cov=destrobe

# Run linting
ruff check .
black --check .
mypy destrobe/
```

### Creating Test Videos

```python
from destrobe.tests.synthetic_video import create_test_video_suite
from pathlib import Path

# Generate test videos
test_videos = create_test_video_suite(Path("test_outputs"))
```

## Contributing

1. Fork the repository
2. Create a feature branch
3. Add tests for new functionality
4. Ensure all tests pass and linting is clean
5. Submit a pull request

## License

MIT License - see [LICENSE](LICENSE) for details.

## Acknowledgments

- Built with OpenCV for video processing
- Uses scikit-image for SSIM computation
- CLI powered by Typer and Rich
- Inspired by the need for accessible video content

## Related Projects

- [VapourSynth](http://www.vapoursynth.com/) - Advanced video processing framework
- [FFmpeg](https://ffmpeg.org/) - Multimedia framework used for audio remux
- [OpenCV](https://opencv.org/) - Computer vision library for video I/O

---

**Remember**: This tool reduces flashes but cannot guarantee complete removal. Always preview content if you have photosensitive conditions.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "destrobe",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "video, flicker, strobe, photosensitive, epilepsy, accessibility, cli",
    "author": null,
    "author_email": "Sam Hill <sam@samjhill.com>",
    "download_url": "https://files.pythonhosted.org/packages/a0/84/9f5b77c14f93eda21ba77211087a605118bfd862b61a87d200cbe218d4c6/destrobe-1.0.0.tar.gz",
    "platform": null,
    "description": "# destrobe\n\n**CLI tool for reducing video strobing and flicker**\n\nA cross-platform Python CLI that reduces strobing/flicker in videos while preserving audio and sync. Designed to be simple, fast, and safe-by-default for photosensitivity concerns.\n\n## \u26a0\ufe0f Important Safety Notice\n\n**destrobe reduces flashing but cannot guarantee complete removal of all photosensitive triggers.** Always preview content first if you have photosensitive epilepsy or similar conditions. Use at your own discretion.\n\n### \u26a0\ufe0f Example Files Warning\n\n**The example videos in the `examples/` directory contain rapid flashing and strobing effects that may trigger photosensitive epilepsy or seizures.** These files are included specifically to demonstrate destrobe's flicker reduction capabilities on challenging content. **DO NOT VIEW the original files directly if you have photosensitive epilepsy or related conditions.** Only view the processed versions (e.g., `examples/porygon_ULTRA.preview.mp4`) which have had the flashing significantly reduced.\n\n## Quick Start\n\n```bash\n# Install with pipx (recommended)\npipx install destrobe\n\n# Basic usage - process a video with default settings\ndestrobe run input.mp4\n\n# Preview before processing (recommended)\ndestrobe preview input.mp4\n\n# Batch process a directory\ndestrobe run /path/to/videos --recursive\n\n# Use stronger filtering\ndestrobe run input.mp4 --preset strong\n```\n\n## Features\n\n- **Three filtering methods**: Temporal median (`median3`), motion-aware smoothing (`ema`), and flash detection/capping (`flashcap`)\n- **Safe presets**: `safe`, `balanced`, and `strong` configurations for different needs\n- **Audio preservation**: Automatically remux original audio using FFmpeg when available\n- **Batch processing**: Process individual files or entire directories recursively\n- **Preview mode**: Generate side-by-side comparisons before full processing\n- **Quality metrics**: Measure flicker reduction and structural similarity\n- **Performance monitoring**: Built-in benchmarking and progress tracking\n- **Cross-platform**: Works on macOS, Linux, and Windows\n\n## Installation\n\n### Using pipx (Recommended)\n\n```bash\n# Install from PyPI (simplest)\npipx install destrobe\n\n# Or install from GitHub (latest development version)\npipx install git+https://github.com/samjhill/destrobe.git\n```\n\n### Using pip\n\n```bash\n# Install from PyPI\npip install destrobe\n\n# Or install from GitHub\npip install git+https://github.com/samjhill/destrobe.git\n```\n\n### From Source\n\n```bash\ngit clone https://github.com/samhilll/destrobe.git\ncd destrobe\npip install -e .\n```\n\n### Requirements\n\n- Python 3.10+\n- FFmpeg (optional, for audio remux)\n- Dependencies: OpenCV, NumPy, scikit-image, typer, rich, tqdm\n\n## Usage\n\n### Basic Commands\n\n#### Process Videos\n\n```bash\n# Process single file\ndestrobe run video.mp4\n\n# Process multiple files\ndestrobe run video1.mp4 video2.mkv video3.avi\n\n# Process directory (non-recursive)\ndestrobe run /path/to/videos\n\n# Process directory recursively\ndestrobe run /path/to/videos --recursive\n```\n\n#### Preview Mode\n\n```bash\n# Create 10-second preview starting at 30 seconds\ndestrobe preview video.mp4\n\n# Custom preview settings\ndestrobe preview video.mp4 --seconds 15 --start 00:01:30 --method ema\n```\n\n#### Analyze Metrics\n\n```bash\n# Show flicker metrics\ndestrobe metrics video.mp4\n\n# Output as JSON\ndestrobe metrics video.mp4 --json\n```\n\n### Filtering Methods\n\n#### `median3` (Default)\nTemporal median filter using 3-frame window. Excellent for removing isolated flashes while preserving motion.\n\n```bash\ndestrobe run video.mp4 --method median3\n```\n\n#### `ema` (Exponential Moving Average)\nMotion-aware temporal smoothing. Adapts filtering strength based on detected motion.\n\n```bash\ndestrobe run video.mp4 --method ema --strength 0.7\n```\n\n#### `flashcap` (Flash Detection & Capping)\nDetects sudden brightness spikes and caps them. Best for content with known flash patterns.\n\n```bash\ndestrobe run video.mp4 --method flashcap --flash-thresh 0.10\n```\n\n### Presets\n\n#### `safe` (Recommended for sensitive viewers)\n- Method: `flashcap`\n- Strength: 0.7\n- Flash threshold: 0.10\n\n```bash\ndestrobe run video.mp4 --preset safe\n```\n\n#### `balanced` (Default)\n- Method: `median3`\n- Balanced between quality and flicker reduction\n\n```bash\ndestrobe run video.mp4 --preset balanced\n```\n\n#### `strong` (Maximum reduction)\n- Method: `ema`\n- Strength: 0.75\n- More aggressive filtering\n\n```bash\ndestrobe run video.mp4 --preset strong\n```\n\n### Advanced Options\n\n```bash\ndestrobe run input.mp4 \\\n  --method median3 \\\n  --strength 0.6 \\\n  --flash-thresh 0.12 \\\n  --outdir processed \\\n  --ext .mp4 \\\n  --logfile metrics.jsonl \\\n  --benchmark \\\n  --threads 4 \\\n  --overwrite\n```\n\n#### Output Control\n- `--outdir`: Output directory (default: `destrobed`)\n- `--ext`: Output file extension (default: `.mp4`)\n- `--overwrite`: Allow overwriting existing files\n- `--no-audio`: Skip audio remux (video only)\n\n#### Performance & Logging\n- `--benchmark`: Show processing speed and system info\n- `--logfile`: Save detailed metrics to JSONL file\n- `--threads`: Number of processing threads\n\n#### Other Options\n- `--no-warn`: Skip photosensitivity warning\n- `--recursive`: Process directories recursively\n\n## Output\n\n### File Naming\nBy default, processed files are saved with method suffix:\n- `input.mp4` \u2192 `destrobed/input.median3.mp4`\n- `input.mp4` \u2192 `destrobed/input.ema.mp4` (when using EMA)\n- `input.mp4` \u2192 `destrobed/input.flashcap.mp4` (when using flashcap)\n\n### Console Output\n```\n\u2192 SailorMoon_EP01.mp4 \u2192 destrobed/SailorMoon_EP01.median3.mp4\n  FI: 0.082 \u2192 0.041 (-50.0%), SSIM: 0.967\n  Performance: 58.2 fps\n```\n\n### Metrics Logging\nWhen using `--logfile`, detailed metrics are saved as JSON Lines:\n\n```json\n{\n  \"file\": \"input.mp4\",\n  \"output\": \"destrobed/input.median3.mp4\", \n  \"method\": \"median3\",\n  \"flicker_before\": 0.082,\n  \"flicker_after\": 0.041,\n  \"ssim\": 0.967,\n  \"fps\": 58.2,\n  \"duration_s\": 132.4,\n  \"audio_remuxed\": true\n}\n```\n\n## Performance\n\nTypical performance on modern hardware:\n\n| Resolution | Method | Apple M1 | Intel i7 | Notes |\n|------------|--------|----------|----------|-------|\n| 1080p | median3 | ~80 fps | ~60 fps | Real-time+ |\n| 1080p | ema | ~90 fps | ~70 fps | Fastest |\n| 1080p | flashcap | ~75 fps | ~55 fps | Most thorough |\n| 4K | median3 | ~25 fps | ~18 fps | Usable |\n\nPerformance can be improved by:\n- Using `--threads` to match your CPU cores\n- Processing shorter segments for very large files\n- Using `ema` method for fastest processing\n\n## Technical Details\n\n### Algorithms\n\n#### Temporal Median Filter (`median3`)\n- Uses 3-frame sliding window\n- Computes per-pixel median on luminance channel\n- Preserves chroma from center frame\n- Excellent for isolated flashes, minimal motion blur\n\n#### Exponential Moving Average (`ema`)\n- Motion-aware temporal smoothing\n- Adapts alpha based on inter-frame motion\n- Higher motion = less smoothing (preserves action scenes)\n- Good balance of speed and quality\n\n#### Flash Detection & Capping (`flashcap`)  \n- Detects sudden luminance spikes\n- Caps detected flashes by blending with neighbors\n- Applies mild temporal smoothing to other frames\n- Best for known problematic content\n\n### Quality Metrics\n\n#### Flicker Index (FI)\nMedian of frame-to-frame luminance deltas. Lower values indicate less flicker.\n\n#### Structural Similarity (SSIM)\nMeasures how well the processed video preserves the original's structure. Values near 1.0 indicate high quality preservation.\n\n### Audio Handling\n- Original audio is preserved via FFmpeg remux when available\n- Falls back to video-only output if FFmpeg is missing\n- No re-encoding of audio streams (fast and lossless)\n\n## Troubleshooting\n\n### FFmpeg Not Found\n```bash\n# Install FFmpeg\n# macOS\nbrew install ffmpeg\n\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# Windows\n# Download from https://ffmpeg.org/download.html\n```\n\n### Slow Processing\n- Use `--threads N` where N is your CPU core count\n- Try `ema` method for fastest processing\n- Process shorter clips first to test settings\n- Consider reducing input resolution for very large files\n\n### Poor Quality Results\n- Try different methods: `median3` for flashes, `ema` for general smoothing\n- Adjust `--strength` (lower = less filtering)\n- Use `--preview` to test settings before full processing\n- Check `--flash-thresh` for flashcap method\n\n### Large File Sizes\n- Output uses same codec as input when possible\n- Use `--ext .mp4` for better compression\n- Original audio is copied without re-encoding\n\n## Development\n\n### Running Tests\n\n```bash\n# Install development dependencies\npip install -e .[dev]\n\n# Run tests\npytest\n\n# Run with coverage\npytest --cov=destrobe\n\n# Run linting\nruff check .\nblack --check .\nmypy destrobe/\n```\n\n### Creating Test Videos\n\n```python\nfrom destrobe.tests.synthetic_video import create_test_video_suite\nfrom pathlib import Path\n\n# Generate test videos\ntest_videos = create_test_video_suite(Path(\"test_outputs\"))\n```\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Add tests for new functionality\n4. Ensure all tests pass and linting is clean\n5. Submit a pull request\n\n## License\n\nMIT License - see [LICENSE](LICENSE) for details.\n\n## Acknowledgments\n\n- Built with OpenCV for video processing\n- Uses scikit-image for SSIM computation\n- CLI powered by Typer and Rich\n- Inspired by the need for accessible video content\n\n## Related Projects\n\n- [VapourSynth](http://www.vapoursynth.com/) - Advanced video processing framework\n- [FFmpeg](https://ffmpeg.org/) - Multimedia framework used for audio remux\n- [OpenCV](https://opencv.org/) - Computer vision library for video I/O\n\n---\n\n**Remember**: This tool reduces flashes but cannot guarantee complete removal. Always preview content if you have photosensitive conditions.\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Cross-platform CLI tool for reducing video strobing and flicker while preserving audio and sync",
    "version": "1.0.0",
    "project_urls": {
        "Homepage": "https://github.com/samhilll/destrobe",
        "Issues": "https://github.com/samhilll/destrobe/issues",
        "Repository": "https://github.com/samhilll/destrobe"
    },
    "split_keywords": [
        "video",
        " flicker",
        " strobe",
        " photosensitive",
        " epilepsy",
        " accessibility",
        " cli"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "5f6a255453875b2139fbd277e758f817257800a574f8ff191ef10ba16d3650ff",
                "md5": "9bab7edc3cfe3f28b350785ebf84ab34",
                "sha256": "e926eebb27773664e982b6ee504ce0b78c42ee0130676a386bf1224f7ae7e277"
            },
            "downloads": -1,
            "filename": "destrobe-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "9bab7edc3cfe3f28b350785ebf84ab34",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 40128,
            "upload_time": "2025-08-16T01:26:07",
            "upload_time_iso_8601": "2025-08-16T01:26:07.035213Z",
            "url": "https://files.pythonhosted.org/packages/5f/6a/255453875b2139fbd277e758f817257800a574f8ff191ef10ba16d3650ff/destrobe-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "a0849f5b77c14f93eda21ba77211087a605118bfd862b61a87d200cbe218d4c6",
                "md5": "649f66a6401376ff82a5c90efa460a25",
                "sha256": "20a827bdc003bdc667a024cc010cbea2868b9832ed4194f0930a59b40adac602"
            },
            "downloads": -1,
            "filename": "destrobe-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "649f66a6401376ff82a5c90efa460a25",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 41454,
            "upload_time": "2025-08-16T01:26:08",
            "upload_time_iso_8601": "2025-08-16T01:26:08.479954Z",
            "url": "https://files.pythonhosted.org/packages/a0/84/9f5b77c14f93eda21ba77211087a605118bfd862b61a87d200cbe218d4c6/destrobe-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-16 01:26:08",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "samhilll",
    "github_project": "destrobe",
    "github_not_found": true,
    "lcname": "destrobe"
}
        
Elapsed time: 1.26183s