npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

glyphcast

v1.5.3

Published

Video as colored glyphs: a complete WebGL2 player with controls and PiP, and a glyph stream a server can send instead of video

Readme

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.