tvid — видеоплеер для терминала на Rust. Он использует FFmpeg для декодирования и рендерит видео, аудио и субтитры прямо в терминале, предоставляя оверлейный UI, список воспроизведения и базовые взаимодействия клавиатуры/мыши.
Translations (by ChatGPT):
en-us/English | zh-cn/简体中文 | zh-tw/繁體中文 | ja-jp/日本語 | fr-fr/Français | de-de/Deutsch | es-es/Español | ko-kr/한국어 | pt-br/Português (Brasil) | ru-ru/Русский | it-it/Italiano | tr-tr/Türkçe | vi-vn/Tiếng Việt
Проект активно развивается. Поведение и интерфейс могут изменяться.
- Воспроизводит почти любой формат, поддерживаемый FFmpeg
- Вывод аудио и рендеринг субтитров (ASS / текст)
- Несколько режимов рендера: true color, 256 цветов, градации серого, ASCII art, Braille Unicode
- Опциональные протоколы изображений: Sixel и OSC 1337 (стиль iTerm2)
- Оверлейный UI в терминале: прогресс-бар, сообщения и справка на экране
- Поддержка плейлистов:
- передача нескольких файлов через командную строку
- навигация по плейлисту в памяти (следующий/предыдущий, цикл)
- опциональная боковая панель плейлиста
- Управление мышью и клавиатурой для перемотки и навигации
- Файл конфигурации и плейлист по умолчанию в
~/.config/tvid/ - Локализованный UI (системная локаль) и Unifont для поддержки глифов
- Актуальный toolchain Rust (nightly не требуется)
- Debian / Ubuntu:
sudo apt install cargoилиsudo apt install rustup && rustup install stable - Arch:
sudo pacman -S rustилиsudo pacman -S rustup && rustup install stable
- Debian / Ubuntu:
- Библиотеки FFmpeg и заголовки разработчика
- Debian / Ubuntu:
sudo apt install ffmpeg libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev - Arch:
sudo pacman -S ffmpeg
- Debian / Ubuntu:
Можно установить tvid напрямую через Cargo:
cargo install tvidОпциональные фичи включаются при сборке. По умолчанию: ffmpeg, i18n, config, audio, video, subtitle, unicode, unifont.
cargo install tvid --features sixel,osc1337
# или отключить стандартные фичи и выбрать минимум
cargo install tvid --no-default-features --features ffmpeg,video-
Клонировать репозиторий:
git clone https://github.com/copi143/tvid.git cd tvid -
Сборка проекта:
cargo build --release
Опциональные фичи включаются при сборке. По умолчанию:
ffmpeg,i18n,config,audio,video,subtitle,unicode,unifont.cargo build --release --features sixel,osc1337 # или отключить стандартные фичи и выбрать минимум cargo build --release --no-default-features --features ffmpeg,video -
Запуск плеера:
cargo run -- <input1> [input2] [...] # или после сборки target/release/tvid <input1> [input2] [...]
tvid <input1> [input2] [...]Каждый входной файл становится элементом плейлиста в памяти.
При первом запуске tvid создаёт каталог и два файла:
- Каталог конфигурации:
~/.config/tvid/ - Файл конфигурации:
tvid.toml- пример ключей:
volume(0–200): начальная громкостьlooping(true/false): зацикливание плейлиста
- пример ключей:
- Файл плейлиста:
playlist.txt- каждая строка — путь к файлу
- пустые строки и комментарии
#игнорируются
При запуске tvid загружает playlist.txt, затем добавляет файлы из командной строки.
Основные управление (глобально):
Space– воспроизведение / паузаq– выход- Стрелки – перемотка
←– назад на 5 секунд→– вперёд на 5 секунд↑– назад на 30 секунд↓– вперёд на 30 секунд
Управление плейлистом:
n– следующий элементl– показать/скрыть боковую панель плейлиста- В панели плейлиста:
w/↑– переместить выбор вверхs/↓– внизSpace/Enter– воспроизвести выбранный элементq– закрыть панель плейлиста
UI и другое:
f– открыть выбор файлаc– переключить цветовой режим- Прогресс-бар:
- левый клик рядом с нижней областью прогресса для перемотки
- перетаскивание левой кнопкой для скраббинга
Примечание: по мере развития проекта могут появляться новые сочетания и элементы UI.
Нажмите /, чтобы открыть ввод команды, затем:
Enter– выполнить командуEsc– отменитьTab– автодополнение (команды или аргументы)↑/↓– история команд
Примеры:
/seek +5/volume 80/lang zh-cn
Доступные коды языка: en-us, zh-cn, zh-tw, ja-jp, fr-fr, de-de, es-es, ko-kr, pt-br, ru-ru, it-it, tr-tr, vi-vn.
- Ошибки сборки:
- Убедитесь, что FFmpeg и его headers установлены.
- Ошибка загрузки shared libraries (при запуске):
- Убедитесь, что компилируете и запускаете на одной машине.
- Проверьте, доступны ли runtime-библиотеки FFmpeg (например, работает ли
vlc).
- При старте:
av init failed:- Проверьте, что FFmpeg работает корректно.
- После старта:
No input files.:- Убедитесь, что:
- передан хотя бы один доступный видео/аудио файл, или
~/.config/tvid/playlist.txtсодержит валидные пути.
- Убедитесь, что:
Copyright (c) 2025 copi143
This project is dual-licensed under either:
at your option.
You can choose either license according to your needs.
You may obtain copies of the licenses at:
- MIT: LICENSE-MIT or https://opensource.org/licenses/MIT
- Apache-2.0: LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the licenses for the specific language governing permissions and limitations.
The file unifont-17.0.01.bin included in this project is a binary font file generated from the original unifont-17.0.01.hex source file using a Python script. The conversion process does not modify the font data, only its format.
The original Unifont files are dual-licensed under:
- GNU General Public License (GPL) version 2 or (at your option) any later version, with the GNU Font Embedding Exception
- SIL Open Font License (OFL) version 1.1
For details, see the included OFL-1.1.txt file, or visit the GNU Unifont website.
The Python script used for conversion is provided below for reference:
with open('unifont-17.0.01.hex', 'r', encoding='utf-8') as f:
lines = f.readlines()
result: list[bytearray | None] = [None] * 65536
for line in lines:
if line.startswith('#') or line.strip() == '': continue
parts = line.strip().split(':')
if len(parts) != 2: continue
codepoint = int(parts[0], 16)
glyph_data = parts[1] if len(parts[1]) == 64 else ''.join([parts[1][i:i + 2] + '00' for i in range(0, 32, 2)])
bytes_data = bytes(int(glyph_data[i:i + 2], 16) for i in range(0, 64, 2))
data = bytearray(32)
for y in range(0, 16):
for x in range(0, 16):
bit = (bytes_data[y * 2 + x // 8] >> (7 - x % 8)) & 1
if bit:
bidx = y // 4 * 8 + x // 2
bbit = y % 4 * 2 + x % 2
data[bidx] |= 1 << [0, 3, 1, 4, 2, 5, 6, 7][bbit]
result[codepoint] = data
with open('unifont-17.0.01.bin', 'wb') as f:
for entry in result:
if entry is None:
f.write(b'\x00' * 32)
else:
f.write(entry)