mirror of
https://github.com/narrrl/proton-stream.git
synced 2026-11-03 16:41:26 +01:00
56 lines
2.4 KiB
Rust
56 lines
2.4 KiB
Rust
//! Playback, through libmpv, of streams that only exist behind a Proton link.
|
|
//!
|
|
//! mpv is not asked to download anything. A custom `pstr://` protocol is
|
|
//! registered with `mpv_stream_cb_add_ro`, and mpv's demuxer reads through it
|
|
//! exactly as it would read a local file — small reads, seeks, an EOF. Every one
|
|
//! of those lands in [`pstr_stream`], which serves it from the block ring, the
|
|
//! disk cache or Proton, in that order.
|
|
//!
|
|
//! ```text
|
|
//! Player::play(stream) registry: 7 → VideoStream
|
|
//! │ loadfile pstr://7 ▲
|
|
//! ▼ │ hash lookup, no I/O
|
|
//! mpv demuxer thread ── read/seek/size ──▶ StreamCursor ──▶ VideoStream
|
|
//! │ │
|
|
//! └── cancel (another thread) ──▶ CancelLatch ─┘
|
|
//! ```
|
|
//!
|
|
//! Three things about that shape are deliberate:
|
|
//!
|
|
//! * **mpv gets a token, not an identity.** The URL fragment of a Proton share
|
|
//! link *is* its decryption password, and mpv puts a stream's URL in its log,
|
|
//! its `path` property and its window title. A `u64` leaks nothing.
|
|
//! * **The open callback does no work.** Opening a revision can take seconds and
|
|
//! fail for reasons a person needs to read; mpv's open callback can only say
|
|
//! "loading failed". So the caller opens first and registers the result.
|
|
//! * **`stream_cb`, not a loopback HTTP server.** No port, no other local
|
|
//! process able to ask for the plaintext, no decrypted bytes leaving the
|
|
//! process.
|
|
//!
|
|
//! Where the picture ends up is a separate axis, and the streaming path above
|
|
//! is identical either way: [`VideoOutput::Window`] lets mpv make a window, and
|
|
//! [`VideoOutput::Embedded`] plus a [`VideoRenderer`] draws each frame into an
|
|
//! OpenGL framebuffer the caller owns. Only [`PlayerConfig`] and [`render`] know
|
|
//! the difference.
|
|
|
|
mod chapters;
|
|
mod cursor;
|
|
mod error;
|
|
mod gl;
|
|
mod player;
|
|
mod protocol;
|
|
mod registry;
|
|
mod render;
|
|
#[cfg(test)]
|
|
mod testing;
|
|
mod tracks;
|
|
|
|
pub use chapters::{Chapter, ChapterRole, chapter_at, chapter_end, credits_start, roles};
|
|
pub use error::{Error, Result};
|
|
pub use player::{
|
|
EndReason, MAX_VOLUME, Player, PlayerConfig, PlayerEvent, READAHEAD_BLOCKS, VideoOutput,
|
|
};
|
|
pub use registry::{PROTOCOL, StreamHandle, StreamRegistry};
|
|
pub use render::VideoRenderer;
|
|
pub use tracks::{Track, TrackKind, language_name};
|