alhazen-gpui
Native video playback for GPUI apps. A VideoPlayer entity and a
video_view element, powered by the alhazen-core
media engine.
let video = cx.new;
// in render():
video_view.size_full
- Plays common formats with nothing installed: MP4, MOV, MKV and WebM, with AV1, VP9, VP8, ProRes, Opus, Vorbis, FLAC and PCM in pure Rust on every platform.
- On Windows: H.264, HEVC, VP9 and AV1 decode on the GPU, plus AAC, MP3, AC-3 and ALAC, through Windows' own decoders.
- On Linux with an NVIDIA GPU: H.264, HEVC, VP8, VP9 and AV1 decode on the GPU (NVDEC), scaled to the size you display them at. Loaded from the driver at runtime: nothing to install.
- Everything else goes through the user's
ffmpeg, if installed. It's found at runtime, never linked. - Local files and HTTP(S) streaming, with seeking.
- HLS (
.m3u8), VOD and live: adaptive quality with a manual override, audio in a separate playlist, AES-128. - Smooth playback: audio-driven sync, late-frame dropping, decoding at the size you display, and automatic fallback to a faster decoder.
Quick start
[]
= "0.2.2"
= "0.5"
# Decoding unoptimized is many times slower than real time: optimize the decoders even in
# debug builds.
[]
= 3
[]
= 3
use ;
use ;
The example player
examples/play.rs is a complete player window: progress bar, seeking,
volume and a status line, in plain GPUI divs. It's meant to be copied:
For HLS streams a Quality button cycles Auto → each variant → Auto.
API
VideoPlayer (a GPUI entity)
Create it with cx.new(|cx| VideoPlayer::new(source, config, cx)). Opening happens in the
background; state() is Loading until then.
Control (takes cx) |
Query |
|---|---|
play, pause, toggle |
state, is_playing |
seek(Duration) |
position, duration, is_seekable |
set_volume(0.0..=1.0), set_muted(bool) |
volume, is_muted |
has_video, has_audio, video_size |
|
metadata(): title, artist, album, … of the file; cover(): its embedded cover art, decoded |
|
set_variant(Variant) (HLS) |
variants(), current_variant() |
player(): the engine's Player (stats, events, audio renditions) once opened |
Events (cx.subscribe) are the engine's PlayerEvents: StateChanged, FrameReady,
Warning, Error, Ended, and VariantChanged for HLS quality switches.
video_view(player) (an element)
Styled like a div (.size_full(), .w(px(640.)), .rounded_md(), ...). It letterboxes by
default; change that with .object_fit(gpui::ObjectFit::Cover) (or Fill, ScaleDown,
None). It tells the engine the size it's drawn at, so large videos are decoded down to that
size before colour conversion. For audio-only media it draws the file's cover art, if it has one.
Configuration
PlayerConfig and Source come from alhazen-core and are re-exported here. The engine itself
is available as alhazen_gpui::alhazen_core. See
alhazen-core's README for every
setting: audio output, GPU preference, backend order, ffmpeg path, buffering.
Cargo features
The same as alhazen-core's, forwarded to it:
| Feature | Default | Adds |
|---|---|---|
native |
✅ | Pure-Rust decoders and the MP4/MOV demuxer. |
http |
✅ | HTTP(S) sources. |
hls |
✅ | HTTP Live Streaming (.m3u8). The play example needs it. |
audio-output |
✅ | Sound through the default output device. |
ffmpeg-cli |
✅ | The user's ffmpeg, found at runtime. |
media-foundation |
✅ | Windows' (GPU) decoders; nothing on other platforms. |
nvdec |
✅ | NVIDIA GPU decoding on Linux, loaded from the driver at runtime; nothing on other platforms. |
native-aac |
✅ | AAC-LC, HE-AAC and HE-AACv2 in pure Rust (rusty_aac). |
native-mp3 |
✅ | MP3 in pure Rust (rusty_mp3). |
Debugging playback
Set ALHAZEN_DEBUG=1 to print one line per second to stderr: position, frames shown per
second, paint cost, how far the video is behind the clock, dropped frames, state and which
decoder is in use. For example:
[alhazen] pos 12.04s | shown 60 fps | paint avg 1.2 ms, worst 2.0 ms | frame behind clock 3.0 ms | dropped 0/s | state Playing | video media-foundation
Platform requirements
- Rust 1.92+.
- x86-64:
nasmonPATH(rav1d's AV1 assembly). - Linux: GPUI's requirements (Vulkan,
libxkbcommon, Wayland/X11 headers) and ALSA headers for sound (libasound2-dev). - Windows 10/11, macOS: nothing else.
- GPU decoding on Linux: an NVIDIA GPU with its proprietary driver (optional; without it, playback uses the other decoders).
License
Apache License, Version 2.0 (LICENSE). If you distribute an app that contains alhazen-gpui, include the NOTICE text (Apache-2.0 §4(d)), for example in an "About" or "Licenses" screen.
Part of Alhazen.