| Crates.io | tvid |
| lib.rs | tvid |
| version | 0.2.1 |
| created_at | 2025-09-26 20:50:40.782579+00 |
| updated_at | 2026-01-16 23:28:20.326902+00 |
| description | A terminal video player |
| homepage | https://github.com/copi143/tvid |
| repository | https://github.com/copi143/tvid |
| max_upload_size | |
| id | 1856610 |
| size | 2,647,583 |
tvid is a terminal video player written in Rust. It uses FFmpeg for decoding and renders video, audio and subtitles directly inside your terminal, providing an overlay UI, playlist view and basic mouse / keyboard interaction.
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
This project is under active development. Behaviour and UI may change.
~/.config/tvid/sudo apt install cargo or sudo apt install rustup && rustup install stablesudo pacman -S rust or sudo pacman -S rustup && rustup install stablesudo apt install ffmpeg libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-devsudo pacman -S ffmpegYou can install tvid directly using Cargo:
cargo install tvid
Optional features are enabled at build time. Defaults are ffmpeg, i18n, config, audio, video, subtitle, unicode, unifont.
cargo install tvid --features sixel,osc1337
# or disable defaults and pick a minimal set
cargo install tvid --no-default-features --features ffmpeg,video
Clone the repository:
git clone https://github.com/copi143/tvid.git
cd tvid
Build the project:
cargo build --release
With optional features:
cargo build --release --features sixel,osc1337
# or disable defaults and pick a minimal set
cargo build --release --no-default-features --features ffmpeg,video
Run the player:
cargo run -- <input1> [input2] [...]
# or, after building
target/release/tvid <input1> [input2] [...]
tvid <input1> [input2] [...]
Each input becomes an item in the in‑memory playlist.
On first run, tvid creates a config directory and two files:
~/.config/tvid/tvid.toml
volume (0–200): initial volumelooping (true / false): whether to loop the playlistplaylist.txt
# comments are ignoredAt startup, tvid loads the playlist from playlist.txt and then appends any files passed on the command line.
Core playback controls (global):
Space – play / pauseq – quit player← – seek backward 5 seconds→ – seek forward 5 seconds↑ – seek backward 30 seconds↓ – seek forward 30 secondsPlaylist controls:
n – play next item in playlistl – toggle playlist side panelw / ↑ – move selection ups / ↓ – move selection downSpace / Enter – play selected itemq – close playlist panelUI & other controls:
f – open file selector (UI panel)c – cycle color modeNote: additional shortcuts and UI elements may be added while the project evolves.
Press / to open the command input, then:
Enter – run the commandEsc – cancelTab – autocomplete (commands or arguments)↑ / ↓ – command historyExamples:
/seek +5/volume 80/lang zh-cnAvailable language codes: 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
vlc run correctly).av init failed:
No input files.:
~/.config/tvid/playlist.txt contains valid, accessible paths.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:
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:
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)