![Logo](./images/logo.svg)

It's a simple python package to play videos in a terminal using [ASCII](https://en.wikipedia.org/wiki/ASCII) characters. [![Financial Contributors on Open Collective](https://opencollective.com/video-to-ascii/all/badge.svg?label=financial+contributors)](https://opencollective.com/video-to-ascii) [![PyPI version](https://badge.fury.io/py/video-to-ascii.svg)](https://badge.fury.io/py/video-to-ascii) [![Maintainability](https://api.codeclimate.com/v1/badges/3108b26a0bcfffd4b4fe/maintainability)](https://codeclimate.com/github/joelibaceta/video-to-ascii/maintainability) [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/joelibaceta/video-to-ascii)

![Screenshot](./images/Simpsons.apng)
Translations

- [🇺🇸 English](./README.md) - [🇪🇸 Español](./translations/README_es.md) - [🇹🇼 繁體中文](./translations/README_zh-TW.md)

## Requirements - Python3 - PortAudio (_Only required for installation with audio support_) - FFmpeg (_Only required for installation with audio support_) - Linux or MacOS ... for now ## Installation ### From PyPI (Recommended) Standard installation (without audio support): ```bash $ pip install video-to-ascii ``` With audio support: ```bash $ pip install video-to-ascii[audio] ``` Complete installation (with all optional dependencies): ```bash $ pip install video-to-ascii[all] ``` ### 🔄 Migration Guide If you were using the old installation method with `--install-option`: ```bash # ❌ Old way (no longer supported) $ pip install video-to-ascii --install-option="--with-audio" # ✅ New way $ pip install video-to-ascii[audio] ``` **Note**: The `--install-option` flag has been [deprecated by pip](https://pip.pypa.io/en/stable/news/#deprecation-of-install-option-and-global-option) and removed in pip 23.1+. ### From Source Clone the repository and install: ```bash $ git clone https://github.com/joelibaceta/video-to-ascii.git $ cd video-to-ascii $ pip install . ``` Or with audio support: ```bash $ pip install .[audio] ``` ## How to use Just run `video-to-ascii` in your terminal ```bash $ video-to-ascii -f myvideo.mp4 ``` ### Options **`--strategy`** Allow to choose a strategy to render the output. ![Render Strategies](./images/Strategies.png) **`-o --output`** Export the rendering output to a bash file to share with someone. ![Exporting](./images/export.png) **`-a --with-audio`** If an installation with audio support was made, you can use this option to play the audio track while rendering the video ascii characters. ## How it works Every video is composed by a set of frames that are played at a certain frame rate. ![Video Frames](./images/imgVideoFrames.png) Since a terminal has a specific number of rows and columns, we have to resize our video to adjust to the terminal size limitations. ![Terminal](./images/imgTerminal.png) To reach a correct visualization of an entire frame we need to adjust the _frame height_ to match the _terminal rows_, avoiding using more _characters_ than the number of _terminal columns_. ![Resizing](./images/imgResizing.png) When picking a character to represent a pixel we need to measure the relevance of that pixel's color in the frame, based on that we can then select the most appropriate character based on the [relative luminance](https://en.wikipedia.org/wiki/Relative_luminance) in colorimetric spaces, using a simplified version of the luminosity function.

> Green light contributes the most to the intensity perceived by humans, and blue light the least. This function returns an integer in the range from 0 to 255, we assign a character according to density to show more colored surface for areas with more intense color (highest values). ```python CHARS_LIGHT = [' ', ' ', '.', ':', '!', '+', '*', 'e', '$', '@', '8'] CHARS_COLOR = ['.', '*', 'e', 's', '@'] CHARS_FILLED = ['░', '▒', '▓', '█'] ``` The reduced range of colors supported by the terminal is a problem we need to account for. Modern terminals support up to 256 colors, so we need to find the closest 8 bit color that matches the original pixel in 16 or 24 bit color, we call this set of 256 colors [ANSI colors](https://stackoverflow.com/questions/4842424/list-of-ansi-color-escape-sequences). ![The Mapping of RGB and ANSI Colors](./images/imgPixelSection.png) ![8 Bits Color Table](./images/8-bit_color_table.png) Finally, when putting it all together, we will have an appropriate character for each pixel and a new color. ![Frame Image by Characters](./images/imgPixelImage.png) ## Contributors ### Code Contributors This project exists thanks to all the people who contribute. [[Contribute](./CONTRIBUTING.md)]. ### Financial Contributors Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/video-to-ascii/contribute/)]. Or maybe just [buy me a coffee](https://ko-fi.com/joelibaceta). #### Individuals #### Organizations Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/video-to-ascii/contribute)] ## As Seen On