v0.1.8
Menu
Download

Rust Core

Downloads, disk scans, ffmpeg jobs, and SponsorBlock fetches run in Rust. The React layer invokes and renders.

Command modules under src-tauri/src/commands/ own IO-heavy work. downloader.rs spawns yt-dlp children, parses stdout into download-progress events, and cleans up on pause or cancel. gallery.rs walks configured folders, merges playlist stacks, dedupes by yt-dlp id, and normalizes chapter arrays from sidecars.

media.rs runs ffmpeg/ffprobe sidecars with per-video async locks (with_per_video_ffmpeg_lock). That fixed a past deadlock where nested locks on the same file blocked sprite generation during playback. Auto scrub previews enqueue sprite sheets when a video download finishes (unless audio-only or the setting is off).

explorer_embed.rs positions the embedded browser: in-window child on Windows, parented surface on Linux dev builds. Bounds sync coalesces through explorerBoundsSync.ts during sidebar animation so IPC does not fire on every frame.

Windows-only niceties live here too: windows_audio_brand.rs renames WebView2 audio sessions in the volume mixer to "RuForge" with the app icon. Linux dev builds get broader asset scopes and platform path hydration from Tauri APIs.

In the repo

        .invoke_handler(tauri::generate_handler![
            tray_front_debug,
            get_video_info,
            start_download_job,
            pause_download_job,
            stop_all_active_download_jobs,
            scan_gallery,
            regroup_playlist_downloads,
            ensure_sponsorblock_segments,
            open_mini_player,
            open_youtube_explorer,
            get_embedded_explorer_webview_url,
            update_tray_config,
            extract_frames,
            ensure_poster_if_missing,
            delete_media,
            delete_media_batch,
            get_storage_stats,
            authorize_cleanup,
            clear_ruforge_cache,
            eval_in_webview,
            is_linux_host,
            embedded_explorer_webview_label,
            ensure_embedded_explorer_bounds,
            set_embedded_explorer_visible,
            get_hardware_acceleration_pref,
            set_hardware_acceleration_pref,
            get_hardware_acceleration_browser_args,
            open_windows_sound_settings,
            probe_local_media_ffprobe,
            open_external_url,
            get_subtitle_tracks,
            read_local_subtitle_vtt,
            get_ytdlp_update_status,
            download_ytdlp_update,
            push_background_notify,
#[tauri::command]
pub async fn scan_gallery(dir: String) -> Result<Vec<GalleryEntry>, String> {
    let dir_path = std::path::Path::new(&dir);
    if !dir_path.exists() {
        return Ok(vec![]);
    }

    sweep_download_tree_for_duplicates(dir_path);

    let mut out: Vec<GalleryEntry> = Vec::new();
    let read_dir = match std::fs::read_dir(dir_path) {
        Ok(rd) => rd,
        Err(e) => return Err(e.to_string()),
    };

    let mut entries: Vec<std::path::PathBuf> = read_dir.filter_map(|e| e.ok().map(|e| e.path())).collect();

    entries.sort_by(|a, b| {
        a.file_name()
            .unwrap_or_default()
            .to_string_lossy()
            .to_lowercase()
            .cmp(
                &b.file_name()
                    .unwrap_or_default()
                    .to_string_lossy()
                    .to_lowercase(),
            )
    });
#[tauri::command]
pub async fn extract_frames(
    app: AppHandle,
    video_path: String,
    allow_generate: Option<bool>,
) -> Result<Vec<String>, String> {
    let allow_generate = allow_generate.unwrap_or(true);
    let vk = video_path.clone();
    let result = with_per_video_ffmpeg_lock(&vk, |slot| {
        let app = app.clone();
        let video_path = video_path.clone();
        async move { extract_frames_inner(app, video_path, allow_generate, slot).await }
    })
    .await;
    if let Ok(ref paths) = result {
        if !paths.is_empty() {
            let _ = app.emit(
                "scrub-sprites-updated",
                serde_json::json!({ "videoPath": vk }),
            );
        }
    }
    result

Where it shows up

  • src-tauri/src/lib.rs command registration
  • downloader.rs, gallery.rs, media.rs, sponsorblock.rs
  • explorer_embed.rs for Explorer bounds and visibility
  • Sidecar resolution for yt-dlp, ffmpeg, ffprobe under binaries/