Tauri Commands: Streaming¶
All streaming Tauri commands are implemented in src-tauri/src/vozduxan_stream.rs. They are the bridge between the frontend audio player and the vozduxan C++ library.
Source: src-tauri/src/vozduxan_stream.rs
Command reference¶
torrent_prepare_stream¶
Starts or resumes playback of a specific file within a torrent.
// Frontend
const ready = await invoke<{ url: string }>("torrent_prepare_stream", {
magnet: string,
fileIdx: number,
torrentFileB64: string | null, // base64 .torrent file, or null
});
// ready.url = "http://127.0.0.1:<port>/stream/<token>"
Rust side: decodes torrentFileB64 from base64 if present, then calls state.prepare(app, magnet, fileIdx, torrent_bytes). See Rust Wrapper — prepare() for the full token-bucket logic and version-guard pattern.
If torrentFileB64 is provided, vozduxan starts the torrent from the binary content directly, skipping the DHT metadata exchange. This saves several seconds on first-time playback for RuTracker tracks.
Returns: { url: string } — the local HTTP stream URL.
torrent_release_stream¶
Releases a stream by token. Called when a track ends, is skipped, or the component unmounts.
Rust side: runs in spawn_blocking because vozduxan_stream_release joins the C++ priority thread (~100 ms). The blocking call must not happen on the async executor thread.
After the C++ call returns, the Rust side:
1. Clears whichever token bucket held this token (current_token, prefetch_token, or warm_prefetch_token).
2. Increments the eviction counter. Every 10 releases, calls vozduxan_session_evict to remove idle torrents whose TTL has expired from the libtorrent session.
torrent_dispose_preview¶
Releases all active tokens (current + prefetch + warm). Called by the cache purge action in Settings.
Rust side: runs in spawn_blocking. Collects all three token values (taking them from the mutexes) before entering C++, then releases them sequentially. This mutex-drop-before-C++ pattern avoids serializing unrelated Tauri commands during the ~300 ms total C++ join time (3 tokens × ~100 ms each).
After releasing, calls vozduxan_session_evict unconditionally.
torrent_prepare_cancel¶
Cancels an in-flight torrent_prepare_stream call.
Sets the prepare_cancelled AtomicBool to true. The prepare() loop in Rust polls this flag and returns an error when it's set. This is used by the player when the user switches tracks before the current track finishes buffering.
torrent_prefetch_next_track¶
Warms the next track's piece priority window without blocking the current track.
const result = await invoke("torrent_prefetch_next_track", {
currentMagnet: string,
currentFileIdx: number,
nextMagnet: string,
nextFileIdx: number,
nextTorrentFileB64: string | null,
warmOnly: boolean, // false = track+1 bucket, true = track+2 bucket
});
currentMagnet and currentFileIdx are accepted for API compatibility but unused in the vozduxan path — vozduxan manages the active session internally and doesn't need the current track identity to schedule prefetch.
warmOnly = false → stores in prefetch_token (the real next track).
warmOnly = true → stores in warm_prefetch_token (second-ahead warm-up).
vozduxan_notify_position¶
Forwards the current playback byte offset to the C++ priority scheduler.
await invoke("vozduxan_notify_position", {
token: string,
byteOffset: number, // current playback position in bytes
});
Called on every timeupdate event from the <audio> element and on seek. The C++ priority worker uses this to slide the piece priority window forward.
This command is non-blocking on the Rust side — it calls notify_position which immediately writes to the token's state structure without any mutex contention on the C++ side.
vozduxan_stream_stats¶
Returns download rate and peer count for a stream token. Used by the stream status popup in the player UI.
const stats = await invoke<{ downloadRate: number; numPeers: number }>(
"vozduxan_stream_stats",
{ token: string }
);
Calls vozduxan_stream_stats in C++ directly — no spawn_blocking needed because it only reads from lightweight statistics fields.
torrent_magnet_list_files¶
Lists the files inside a magnet/torrent without starting playback.
Used to enumerate files before the user selects a specific track to play. Calls state.list_files(magnet, None) — see Rust Wrapper.
spawn_blocking discipline¶
Commands that call C++ code that blocks for significant time (priority thread joins, eviction) use tokio::task::spawn_blocking. This moves the blocking call off the async executor thread pool, preventing it from starving other pending commands.
The pattern:
tokio::task::spawn_blocking(move || {
// C++ call here (may block for ~100 ms)
unsafe { ffi::vozduxan_stream_release(inner.ptr, token_c.as_ptr()) };
// post-C++ cleanup
})
.await
.map_err(|e| format!("spawn_blocking error: {e}"))
Commands that only read lightweight statistics or write flags (vozduxan_notify_position, torrent_prepare_cancel) do not need spawn_blocking.