PHPackages                             b7s/fluentcut - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [CLI &amp; Console](/categories/cli)
4. /
5. b7s/fluentcut

ActiveLibrary[CLI &amp; Console](/categories/cli)

b7s/fluentcut
=============

A fluent PHP API for programmatic video editing powered by FFmpeg - compose, transform, and create videos with an elegant chainable interface

v1.0.30(1mo ago)66↑2400%1MITPHPPHP ^8.3

Since Apr 8Pushed 2w agoCompare

[ Source](https://github.com/b7s/fluentcut)[ Packagist](https://packagist.org/packages/b7s/fluentcut)[ RSS](/packages/b7s-fluentcut/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (4)Versions (8)Used By (0)

 [![Logo](docs/logo.webp)](docs/logo.webp)FluentCut
=========

[](#fluentcut)

### 🎬 Craft and compose videos programmatically in PHP with an elegant fluent API

[](#-craft-and-compose-videos-programmatically-in-php-with-an-elegant-fluent-api)

[![PHP Version](https://camo.githubusercontent.com/38027453aeb7eb818641c9de8f82b7624c3558d92634f1946edc715c3ddf8956/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e332532422d3737374242343f6c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://www.php.net/)[![PHPStan Level 6](https://camo.githubusercontent.com/21c74b536006ba91b1e8b5ee044ed3db15c8595100ff21f24852126e81c04c4f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d4c6576656c253230362d627269676874677265656e)](https://phpstan.org/)[![License: MIT](https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667)](https://opensource.org/licenses/MIT)

This standalone, developer‑friendly library brings the full power of FFmpeg into a beautifully fluent PHP API. Effortless to use, built for real‑world production environments, and designed with expressive chaining in mind — it handles everything from simple slideshows and video trimming to complex multi‑clip compositions with text overlays, transitions, and audio mixing.

Whether you're automating video generation, building media pipelines, or creating dynamic content at scale, FluentCut gives you a clean, modern, and type‑safe toolkit that makes programmatic video editing feel natural.

✨ Features
----------

[](#-features)

- 🎯 **Fluent API** - Laravel-inspired chainable interface that reads like a sentence
- 🎬 **Video Composition** - Combine videos, images, and color clips into seamless productions
- ✍️ **Text Overlays** - Add styled text with borders, shadows, and custom positioning
- 🖼️ **Image Overlays** - Layer images on top of clips with precise positioning
- 🎵 **Audio Control** - Add background music, keep source audio, and adjust volume
- 🔄 **Transitions** - 30 built-in transitions including fades, wipes, slides, dissolves, radial, circle effects, and more
- 🎨 **Video Effects** - 23 built-in visual effects with stackable combinations: directional zoom (9 positions), sepia, grayscale, vignette, and more
- 📐 **Smart Resize** - Four resize modes: contain, contain with blur, cover, and stretch
- ⚡ **Presets** - One‑call presets for slideshows, social media, GIFs, and web output
- 🔒 **Type‑Safe** - Full PHP 8.3+ type hints / PHPStan level 6
- 🛠️ **CLI Tools** - Built‑in doctor and info commands for diagnostics and media inspection
- 🚀 **GPU Acceleration** - Auto-detects and uses NVIDIA NVENC, Intel QSV, VA-API, or VideoToolbox when available
- ⏱️ **No Hard Timeout** - Renders without time limits by default; auto-scales per operation

Easy to use
-----------

[](#easy-to-use)

```
use B7s\FluentCut\Enums\VideoEffect;

$result = FluentCut::make()
    ->fullHd()
    ->addImage('photo.jpg', duration: 3, effect: VideoEffect::SoftZoom)
    ->addText('Hello, world!')
    ->saveTo('output.mp4')
    ->render();
```

📦 Installation
--------------

[](#-installation)

```
composer require b7s/fluentcut
```

### Requirements

[](#requirements)

FFmpeg must be installed on your system. FluentCut uses `ffmpeg` and `ffprobe` under the hood for all media operations.

```
# Ubuntu / Debian
sudo apt install ffmpeg

# macOS
brew install ffmpeg

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

### Check Installation

[](#check-installation)

```
vendor/bin/fluentcut doctor
```

This will verify that PHP 8.3+, FFmpeg, and FFprobe are available and properly configured.

🚀 Quick Start
-------------

[](#-quick-start)

### Basic Usage

[](#basic-usage)

```
use B7s\FluentCut\FluentCut;
use B7s\FluentCut\Enums\VideoEffect;

$result = FluentCut::make()
    ->fullHd()
    ->addImage('slide1.jpg', duration: 3, effect: VideoEffect::SoftZoom)
    ->addImage('slide2.jpg', duration: 3)
    ->addImage('slide3.jpg', duration: 2)
    ->fade(0.5)
    ->saveTo('output/slideshow.mp4')
    ->render();

echo "Saved to: " . $result->outputPath;
echo "Duration: " . $result->getFormattedDuration();
```

### Text Overlays

[](#text-overlays)

```
$result = FluentCut::make()
    ->fromVideo('input.mp4')
    ->fullHd()
    ->addImage('background.jpg', duration: 5)
    ->addText(
        text: 'Welcome to FluentCut',
        x: 'center',
        y: '10%',
        fontSize: 64,
        fontColor: 'white',
        borderWidth: 3,
        borderColor: 'black',
        shadowX: 3,
        shadowY: 3,
        shadowColor: 'black@0.7',
    )
    ->addText(
        'A fluent video editing API',
        x: 'center',
        y: '25%',
        fontSize: 28,
        fontColor: '#cccccc'
    )
    ->saveTo('output/text-overlay.mp4')
    ->render();
```

### Resize Video

[](#resize-video)

```
$result = FluentCut::make()
    ->fromVideo('input.mp4')
    ->resize(1280, 720)
    ->saveTo('output/resized.mp4')
    ->render();
```

### Cut/Trim Video

[](#cuttrim-video)

```
$result = FluentCut::make()
    ->fromVideo('long-video.mp4', start: 10.0, end: 30.0)
    ->saveTo('output/clip.mp4')
    ->render();
```

### GIF Export

[](#gif-export)

```
$result = FluentCut::make()
    ->forGif()
    ->addImage('frame1.jpg', duration: 0.5)
    ->addImage('frame2.jpg', duration: 0.5)
    ->addImage('frame3.jpg', duration: 0.5)
    ->addImage('frame4.jpg', duration: 0.5)
    ->saveTo('output/animation.gif')
    ->render();
```

### Video Effects

[](#video-effects)

Apply visual effects to individual clips. Pass a single effect or an array — duplicates are automatically removed.

```
use B7s\FluentCut\Enums\VideoEffect;

$result = FluentCut::make()
    ->fullHd()
    ->addImage('photo1.jpg', duration: 3, effect: VideoEffect::SoftZoom)
    ->addText('Ken Burns Effect', x: 'center', y: 'bottom', fontSize: 36)
    ->addImage('photo2.jpg', duration: 3, effect: [VideoEffect::Sepia, VideoEffect::Vignette])
    ->addText('Sepia + Vignette', x: 'center', y: 'bottom', fontSize: 36)
    ->addImage('photo3.jpg', duration: 3)
    ->effect(VideoEffect::Grayscale, VideoEffect::Sharpen)
    ->addImage('photo4.jpg', duration: 3)
    ->fade(0.5)
    ->saveTo('output/effects-demo.mp4')
    ->render();
```

### Complex Composition

[](#complex-composition)

```
use B7s\FluentCut\Enums\Transition;

$result = FluentCut::make()
    ->fullHd()
    ->addVideo('intro.mp4')
    ->addImage('slide.png', duration: 5)
    ->addText('Chapter 1', x: 'center', y: 'top', fontSize: 64, borderWidth: 3)
    ->overlayImage('logo.png', x: '90%', y: '5%', width: 120)
    ->addBlack(0.5)
    ->addVideo('outro.mp4', start: 0, end: 10)
    ->addText('Thanks for watching!', x: 'center', y: 'center', fontSize: 48)
    ->transition(Transition::Fade, 0.5)
    ->withAudio('bgm.mp3', volume: 0.7)
    ->keepSourceAudio()
    ->saveTo('output/composition.mp4')
    ->render();
```

### GPU Acceleration

[](#gpu-acceleration)

Leverage hardware-accelerated encoding for dramatically faster rendering. FluentCut auto-detects available GPU encoders and uses them automatically.

```
use B7s\FluentCut\Enums\HardwareAccel;

// Auto-detect best available GPU (NVIDIA, Intel, AMD, or Apple Silicon)
$result = FluentCut::make()
    ->fullHd()
    ->useGpu()
    ->addImage('slide1.jpg', duration: 3)
    ->addImage('slide2.jpg', duration: 3)
    ->fade(0.5)
    ->saveTo('output/fast_render.mp4')
    ->render();

// Explicit GPU backend
$result = FluentCut::make()
    ->useGpu(HardwareAccel::Nvenc)   // Force NVIDIA
    ->useGpu(HardwareAccel::VideoToolbox)  // Force Apple Silicon
    ->useGpu(HardwareAccel::Qsv)     // Force Intel Quick Sync
    ->useGpu(HardwareAccel::Vaapi)   // Force AMD/Intel VA-API
    // ... build composition
    ->render();
```

**How it works:** Segment rendering uses GPU encoding for parallel speed, while transition passes (xfade) use CPU — this is unavoidable since FFmpeg's xfade filter is CPU-only, but it's only re-encoding already-compressed segments.

🛠️ CLI Commands
---------------

[](#️-cli-commands)

### doctor - Diagnose Installation

[](#doctor---diagnose-installation)

```
vendor/bin/fluentcut doctor
```

The `doctor` command checks your installation and shows:

- PHP version (8.3+ required)
- FFmpeg availability and version
- FFprobe availability and version

### info - Media File Information

[](#info---media-file-information)

```
vendor/bin/fluentcut info video.mp4
```

The `info` command probes a media file and displays:

- Format and duration
- File size and bitrate
- Video streams (resolution, framerate)
- Audio streams (sample rate, channels)

📖 API Reference
---------------

[](#-api-reference)

### Canvas / Dimensions

[](#canvas--dimensions)

Set the output canvas size and framerate for your composition. All dimension presets also set sensible default framerates.

```
// Custom canvas
->canvas(1280, 720)  // Custom width x height

// Presets
->hd()         // 1280x720
->fullHd()     // 1920x1080
->fourK()      // 3840x2160
->vertical()   // 1080x1920 (portrait / stories)
->square()     // 1080x1080 (social media)

// Framerate
->fps(30)      // Custom framerate
->fps(60)      // High framerate

// Resize mode (how clips fit the canvas)
->resizeMode(ResizeMode::ContainBlur)  // Default
```

### Video Clips

[](#video-clips)

Add video files to the composition. Optionally trim by specifying start and end times in seconds.

```
// Add entire video
->addVideo('clip.mp4')

// Trim a segment
->addVideo('clip.mp4', start: 5.0, end: 15.0)

// With a visual effect
->addVideo('clip.mp4', effect: VideoEffect::Grayscale)

// With multiple effects
->addVideo('clip.mp4', effect: [VideoEffect::Grayscale, VideoEffect::Vignette])

// Alias
->fromVideo('clip.mp4', start: 5.0, end: 15.0)
```

### Image Clips

[](#image-clips)

Add still images as clips with a specified duration. Perfect for building slideshows or title cards.

```
// Single image (1 second default)
->addImage('photo.jpg', duration: 3)

// With a single effect
->addImage('photo.jpg', duration: 3, effect: VideoEffect::SoftZoom)

// With multiple effects
->addImage('photo.jpg', duration: 3, effect: [VideoEffect::SoftZoom, VideoEffect::Vignette])

// Multiple images at once
->addImages(['img1.jpg', 'img2.jpg', 'img3.jpg'], duration: 2)

// Multiple images with effects
->addImages(['img1.jpg', 'img2.jpg'], duration: 2, effect: [VideoEffect::Sepia, VideoEffect::Sharpen])
```

### Color / Background Clips

[](#color--background-clips)

Add solid-color clips to create title screens, interstitials, or backgrounds.

```
// Custom color
->addColor('#1a1a2e', duration: 2)
->addColor('red', duration: 1)

// With effects
->addColor('black', duration: 2, effect: VideoEffect::Vignette)
->addColor('black', duration: 2, effect: [VideoEffect::Brightness, VideoEffect::Vignette])

// Presets
->addBlack(0.5)  // Half-second black screen
->addWhite(1.0)  // One-second white screen
```

### Text Overlays

[](#text-overlays-1)

Add text to the last added clip. All parameters except `text` are optional. Supports positioning with pixel values, percentages (`'50%'`), or keywords (`'center'`, `'top'`, `'bottom'`, `'left'`, `'right'`).

```
// Text with just the text parameter (all other options have sensible defaults)
->addText('Hello')

// Custom position, size, and color
->addText('Title', x: 'center', y: 'top', fontSize: 64, fontColor: 'white')

// Add border/outline
->addText('Subtitle', borderWidth: 3, borderColor: 'black')

// Add drop shadow
->addText('With Shadow', shadowX: 3, shadowY: 3, shadowColor: 'black@0.5')

// Both border and shadow combined
->addText('Styled', borderWidth: 2, borderColor: 'black', shadowX: 2, shadowY: 2, shadowColor: 'black@0.5')

// Custom font file
->addText('Custom', fontFile: '/path/to/font.ttf')
```

### Image Overlays

[](#image-overlays)

Layer images on top of the last added clip, such as watermarks or logos.

```
->overlayImage('logo.png', x: '90%', y: '5%', width: 120)

// Full parameters
->overlayImage(
    path: 'watermark.png',
    x: 'right',
    y: 'bottom',
    width: 200,
    height: 100,
    start: 0.0,
    end: null  // null = visible for entire clip
)
```

### Audio

[](#audio)

Control the audio layer of your composition. Add background music, preserve source audio, and adjust volume levels. You can add multiple audio tracks with independent control over volume, start time, and duration.

```
// Single background music track (plays once, full volume)
->withAudio('bgm.mp3')

// Single track with custom volume
->withAudio('bgm.mp3', volume: 0.7)

// Loop audio until video ends (with fade in at start, fade out at end)
->withAudio('bgm.mp3', loop: true)

// Loop with custom fade duration
->withAudio('bgm.mp3', loop: true, fadeDuration: 0.5)
->withAudio('bgm.mp3', loop: true, fadeDuration: 1)
->withAudio('bgm.mp3', loop: true, fadeDuration: 2.25)

// Multiple audio tracks - each call adds a new track
->withAudio('intro.mp3', volume: 1.0)           // Track 1: full volume from start
->withAudio('background.mp3', volume: 0.5)      // Track 2: half volume from start
->withAudio('ending.mp3', volume: 0.8, startAt: 30.0)  // Track 3: starts at 30s

// Multiple tracks with different start times and cut times
->withAudio('music.mp3', volume: 0.6, startAt: 0.0)   // Plays from 0s until video ends
->withAudio('narration.mp3', volume: 1.0, startAt: 5.0, endAt: 35.0)  // Plays from 5s to 35s

// Each track can have its own loop and fade settings
->withAudio('loop-music.mp3', loop: true, fadeDuration: 0.3)  // Loop with quick fade
->withAudio('intro.mp3', loop: false, fadeDuration: 0.5)      // No loop with default fade

// Cut audio at specific time with fade out
->withAudio('music.mp3', endAt: 30.0, fadeDuration: 0.5)

// Keep audio from source video clips
->keepSourceAudio()

// Adjust volume of the last added audio track
->audioVolume(0.5)

// Add audio specifically to the current clip (not global)
->addAudioToClip('narration.mp3')
```

**Parameters:**

- `path` (string) - Path to the audio file
- `volume` (?float) - Volume level 0.0-1.0, defaults to 1.0
- `startAt` (int|float) - Start offset in seconds, defaults to 0.0
- `endAt` (null|int|float) - Cut audio at this timestamp (seconds), null = play until video ends
- `loop` (bool) - Loop audio until video ends, defaults to false
- `fadeDuration` (float) - Fade in/out duration in seconds, defaults to 0.0

**Note:** Each audio track plays once by default unless `loop: true`. When looping, fade is applied at the start and end of each audio iteration for smooth transitions.

### Transitions

[](#transitions)

Define the transition between the current clip and the next one. Transitions are applied between consecutive clips in the timeline.

```
use B7s\FluentCut\Enums\Transition;

// Generic transition method
->transition(Transition::Fade, 0.5)
->transition(Transition::WipeLeft, 0.3)
->transition(Transition::Dissolve, 1.0)
->transition(Transition::CircleOpen, 0.8)
->transition(Transition::Radial, 1.0)

// Shorthand presets
->fade(0.5)               // Crossfade
->fadeThroughBlack(0.5)   // Fade through black
->noTransition()          // Hard cut
```

**Available transitions:**

TransitionDescription`None`Hard cut (no transition)`Fade`Smooth crossfade between clips`FadeBlack`Fade through black`FadeWhite`Fade through white`FadeGrays`Fade through grayscale`Dissolve`Pixel dissolve blend`WipeLeft`Wipe from right to left`WipeRight`Wipe from left to right`WipeUp`Wipe from bottom to top`WipeDown`Wipe from top to bottom`SlideLeft`Slide from left`SlideRight`Slide from right`SlideUp`Slide from bottom`SlideDown`Slide from top`Radial`Radial wipe from center`CircleOpen`Circle opening from center`CircleClose`Circle closing to center`CircleCrop`Circular crop transition`RectCrop`Rectangular crop transition`Distance`Distance-based blend`Pixelize`Pixelization effect`HorizontalBlur`Horizontal blur transition`HorizontalLeftSlice`Horizontal slice from left`HorizontalRightSlice`Horizontal slice from right`VerticalUpSlice`Vertical slice upward`VerticalDownSlice`Vertical slice downward`DiagonalTopLeft`Diagonal from top-left`DiagonalTopRight`Diagonal from top-right`DiagonalBottomLeft`Diagonal from bottom-left`DiagonalBottomRight`Diagonal from bottom-right### Video Effects

[](#video-effects-1)

Apply one or more visual effects per clip. Pass a single `VideoEffect`, an array of effects, or use the variadic `effect()` method. Duplicates and `None` are automatically removed.

```
use B7s\FluentCut\Enums\VideoEffect;

// Single effect when adding a clip
->addImage('photo.jpg', duration: 3, effect: VideoEffect::SoftZoom)
->addVideo('clip.mp4', effect: VideoEffect::Grayscale)
->addColor('black', duration: 2, effect: VideoEffect::Vignette)

// Multiple effects via array
->addImage('photo.jpg', duration: 3, effect: [VideoEffect::SoftZoom, VideoEffect::Vignette])
->addImages(['a.jpg', 'b.jpg'], duration: 2, effect: [VideoEffect::Sepia, VideoEffect::Sharpen])

// Variadic effect() on the last clip (merges with existing effects)
->addImage('photo.jpg', duration: 3)
->effect(VideoEffect::Sepia, VideoEffect::Sharpen)

// No effect (default)
->addImage('photo.jpg', duration: 3)
```

**Available effects:**

EffectDescription`VideoEffect::None`No effect (default)`VideoEffect::SoftZoom`Slow zoom in to center (Ken Burns effect)`VideoEffect::ZoomCenter`Slow zoom in to center`VideoEffect::ZoomTopLeft`Slow zoom in to top-left`VideoEffect::ZoomTopCenter`Slow zoom in to top-center`VideoEffect::ZoomTopRight`Slow zoom in to top-right`VideoEffect::ZoomCenterLeft`Slow zoom in to center-left`VideoEffect::ZoomCenterRight`Slow zoom in to center-right`VideoEffect::ZoomBottomLeft`Slow zoom in to bottom-left`VideoEffect::ZoomBottomCenter`Slow zoom in to bottom-center`VideoEffect::ZoomBottomRight`Slow zoom in to bottom-right`VideoEffect::Grayscale`Convert to grayscale`VideoEffect::Sepia`Sepia tone (vintage warm look)`VideoEffect::Blur`Gaussian blur`VideoEffect::Sharpen`Sharpen details`VideoEffect::Vignette`Dark edges vignette`VideoEffect::Brightness`Increase brightness`VideoEffect::Contrast`Increase contrast`VideoEffect::Saturate`Boost color saturation`VideoEffect::Desaturate`Reduce color saturation`VideoEffect::Negate`Invert colors`VideoEffect::EdgeDetect`Edge detection outline`VideoEffect::Pixelate`Pixelation mosaic### Resize Modes

[](#resize-modes)

Control how clips are fitted to the canvas when their aspect ratio doesn't match.

```
use B7s\FluentCut\Enums\ResizeMode;

->resizeMode(ResizeMode::ContainBlur)  // Fit + blurred background (default)
->resizeMode(ResizeMode::Contain)      // Fit with letterboxing
->resizeMode(ResizeMode::Cover)        // Crop to fill (aspect preserved)
->resizeMode(ResizeMode::Stretch)      // Stretch to fill (aspect distorted)
```

### Output Configuration

[](#output-configuration)

Configure where and how the final video is saved.

```
// Output path
->saveTo('output/video.mp4')  // Save to specific location
->output('output/video.mp4')  // alias

// Codec selection
use B7s\FluentCut\Enums\Codec;
->codec(Codec::H264)  // Most compatible (default)
->codec(Codec::H265)  // Better compression
->codec(Codec::Vp9)   // WebM format

// Resize output (independent of canvas)
->resize(1280, 720)
```

### Presets

[](#presets)

Pre-configured settings optimized for common use cases. Each preset sets canvas size, framerate, transition, and resize mode.

```
->forSlideshow()      // Full HD, 30fps, fade transition, contain with blur
->forPresentation()   // Full HD, 24fps, contain mode
->forSocialMedia()    // Vertical (1080x1920), 30fps, cover mode
->forGif()            // 480x270, 10fps, cover mode
->forWeb()            // Full HD, 30fps, H.264, contain with blur
```

### Progress Monitoring

[](#progress-monitoring)

Track render progress in real time with a callback that receives detailed progress information.

```
->onProgress(function (\B7s\FluentCut\Results\ProgressInfo $progress) {
    $bar = str_repeat('=', (int) round($progress->percentage / 2.5));
    $pad = str_repeat(' ', 40 - strlen($bar));
    echo "\r  [{$bar}{$pad}] {$progress->getFormattedPercentage()} "
       . "| Time: {$progress->getFormattedTime()} "
       . "| Speed: {$progress->getFormattedSpeed()} "
       . "| {$progress->phase}";
})
```

### GPU Acceleration

[](#gpu-acceleration-1)

Enable hardware-accelerated encoding for faster rendering. FluentCut auto-detects available GPU encoders.

```
use B7s\FluentCut\Enums\HardwareAccel;

// Auto-detect best available GPU (NVIDIA, Intel, AMD, Apple Silicon)
->useGpu()

// Explicit backend
->useGpu(HardwareAccel::Nvenc)        // NVIDIA NVENC
->useGpu(HardwareAccel::VideoToolbox) // Apple Silicon
->useGpu(HardwareAccel::Qsv)          // Intel Quick Sync
->useGpu(HardwareAccel::Vaapi)        // AMD/Intel VA-API
```

**Platform detection:**

- macOS → VideoToolbox (Apple Silicon)
- Windows → Nvenc, then Qsv
- Linux → Nvenc, then Vaapi, then Qsv

**Note:** Transition effects (xfade) use CPU because FFmpeg's xfade filter has no GPU implementation. This is a minor re-encoding pass — the heavy segment rendering still uses GPU.

### Execution (render)

[](#execution-render)

The `render()` method is the terminal operation that builds the FFmpeg command and executes it, returning a `RenderResult` object.

```
$result = FluentCut::make()
    ->fullHd()
    ->addVideo('clip.mp4')
    ->saveTo('output.mp4')
    ->render();
```

### Result Object

[](#result-object)

The `RenderResult` object contains information about the rendered video and metadata about the render process.

```
$result->isSuccessful();           // bool - Check if render succeeded
$result->getPath();                // string - Output file path
$result->getDuration();            // float - Duration in seconds
$result->getFormattedDuration();   // string - "02:30.50" format
$result->getFormattedSize();       // string - Human-readable file size
$result->width;                    // int - Video width
$result->height;                   // int - Video height
$result->format;                   // string - Output format
$result->fileSize;                 // int - File size in bytes
$result->error;                    // string|null - Error message if failed
$result->metadata;                 // array - Render parameters used
$result->toArray();                // array - All data as array
```

### Static Helpers

[](#static-helpers)

Utility methods for media inspection and system checks without creating a FluentCut instance.

```
use B7s\FluentCut\FluentCut;

// Probe a media file (returns full metadata)
$info = FluentCut::probe('video.mp4');

// Get specific properties
$duration = FluentCut::getDuration('video.mp4');     // ?float - seconds
$dimensions = FluentCut::getDimensions('video.mp4'); // ?array ['width' => ..., 'height' => ...]

// Check system requirements
$ready = FluentCut::checkRequirements();  // bool - FFmpeg + FFprobe available
```

⚙️ Configuration
----------------

[](#️-configuration)

Create a `fluentcut-config.php` file in your project root:

```
