# Amharc / KnottVideo
[](https://crates.io/crates/amharc)
[](https://docs.rs/amharc)
[](https://opensource.org/license/mit)
`amharc` is the Cargo distribution of **KnottVideo**, a native Rust video
player for Linux built with GTK4 and GStreamer. It combines a cinematic desktop
viewer, a searchable local playlist, and a compact floating widget in one
offline-first application.
The installed executable is named `knott-video` so existing desktop launchers,
session data, and `Open With` integration remain compatible.
## Highlights
- Embedded local playback with loading, buffering, end-of-stream, and
recoverable error states.
- Multi-file open and drag-and-drop queue with instant search, a Continue
Watching filter, single-click playback, reordering, automatic progression,
finite shuffle cycles, repeat modes, and undo.
- A persistent media workspace with multiple recursive video folders, fast
folder switching, queue merging, reusable named playlists, M3U exchange, and
a library-wide recent history with one-click resume.
- Precise scrubbing, configurable 5/10/30-second seeking, frame stepping,
jump-to-time, and A–B looping, plus persistent named points for returning to
exact moments.
- A responsive fullscreen viewer and a compact, adjustable-opacity widget mode.
- Live Fit/Stretch video framing with an in-player shortcut and preference.
- Five persistent, live-switching cinema themes that retune the entire player,
with motion that follows the desktop reduced-animation preference.
- Persistent playlist, library-wide resume positions, private recent history,
volume, mute, speed, subtitles, repeat/shuffle state, queue visibility,
pinning, and window opacity.
- External SRT, VTT, ASS, SSA, and SUB subtitles with sidecar discovery.
- PNG frame snapshots, video-path copying, and containing-folder access.
- Local-only playback: KnottVideo does not upload media or require an account.
## Install from crates.io
KnottVideo uses native GTK4 and GStreamer libraries. On Ubuntu or Debian,
install the build and runtime dependencies first:
```sh
sudo apt install build-essential pkg-config libgtk-4-dev \
libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \
gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \
gstreamer1.0-libav
```
Then install the release from crates.io and launch it:
```sh
cargo install amharc --locked
knott-video
```
Codec availability depends on the installed GStreamer plugins.
## Build a source checkout
```sh
cargo build --release --locked
cargo run --release
```
To install the release binary, desktop entry, and application icon for the
current user:
```sh
./scripts/install.sh
```
The script installs the binary under `${XDG_BIN_HOME:-$HOME/.local/bin}` and
desktop assets under `${XDG_DATA_HOME:-$HOME/.local/share}`. Remove those files
with `./scripts/uninstall.sh`. A plain `cargo install` installs only the binary.
## Widget mode
Press `Ctrl+M` or select **Widget** to collapse KnottVideo into a focused
floating viewer. Widget mode keeps essential transport, timeline, speed,
subtitle, pin, and opacity controls close to the video while hiding the queue
and application chrome. Move the pointer or use the keyboard to reveal controls;
they retract during playback to preserve the image.
## Workspace, recents, themes, playlists, and saved points
Select **Workspace** or press `Ctrl+Shift+O` to open the media workspace. Add
as many local video folders as you need; KnottVideo scans supported files in
each folder and its subfolders without following directory symlinks. **Load**
flips the player to that folder, while **Add** merges its videos into the
current queue. Removing a folder from the workspace never deletes media from
disk.
Use **Add video files** in the Folders page (or `Ctrl+O` anywhere) to reference
individual videos in their existing locations. KnottVideo never moves or
copies them. They appear in the persistent main queue, where the search field
finds them by title or path and a click opens them directly.
The **Appearance** page includes Signal Cyan, Aurora Jade, Ember Cinema,
Ultraviolet, and Moonstone. A selection is applied live across the desktop
player, compact widget, dialogs, focus rings, glows, and controls, then saved
automatically. Press `Ctrl+,` to open Appearance directly. Interface entrances,
hover transitions, and palette-change effects honor GTK's system animation
setting, including reduced-motion configurations.
The **Playlists** page saves the current queue under a name. A playlist can be
loaded, updated from the current queue, exported as UTF-8 M3U8, or deleted
independently of its source folders. M3U and M3U8 files can be imported with
absolute paths, relative paths, or local `file://` URIs. Unavailable files are
skipped safely.
The **Recent** page remembers up to 100 opened videos across queue, folder, and
playlist changes. Resume a video at its library-wide saved position, add it to
the current queue, forget the entry, or clear the list without touching media
or named points. Files that moved or disappeared remain clearly marked so the
history never fails silently. Recent history stays entirely on the local
machine and can be disabled independently in Viewer preferences.
The **Viewer** page provides an explicit audio output switch, optional
auto-hiding playback controls, controls whether newly opened media starts
automatically, whether unfinished viewing progress and recent-video history
are stored, the
5/10/30-second seek step, and video framing. While auto-hide is enabled,
controls crossfade away during playback and return on pointer movement, key
input, or pause; the idle pointer disappears with them for a clean frame.
**Fit** preserves the source aspect ratio; **Stretch** fills
the entire viewport. Press `Ctrl+.` to open Viewer preferences directly, or
press `V` while watching to switch framing immediately. Disabling progress
memory clears previously stored resume positions; disabling recent history
clears the recent list without deleting videos.
From **Video tools**, save named points such as “Intro” or “Favorite scene.”
Points are stored per video, remain available across sessions, and can be
selected directly or flipped backward and forward with `Ctrl+Left` and
`Ctrl+Right`.
Always-on-top uses the EWMH `_NET_WM_STATE_ABOVE` hint and currently requires
an X11 session with a compatible window manager. Playback and the remaining
viewer features continue to work when that hint is unavailable.
## Keyboard shortcuts
| `Space` / `K` | Play or pause |
| `Left` / `J`, `Right` / `L` | Seek by the configured 5/10/30-second step |
| `Shift+Left` / `Shift+J`, `Shift+Right` / `Shift+L` | Seek backward or forward 60 seconds |
| `Up` / `Down` | Raise or lower volume |
| `Home` / `End` | Seek to the beginning or end |
| `P` / `N` | Previous or next video |
| `S` | Toggle shuffle |
| `R` | Cycle repeat off, playlist, and current video |
| `Q` | Show or hide the playlist |
| `.` | Advance one frame |
| `A` / `B` | Set A–B loop points; press again to clear |
| `T` | Toggle always-on-top |
| `V` | Cycle Fit and Stretch video framing |
| `[` / `]` | Decrease or increase window opacity |
| `Ctrl+T` | Jump to a time |
| `Ctrl+O` | Add videos |
| `Ctrl+F` | Find videos in the queue |
| `Ctrl+Shift+O` | Open the media workspace |
| `Ctrl+,` | Open appearance themes |
| `Ctrl+.` | Open viewer preferences |
| `Ctrl+D` | Save a named point in the current video |
| `Ctrl+Left` / `Ctrl+Right` | Previous or next saved point |
| `F` / `Escape` | Enter or leave fullscreen |
| `M` | Mute or restore audio |
| `Ctrl+M` | Toggle widget mode |
| `Ctrl+R` | Cycle playback speed |
| `Ctrl+Shift+S` | Save the current frame as PNG |
| `Ctrl+Up` / `Ctrl+Down` | Move the selected video |
| `Delete` | Remove the selected video |
| `Ctrl+Delete` | Clear the playlist |
| `?` | Show the in-app shortcut guide |
## Supported media
The player recognizes MP4/M4V, Matroska, WebM, AVI, MOV, MPEG, Ogg, transport
stream, FLV, WMV, and 3GP files. Actual decoding support is provided by the
local GStreamer installation.
## Development and documentation
The standard release gates are:
```sh
cargo fmt --all -- --check
cargo test --locked
cargo clippy --all-targets --locked -- -D warnings
cargo doc --no-deps --no-default-features --locked
cargo package --locked
```
API and package documentation is published at [docs.rs/amharc](https://docs.rs/amharc).
Release history is recorded in the
[packaged changelog](https://docs.rs/crate/amharc/latest/source/CHANGELOG.md).
## Author and license
Created by **Trevor Knott** at **Knott Dynamics**.
Licensed under the [MIT License](https://opensource.org/license/mit).