Skip to content

fix(services): reorder binary path resolution, mux progress, thumbnails#44

Open
usrbinkat wants to merge 1 commit intovanloctech:mainfrom
usrbinkat:fix/path-resolution-mux-progress-thumbnails
Open

fix(services): reorder binary path resolution, mux progress, thumbnails#44
usrbinkat wants to merge 1 commit intovanloctech:mainfrom
usrbinkat:fix/path-resolution-mux-progress-thumbnails

Conversation

@usrbinkat
Copy link

@usrbinkat usrbinkat commented Mar 8, 2026

Problem

Binary path resolution in ffmpeg.rs, ytdlp.rs, and deno.rs checks hardcoded paths (/opt/homebrew/bin, /usr/local/bin, /usr/bin) before $PATH entries. This causes the app to miss binaries provided by Nix, Homebrew, or other package managers that express their binaries through PATH. On macOS, GUI apps launched from Finder don't inherit the user's shell PATH, making the hardcoded fallbacks essential — but they should be fallbacks, not the primary resolution mechanism.

Expected: The app resolves yt-dlp, ffmpeg, and deno from the user's PATH first, then falls back to well-known locations.
Actual: Hardcoded paths win over PATH entries. A stale or missing binary at /usr/local/bin/ffmpeg shadows a working one in PATH (see #42).

Additionally:

  • The yt-dlp sidecar placeholder created by build.rs for dev builds (a 22-byte shell stub) is returned as a valid bundled binary by get_bundled_ytdlp_path(), causing silent failures at runtime.
  • deno.rs checks ~/.deno/bin/deno (curl installer location) before which deno, so a system-provided deno on PATH is shadowed by a stale home-dir install.
  • During --download-sections downloads, yt-dlp delegates the mux/merge to ffmpeg. The progress parser only handles [download] X% lines — ffmpeg stderr progress (time=, speed=, Lsize=) is ignored, leaving the progress bar stuck at 0%.
  • UniversalQueueItem has no YouTube thumbnail fallback. When metadata fetch fails, the queue shows a blank grey placeholder instead of the readily available img.youtube.com thumbnail.
  • Firefox profile selection returns profiles in file order. The active profile (where cookies live) is often not first, causing --cookies-from-browser firefox:<profile> to target the wrong profile.

Fix

Binary path resolution (ffmpeg.rs, ytdlp.rs, deno.rs)

  • Reorder get_system_binary_candidates() to iterate $PATH entries first, then append well-known fallback paths with deduplication
  • Reorder get_deno_path() and check_deno_internal(): which/where (PATH) before ~/.deno/bin/deno fallback

Dev build sidecar (build.rs, ytdlp.rs)

  • build.rs creates a minimal placeholder (#!/bin/sh\nexit 1\n) so tauri_build::build() passes externalBin validation without a real per-platform binary
  • get_bundled_ytdlp_path() rejects files under 1024 bytes as placeholders
  • get_ytdlp_path() falls through to system PATH as last resort in Auto mode

FFmpeg mux progress (progress.rs, download.rs, types.ts, contexts, queue components)

  • Add parse_ffmpeg_progress() matching ffmpeg stderr lines containing time=HH:MM:SS, speed=Nx, Lsize=
  • download.rs stderr task emits download-progress with status="muxing" when parse_progress() returns None and parse_ffmpeg_progress() matches
  • Add isMuxing field to DownloadItem — set in DownloadContext.tsx and UniversalContext.tsx without overriding isLive
  • QueueItem.tsx and UniversalQueueItem.tsx render an indeterminate shimmer bar with "Muxing" label, elapsed time, and speed when isMuxing && progress === 0

YouTube thumbnail fallback (UniversalQueueItem.tsx)

  • Add getYouTubeVideoId() at module level extracting video ID from YouTube URLs
  • thumbnailUrl falls back to img.youtube.com/vi/{id}/mqdefault.jpg when item.thumbnail is null or errored
  • useEffect resets thumbError on item.thumbnail or item.url change to prevent stale error state

Firefox profile sorting (dependencies.rs)

  • Add parse_firefox_profiles() parsing profiles.ini [Install*] section Default= to identify the active profile path
  • Sort profiles with active profile first, then alphabetical
  • Replaces inline Name= line scanning on all three platforms (macOS, Windows, Linux)

Fixes #42

Test plan

  • yt-dlp, ffmpeg, deno resolve from PATH in Nix devshell
  • Dev build compiles without real yt-dlp sidecar binary
  • Download video with --download-sections — muxing shimmer bar displays with elapsed time and speed
  • Paste YouTube URL — thumbnail fallback renders from img.youtube.com
  • Firefox cookie profile shows active profile first

binary path resolution:
- reorder get_system_binary_candidates() in ffmpeg.rs, ytdlp.rs to check $PATH before /opt/homebrew/bin, /usr/local/bin, /usr/bin
- reorder get_deno_path()/check_deno_internal() in deno.rs: which/where before ~/.deno/bin
- fixes binary resolution for Nix, Homebrew, and other PATH-based environments

dev build sidecar:
- build.rs creates yt-dlp placeholder (<1024 bytes) for tauri_build::build() externalBin validation
- get_bundled_ytdlp_path() rejects placeholders under 1024 bytes
- get_ytdlp_path() falls through to system PATH as last resort in Auto mode

ffmpeg mux progress:
- add parse_ffmpeg_progress() to progress.rs matching time=HH:MM:SS, speed=Nx, Lsize=
- download.rs stderr task emits status=muxing when parse_ffmpeg_progress() matches
- add isMuxing to DownloadItem, set in DownloadContext.tsx/UniversalContext.tsx
- QueueItem.tsx/UniversalQueueItem.tsx render shimmer bar with Muxing label and speed

youtube thumbnail fallback:
- add getYouTubeVideoId() in UniversalQueueItem.tsx
- fallback to img.youtube.com/vi/{id}/mqdefault.jpg when item.thumbnail is null
- useEffect resets thumbError on item.thumbnail/item.url change

firefox profile sorting:
- add parse_firefox_profiles() to dependencies.rs
- parse Install section Default= to identify active profile path
- sort active profile first, replaces inline Name= scanning on macOS/Windows/Linux
@vanloctech
Copy link
Owner

Hi @usrbinkat, please re-check code with format. See more in CI failing. You need setup pre-commit hook for check format before push code

@vanloctech
Copy link
Owner

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4ceb6eb43c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

</div>
) : item.isMuxing && item.progress === 0 ? (
<div className="flex items-center gap-1.5">
<span className="text-blue-300">Muxing</span>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Localize new muxing label through i18n keys

The new Muxing status text is hardcoded in the queue UI instead of going through translation keys, which violates the i18n rule in /workspace/youwee/AGENTS.md (When adding new UI text, add keys to ALL 3 locales). As a result, Vietnamese/Chinese users will see mixed-language UI during muxing and this label cannot be translated without another code pass.

Useful? React with 👍 / 👎.

Comment on lines +14 to +18
if !sidecar_path.exists() {
if let Some(parent) = sidecar_path.parent() {
let _ = std::fs::create_dir_all(parent);
}
let _ = std::fs::write(&sidecar_path, b"#!/bin/sh\nexit 1\n");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Restrict sidecar placeholder creation to non-release builds

This writes a fake yt-dlp binary whenever the target sidecar is missing, regardless of build profile. In release packaging outside the CI path that pre-downloads yt-dlp, the build now succeeds with a stub instead of failing fast, and runtime commands later have no real bundled yt-dlp available. Please gate this placeholder logic to explicit dev/check contexts so release builds still fail when the real sidecar is absent.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Giving error of FFmpeg not found, but it's been installed

2 participants