glyphcast

Video as colored glyphs: a complete WebGL2 player with controls and PiP, and a glyph stream a server can send instead of video
4,980
Install
npm install glyphcast
Latest Version:1.5.3
Vue:3
License:MPL-2.0
Last Updated:Oct 20, 2026
Links: GitHub  ·  npm
Maintainer: lopik

glyphcast

npm JSR crates.io glc.exe License: MPL-2.0

English version · Песочница · Хаб

Опенинг One Piece в режиме Брайля

Опенинг One Piece в режиме Брайля, 180 колонок.

Видео цветными символами. Полноценный плеер для браузера: управление, настройки, субтитры, горячие клавиши, картинка в картинке и полный экран, а каждый кадр перерисовывается символами шейдером WebGL2. Сервер может присылать вместо видео сами символьные кадры, и браузер получает компактный поток .gcast, а не исходное видео. Тот же поток играет и в терминале.

npm install glyphcast
<script type="module">import 'glyphcast/element';</script>

<glyph-player src="movie.mp4" cols="160"></glyph-player>
<glyph-player src="movie.gcast" audio="movie.m4a" subtitles="movie.vtt"></glyph-player>
<glyph-player youtube="https://youtu.be/…" server="http://127.0.0.1:8787"></glyph-player>

Без сборщика: import 'https://cdn.jsdelivr.net/npm/glyphcast@1/dist/element.js/+esm'.

Где играет

🌐 Браузер <glyph-player>, React, Vue WebGL2, управление, субтитры, выбор качества
💻 Терминал glc play movie.gcast 24-битный цвет, звук через ffplay, те же клавиши
🪟 Windows glc.exe нативный, меньше 1 МБ, звук внутри, без Node
📡 Telnet glc telnet movie.gcast смотреть может кто угодно: telnet host 2323, без установки
🦀 Rust крейт glyphcast кодер и декодер, байт в байт как JS, без зависимостей

glc.exe

Консольный плеер для Windows одним файлом меньше 1 МБ: без Node и ffmpeg, со звуком и хабом. Скачайте из Releases, запустите двойным щелчком для меню хаба или перетащите на него .gcast:

glc.exe movie.gcast            # файл
glc.exe hub:<id>               # видео из хаба
glc.exe --lang ru              # интерфейс на русском

Telnet

glc telnet movie.gcast --port 2323     # затем с любой машины: telnet <host> 2323

Каждое подключение получает свой плеер с перемоткой и режимами. Звука по telnet нет, у зрителя нужен терминал с 24-битным цветом (Windows Terminal, iTerm2, большинство терминалов Linux).

Rust

[dependencies]
glyphcast = "1"
use glyphcast::format::{decode_chunk, Reader};

let mut reader = Reader::new();
reader.push(&std::fs::read("movie.gcast")?)?;
let info = reader.info.unwrap();
for chunk in &reader.chunks {
    for frame in decode_chunk(&info, &chunk.data)? {
        // frame.rgb: цвет клетки, frame.masks: её точки Брайля 2×4
    }
}

Крейт пишет те же файлы байт в байт, что и JS-кодер, примерно в 3,5 раза быстрее. Подробнее в native/glyphcast.

Плеер

<glyph-player> играет видео, камеру, локальные файлы и потоки .gcast. Внутри: воспроизведение и пауза, ±10 секунд, полоса перемотки с загруженной частью и подсказкой времени, громкость, скорость, картинка в картинке (через Document PiP весь плеер целиком, где браузер это умеет, иначе только изображение), полный экран и меню настроек: ширина сетки, способ отрисовки (символы, точки Брайля или растр), набор символов, цвет, насыщенность, автоуровни, контуры и кинескоп. С контурами клетки на границах предметов рисуются символами - / | \ по направлению границы, а кинескоп добавляет строки развёртки, виньетку и свечение. Во время воспроизведения панель прячется.

Атрибут
src Ссылка на видео или файл .gcast
poster Картинка, которая видна до первого кадра
audio Звук для файла .gcast
youtube, file, server Поток через glyphcast serve (см. ниже)
subtitles Субтитры WebVTT или SRT, рисуются той же сеткой символов
cols Ширина сетки в символах, по умолчанию 160
glyphs Символы от тёмного к светлому, по умолчанию ' .:-=+*#%@'
tint Один цвет для всех символов, например #33ff66
boost Насыщенность, по умолчанию 1.3
autolevels false выключает подстройку яркости и контраста
mode glyphs, braille или halftone
edges, crt Контуры и вид кинескопа
sharp false выключает чёткость ×2 (апскейл по границам)
smooth false выключает плавность (промежуточные кадры по движению блоков)
fill Подсветка фона клетки её цветом, от 0 до 1, по умолчанию 0.25
autoplay, muted, loop Как у <video>

Клавиши: пробел или K пауза, ←/→ 5 с, J/L 10 с, ↑/↓ громкость, M звук, F полный экран, P картинка в картинке, 0–9 переход. Оформление меняется через --accent и --radius; element.load(файлПотокИлиСсылка) и element.player дают управление из кода.

React и Vue

import { GlyphPlayer } from 'glyphcast/react';

<GlyphPlayer src="/movie.gcast" poster="/movie.jpg" mode="braille" onReady={(player) => player.play()} />
<script setup>
import { GlyphPlayer } from 'glyphcast/vue';
</script>

<template>
  <GlyphPlayer src="/movie.gcast" poster="/movie.jpg" mode="braille" @ended="next" />
</template>

Пропсы те же, что атрибуты (autoPlay, autoLevels в camelCase), плюс события play, pause, ended, timeupdate, error и ready с движком. Элемент подгружается после монтирования, поэтому обёртки работают и с серверным рендерингом.

Без интерфейса тот же движок называется GlyphPlayer и повторяет API медиаэлемента: load, play, pause, seek, currentTime, duration, volume, muted, playbackRate, configure(look), setCaptions(текстИлиСсылка) и привычные события.

Символы вместо видео

При 160 колонках кадр состоит примерно из девяти тысяч цветных клеток, это намного меньше кадра видео. .gcast хранит у каждой клетки яркость (6 бит), цвет один на квадрат 2×2 клетки (как 4:2:0 в видео), а с --detail ещё и узор из 2×4 точек у клеток с резкими краями. Сетка нарезана на блоки 8×4: блок предсказывается из прошлого кадра со сдвигом с точностью до точки или из соседей в том же кадре, и передаётся только то, что предсказание не угадало. Всё кодируется адаптивным арифметическим кодером с контекстами (узоры — точка за точкой по соседям, как в JBIG2), поэтому формату не нужен архиватор общего назначения, а декодер маленький. Куски примерно по две секунды начинаются с точного опорного кадра, новая сцена начинает новый кусок. Формат полностью описан в FORMAT.md и заморожен с версии 1.0: все следующие версии его играют. Звук можно вшить прямо в .gcast: он идёт перед кадрами, плеер достаёт его и ведёт по нему время. В песочнице есть конвертер, который делает .gcast из вашего видео прямо в браузере (кодирование идёт в Web Worker) и показывает, во сколько раз файл стал меньше, а рядом готовую команду для консоли. Целые фильмы лучше конвертировать в консоли: браузер не удержит в памяти их звук. В конце файла лежит индекс кусков: плеер читает его range-запросом и при перемотке сразу качает нужное место, не дожидаясь загрузки всего файла. Формат потоковый: у кусков есть длина, поэтому плеер начинает с первого же куска, а сервер может выдавать их на лету.

npx glyphcast encode movie.mp4 --cols 180 --embed --poster    # один файл со звуком Opus внутри и постер movie.jpg
npx glyphcast encode movie.mp4 --detail                       # узор 2×4 точек из исходника: чёткий текст в режиме Брайля, файл больше примерно на 50%
npx glyphcast encode *.mp4 --embed                            # несколько видео подряд, с прогрессом и оставшимся временем
npx glyphcast encode movie.mp4 --cols 180 --audio movie.m4a   # звук отдельным файлом
npx glyphcast hub                                               # видео в gcast hub, смотреть: npx glyphcast play hub:имя
npx glyphcast play movie.gcast                                  # в терминале: пробел пауза, ←/→ перемотка, M отрисовка, G символы, C цвет, [ ] насыщенность, B фон, Q выход
npx glyphcast serve --dir ./videos                              # живые потоки
npx glyphcast micro movie.mp4 --cols 180                        # крошечное H.264 размером с сетку

glyphcast serve превращает ссылки на YouTube (через yt-dlp) и видео из папки --dir в живые потоки .gcast с отдельным звуком Opus, перематывает, перезапуская поток с нужной секунды, и отдаёт готовые файлы с поддержкой range-запросов. Слушает только 127.0.0.1. Браузер сам не может читать кадры YouTube, поэтому YouTube работает именно через этот сервер. glyphcast play принимает и ссылку на такой поток, так что YouTube можно смотреть прямо в терминале.

Минута фильма, только картинка, 24 к/с:

Что отправляется Размер Битрейт
Исходник, 1280×544 H.264 4,20 МБ 587 кбит/с
.gcast 0.26 (формат 5), 180 колонок, --detail 1,55 МБ 217 кбит/с
.gcast 1.0 (формат 6), 180 колонок, --detail 0,98 МБ 137 кбит/с
.gcast 1.0, 180 колонок 0,52 МБ 73 кбит/с
.gcast 1.0, 120 колонок, --detail 0,50 МБ 69 кбит/с
Микровидео, 180 колонок H.264 0,29 МБ 41 кбит/с

Файлы формата 6 на 32–39% меньше формата 5 на фильмах, мультфильмах и записях экрана и при этом ближе к исходнику (SSIM картинки из точек выше на 0,03–0,07). Размер потока зависит от сетки и движения в кадре, а не от разрешения исходника. Микровидео размером с сетку всё равно меньше: видеокодеки десятилетиями оттачивали под пиксели. .gcast хранит то, что рисуется, — клетки и узоры их точек, поэтому ему не нужен видеодекодер, он одинаково играет в браузере и в текстовом терминале, сохраняет тонкие линии и текст точками, и его можно генерировать или править покадрово. В Node модуль glyphcast/node даёт encodeVideo, encodeMicroVideo, extractAudio и serve, а Encoder собирает поток из сырых кадров любого источника.

Хаб

gcast hub хранит видео в .gcast и показывает их в браузере. Те же видео играют в консоли:

npx glyphcast hub                  # список и поиск
npx glyphcast play hub:<имя>       # смотреть со звуком, паузой и перемоткой
npx glyphcast login                # вход через Google (в браузере), нужен для загрузки
npx glyphcast publish movie.mp4 --title "Название"   # закодировать три сетки со звуком и загрузить

Загрузка требует входа через Google — на сайте или командой glc login. Новое видео сразу открывается по ссылке, а в общий список попадает после проверки. Правила и конфиденциальность.

Лицензия

Mozilla Public License 2.0 (см. LICENSE и NOTICE): изменения в файлах glyphcast остаются открытыми, ваш код вокруг может быть закрытым. Версии до 0.20.13 вышли под MIT, 0.21.0–0.21.3 — под Apache 2.0.

Related Packages

alpha-video-player-js

Web 视频动画特效播放 sdk

2,116 2
@fxshelf/glyph-rain

Matrix-style glyph rain with cursor stir and drop-head lighting for React and Vu...

295 0
nplayer

powerful danmaku video player

7,545 1,394
@nplayer/danmaku

powerful danmaku video player

2,862 1,394
@nplayer/vue

powerful danmaku video player

1,175 1,395

Version History

Version Released License
1.5.3 MPL-2.0
1.5.2 MPL-2.0
1.5.1 MPL-2.0
1.4.0 MPL-2.0
1.3.0 MPL-2.0
Pre-releases (1)
Version Released License
0.0.0-stage