ascii-chat 0.11.33
Video chat in your terminal
Loading...
Searching...
No Matches
main.c File Reference

Local media mirror mode: view webcam or media files as ASCII art without network. More...

Go to the source code of this file.

Functions

int mirror_main (void)
 Run mirror mode main loop.
 

Detailed Description

Local media mirror mode: view webcam or media files as ASCII art without network.

Mirror mode is a standalone, self-contained ASCII video viewer that requires no server or network connection. It's ideal for:

  • Testing webcam capture and ASCII conversion pipelines locally
  • Viewing video files as ASCII art
  • Previewing terminal rendering without networking complexity
  • Debugging frame processing, color palettes, and keyboard input handling

Architecture Overview

Mirror mode uses the unified session library to manage initialization and rendering:

↓
session_client_like_run() [Shared initialization]
├─ Terminal setup (TTY detection, control handler)
├─ Media source creation (webcam/file/stdin/test pattern)
├─ FPS probing (automatically detect frame rate)
├─ Audio initialization (optional, from media or microphone)
├─ Display context creation (palette, color mode, terminal capabilities)
├─ Splash screen animation
└─ Mirror mode main loop
↓
mirror_run()
↓
session_render_loop() [Unified render loop]
├─ Frame capture via session_capture_read_frame()
├─ Frame rate limiting via session_capture_sleep_for_fps()
├─ ASCII conversion via session_display_convert_to_ascii()
├─ Terminal rendering via session_display_render_frame()
├─ Keyboard input polling (if handler provided)
└─ Loop until user Ctrl+C or media EOF
asciichat_error_t session_client_like_run(const session_client_like_config_t *config)
asciichat_error_t session_render_loop(session_capture_ctx_t *capture, session_display_ctx_t *display, session_should_exit_fn should_exit, session_capture_fn capture_cb, session_sleep_for_frame_fn sleep_cb, session_keyboard_handler_fn keyboard_handler, void *user_data)
Unified render loop for all display modes.
void session_display_render_frame(session_display_ctx_t *ctx, const char *frame_data)
Render an ASCII frame to the terminal.
image_t * session_capture_read_frame(session_capture_ctx_t *ctx)
Read the next video frame from the capture source.
void session_capture_sleep_for_fps(session_capture_ctx_t *ctx)
Sleep to maintain target frame rate.
char * session_display_convert_to_ascii(session_display_ctx_t *ctx, const image_t *image)
Convert an image to ASCII art using display context and command-line options.
int main(int argc, char *argv[])
Definition main.c:472
int mirror_main(void)
Run mirror mode main loop.
int frame
Definition splash.c:99

Frame Processing Pipeline

Each frame flows through a multi-stage pipeline:

1. Media Source & Capture

The media source abstraction handles all input types transparently:

  • Webcam: Continuous live capture at target FPS
  • Video Files: Decoded frame-by-frame via FFmpeg
  • Streaming URLs: HTTP/HTTPS/RTSP streams resolved via FFmpeg or yt-dlp
  • Stdin: Custom frame input for testing
  • Test Pattern: Synthetic frames for debugging

Configuration:

.type = MEDIA_SOURCE_WEBCAM, // or FILE, STDIN, TEST
.path = "0", // device index or file path
.target_fps = 60, // desired frame rate
.loop = false, // repeat on EOF
.resize_for_network = false // local rendering, no resize
}
@ MEDIA_SOURCE_WEBCAM
Hardware webcam device.
Definition source.h:82
Configuration for session capture context.
media_source_type_t type
Media source type (WEBCAM, FILE, STDIN, TEST)

Captured frame: Raw RGB image from media source.

2. ASCII Conversion

session_display_convert_to_ascii() transforms raw video to ASCII art:

  • Palette Selection: Choose from standard, compact, or custom ASCII characters
  • Luminance Mapping: Convert RGB to brightness, map to character palette
  • Color Rendering: Terminal color codes (256-color or true color if supported)
  • Compression: Optional RLE compression for efficient transmission

Output: ASCII frame with embedded ANSI color codes.

3. Terminal Rendering

session_display_render_frame() writes ASCII to terminal:

  • Terminal Detection: Detect color capability (256-color, true color, monochrome)
  • Cursor Management: Minimize flicker with intelligent cursor positioning
  • Atomic Writes: Serialized output prevents visual artifacts

Terminal output: Colored ASCII art displayed in real-time.

4. Frame Rate Control

Adaptive sleep maintains target FPS:

  • Track capture timestamps
  • Calculate ideal sleep duration
  • Yield CPU without blocking (platform-aware sleep)

Result: Smooth, responsive playback at target frame rate.

Features

  • Local webcam capture and ASCII conversion (no network)
  • Media file playback (video/audio files, animated GIFs, URLs)
  • Smart media resolution (FFmpeg + yt-dlp for 1000+ streaming sites)
  • Loop playback for media files
  • Terminal capability detection for optimal color output (256-color, true color)
  • Adaptive frame rate limiting for smooth display
  • Audio playback from media files or microphone
  • Keyboard input support for interactive controls
  • Graceful shutdown on Ctrl+C (proper cleanup, no orphaned processes)
  • Snapshot mode for single-frame capture
  • Custom palette support

Usage Examples

// Local webcam (live view)
ascii-chat mirror
// Video file (with loop)
ascii-chat mirror --file video.mp4 --loop
// Streaming URL (YouTube, Twitch, etc. - requires yt-dlp)
ascii-chat mirror --url "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
// Snapshot mode (single frame, then exit)
ascii-chat mirror --snapshot --snapshot-delay 0
// Custom FPS and palette
ascii-chat mirror --file video.mp4 --fps 30 --palette compact
// With audio from file
ascii-chat mirror --file video.mp4 --enable-audio

Integration with Session Library

Mirror mode delegates initialization and lifecycle management to session_client_like_run():

  • Initialization: Media source creation, FPS probing, display setup
  • Splash Screen: Animated intro with embedded log capture
  • Render Loop: Delegates to session_render_loop() for frame processing
  • Cleanup: Proper teardown of audio, display, and media resources
  • Keyboard Handler: Optional interactive controls via mirror_keyboard_handler()

Keyboard Controls

If keyboard support is enabled:

  • q or Ctrl+C: Quit
  • h: Toggle help screen
  • p: Pause/resume playback (media files only)
  • n: Next frame (when paused)
  • Space: Pause/resume

(Actual controls implemented in session_handle_keyboard_input())

Performance Characteristics

  • Webcam: Minimal latency (single-frame buffer)
  • Video Files: Streaming decode (no buffering overhead)
  • Large Files: Constant memory usage (frame-by-frame processing)
  • Terminal Output: Optimized for minimal flicker (differential rendering)
  • CPU Usage: Scales with target FPS and color mode

Terminal Requirements

  • TTY output (not suitable for piped output - detection and auto-fallback implemented)
  • ANSI escape sequence support (16, 256, or true color)
  • Minimum 60x20 terminal size (uses full available space)

Example Workflow

// User runs:
$ ascii-chat mirror --file movie.mp4
// Internal flow:
1. mirror_main() called from binary main()
2. session_client_like_run() initializes:
- Opens FFmpeg decoder for movie.mp4
- Probes FPS (e.g., 24 FPS)
- Creates display context with 256-color palette
- Shows splash screen with animation
3. mirror_run() invokes session_render_loop()
4. Each iteration:
- Reads frame from FFmpeg decoder
- Sleeps to maintain 24 FPS
- Converts to ASCII (luminance mapping + color codes)
- Renders to terminal with cursor optimization
- Polls for keyboard input (q to quit)
5. On Ctrl+C or EOF:
- Clean exit from render loop
- Destroy display, audio, media source
- Print newline to separate from shell prompt
Author
Zachary Fogg me@zf.nosp@m.o.gg
Date
2025
See also
session/client_like.h - Shared initialization
session/render.h - Unified render loop
session/capture.h - Media source abstraction
session/display.h - Terminal rendering
lib/media/source.h - Media source types (Webcam Module, file, etc.)
lib/video/palette.h - ASCII Character Palettes types

Definition in file mirror/main.c.

Function Documentation

◆ mirror_main()

int mirror_main ( void  )

Run mirror mode main loop.

Initializes webcam and terminal, then continuously captures frames, converts them to ASCII art, and displays them locally.

Uses the session library for unified capture and display management.

Returns
0 on success, non-zero error code on failure

Definition at line 379 of file mirror/main.c.

379 {
380 log_info("[MIRROR] main ENTRY");
381
382 // Configure mode-specific session settings
384 .run_fn = mirror_run,
385 .run_user_data = NULL,
387 .keyboard_handler = mirror_keyboard_handler,
388 .print_newline_on_tty_exit = true, // Mirror prints newline to separate frame from prompt
389 };
390
391 // Run shared initialization/teardown with mode-specific loop
393 log_info("mirror_main: session_client_like_run returned with result=%d", result);
394
395 if (result != ASCIICHAT_OK) {
396 log_error("Mirror mode failed with error code: %d", result);
397 }
398
399 return (int)result;
400}
@ SESSION_CLIENT_LIKE_KIND_MIRROR
Definition client_like.h:64
asciichat_error_t
Error and exit codes - unified status values (0-255)
Definition error_codes.h:49
@ ASCIICHAT_OK
Definition error_codes.h:51
#define log_error(...)
Log an ERROR message.
Definition log/log.h:587
#define log_info(...)
Log an INFO message.
Definition log/log.h:561
session_client_like_run_fn run_fn

References ASCIICHAT_OK, log_error, log_info, session_client_like_config::run_fn, SESSION_CLIENT_LIKE_KIND_MIRROR, and session_client_like_run().