Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

╔═╗╦  ╦ ╦╔═╗
║ ╦║  ╚╦╝╠╣
╚═╝╩═╝ ╩ ╚

High-performance ASCII video engine

Glyf is a terminal-based media engine written in Go that renders video as synchronized ASCII art in the terminal while playing the accompanying audio track. It decodes raw video frames, converts each frame into a grid of characters based on pixel luminance, and paces frame output against a wall-clock timer to keep video and audio in sync.

Features

  • Real-time video-to-ASCII rendering based on pixel luminance mapping
  • Synchronized audio playback alongside ASCII video output
  • Frame pacing engine that keeps rendering aligned to a target frame rate
  • Graceful terminal cleanup on interrupt (cursor restoration on Ctrl+C)
  • Minimal dependencies — relies on ffmpeg/ffplay for decoding and playback

Architecture

Glyf is organized into four independent packages coordinated by a central engine:

Package Responsibility
video Spawns an ffmpeg process to decode the input file into raw RGB24 frames and exposes them as image.Image values
render Converts a decoded frame into an ASCII string using a luminance-to-character gradient
audio Spawns ffplay in the background to handle audio playback independently of the render loop
engine Owns the main playback loop: pulls frames from the decoder, renders them, and paces output against a synchronized clock

The playback loop and the audio process run concurrently but independently — audio playback is started once via ffplay, while the video loop paces itself against an internal clock (SyncEngine) seeded at playback start, so frame timing does not drift from the decode rate.

Requirements

  • Go 1.26.2 or later
  • FFmpeg (ffmpeg and ffplay binaries) available on the system PATH
  • A terminal emulator with ANSI escape sequence support

Installation

Clone the repository and build the binary:

git clone https://github.com/SupriyoP09/Glyf.git
cd Glyf
go build -o glyf ./cmd/glyf

Usage

Run the binary with a path to a video file:

./glyf -file path/to/video.mp4

If no -file flag is provided, Glyf defaults to looking for test.mp4 in the current directory.

Press Ctrl+C at any time to stop playback; the terminal cursor is restored automatically on exit.

How It Works

  1. Decodingvideo.NewDecoder launches ffmpeg, instructing it to output raw RGB24 frames at a fixed resolution over a pipe. Each call to NextFrame reads exactly one frame's worth of bytes and reconstructs it as an image.Image.
  2. Renderingrender.ImageToASCII walks every pixel, computes luminance using the standard weighted RGB formula, and maps the result onto a fixed ASCII character ramp (from lightest to darkest character).
  3. Audioaudio.Play starts ffplay in headless mode (-nodisp) so audio decoding and output run independently of the render loop.
  4. Synchronizationengine.SyncEngine records a start timestamp and, for each frame index, sleeps just long enough to keep actual elapsed time aligned with the expected frame time for a fixed frame rate.
  5. Output — Each rendered frame is written to the terminal using ANSI cursor-repositioning sequences, avoiding a full screen clear per frame to reduce flicker.

Project Structure

Glyf/
├── cmd/
│   └── glyf/
│       └── main.go       # CLI entry point
├── engine/
│   └── sync.go            # Playback loop and frame-rate synchronization
├── audio/
│   └── player.go           # Audio playback via ffplay
├── render/
│   └── ascii.go             # Luminance-to-ASCII conversion
├── video/
│   └── decoder.go            # ffmpeg-based frame decoding
└── go.mod

About

High-performance ASCII video engine in go

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages