Skip to content

Latest commit

 

History

82 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SugarReel

CI codecov Packagist Version License PHP

Terminal video player — plays mp4 / gif / avi / webm and more on the fly, rendering each frame as ASCII, ANSI 256-color, truecolor half-blocks, or via modern graphics protocols (sixel / kitty / iTerm2). Like mpv -vo tct, but in PHP and reusing the SugarCraft rendering stack throughout.

composer require sugarcraft/sugar-reel
use SugarCraft\Reel\Player;

// Play a video with auto-detected terminal capability.
$player = Player::open('clip.mp4', cols: 80, rows: 24);

// Run it (Space=play, q=quit).
(new \SugarCraft\Core\Program($player))->run();

Status: Step 7 ✓ — full implementation with ffmpeg decode pipe, pure-PHP GIF fallback, all rendering modes (ascii/ansi256/truecolor/ half-block/sixel/kitty/iTerm2), delta repaint, seek, speed control, and a runnable example.

Install

composer require sugarcraft/sugar-reel

Requires:

  • PHP 8.3+
  • ffmpeg and ffprobe in $PATH for mp4/avi/webm playback
  • ext-gd for .gif playback (pure-PHP fallback, no ffmpeg needed)
  • A terminal with at least 256-color support for ANSI modes

Usage

# Built-in synthetic test pattern (no video file needed)
php examples/play.php

# Play a real video file
php examples/play.php video.mp4

# Force a specific rendering mode
php examples/play.php video.mp4 halfblock
php examples/play.php video.mp4 ascii

# Force auto mode (probe terminal, pick best available)
php examples/play.php video.mp4 auto

# Set terminal dimensions
SUGAR_REEL_COLS=120 SUGAR_REEL_ROWS=40 php examples/play.php

Rendering modes

Mode Description Terminal requirement
ascii Grayscale luminance ramp ( .,:;i1tfLCG08@) Any
ansi256 256-color cube + grey ramp 256-color
truecolor 24-bit RGB truecolor 24-bit color
halfblock 24-bit half-blocks, 2× vertical resolution 24-bit color
sixel Sixel graphics protocol (DEC) Sixel-capable
kitty Kitty graphics protocol (DCS APC) Kitty-compatible
iterm2 iTerm2 inline image (OSC 1337) iTerm2 / WezTerm
auto Probe terminal, pick best available (default)

Auto mode probes the terminal using Mosaic::diagnose() (for sixel/kitty/ iTerm2) and falls back to ColorProfile::detect() for ANSI modes.

Luminance ramp selection

ASCII/ANSI256 text modes use a luminance ramp to map pixel brightness to characters. Three named ramps are available:

Ramp Characters Best for
minimal .:-=+*#%@ Low-resolution / high contrast
standard .,:;i1tfLCG08@ General use (default)
dense `` .`^",:;Il!i><~+_-?][}{1)( \/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$``
// Use the dense ramp for more detailed ASCII output
Reel::open('video.mp4')->withRamp('dense')->play();

Keyboard controls

Key Action
Space Pause / resume
Seek backward 10 frames
Seek forward 10 frames
[ Decrease playback speed (−0.25×, min 0.25×)
] Increase playback speed (+0.25×, max 4.0×)
09 Seek to 0–90% of video duration
m Cycle to next rendering mode
q / Esc Quit
resize Terminal resize (SIGWINCH) re-scales video automatically
loop Loop is set at open time via Reel::new()->withLoop(true)->play() (no keyboard shortcut)

Architecture

video file (mp4/gif/avi/webm)
        │
        ▼
┌───────────────────┐     ┌─────────────────┐
│ VideoSource::probe│     │ DecoderFactory  │
│   (ffprobe JSON)  │────▶│ create()        │
└───────────────────┘     └────────┬─────────┘
                                 │
                    ┌────────────┴────────────┐
                    │                        │
               GifDecoder             FfmpegDecoder
               (pure PHP / GD)         (ffmpeg pipe)
                    │                        │
                    └────────────┬───────────┘
                                ▼
                    ┌──────────────────────┐
                    │   RgbFrame (rgb24)    │
                    └──────────┬─────────────┘
                               │
                    ┌─────────┴──────────────┐
                    │   FrameRenderer /       │
                    │   Mosaic bridge         │
                    └─────────┬──────────────┘
                              │
                    ┌─────────┴──────────────┐
                    │   Player (TEA Model)    │
                    │   tick() → view()       │
                    └─────────┬──────────────┘
                              │
                    ┌─────────▼──────────────┐
                    │   Program (candy-core)  │
                    │   raw mode + alt screen│
                    └────────────────────────┘
  • Decode: FfmpegDecoder shells out to ffmpeg for raw RGB frames (pre-scaled to cell dimensions). GifDecoder wraps candy-flip's pure-PHP GIF decoder.
  • Render: Delegates to candy-mosaic for sixel/kitty/iTerm2. Uses candy-palette for color mapping. Delta repaint via candy-buffer.
  • Pace: Cmd::tick() wall-clock alignment via Sync, no busy-waiting.
  • Audio: AudioPlayer shells out to ffplay or mpv --no-video as the audio master clock.

Prior art

SugarReel has no single upstream. Its decode → render → pace pipeline draws on three terminal-video projects, credited here:

The rendering stack is reused from the SugarCraft ecosystem rather than reinvented: candy-mosaic (image → cell renderers), candy-flip (downsampling / dithering), candy-palette (color mapping), and candy-core (TEA runtime + frame pacing).

Known limitations

  • Audio plays at 1.0× regardless of playback speed. Changing speed with [/] only affects video pacing. The audio companion (ffplay/mpv) always plays at normal speed. A/V will diverge noticeably when using speeds other than 1.0×.

  • Seeking repositions audio but not frame-exactly. A seek creates a new AudioPlayer at the correct offset, but the video frame timing and audio timing are only approximately synchronized (frame-skip resync keeps them close at 1.0×).

  • GIF playback fills the terminal in HalfBlock mode (each cell = 2 source rows). In text modes (ascii/ansi256/truecolor) the GIF renders at its native pixel dimensions without 2× vertical scaling.

About

Terminal video player for SugarCraft — mp4 → ASCII/ANSI/truecolor/sixel/kitty output

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages