/ de-omarchy / bin / omarchy-chromium-ytdlp-host
swadhinbiswas Initial de-omarchy: Omarchy UI layer for Arch-based distros · 8/22/2026
9f393b2
143 lines · 4.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/bin/bash

# omarchy:summary=Native messaging host: download the URL sent by the yt-dlp Chromium extension
# omarchy:hidden=true

set -euo pipefail

SCRIPT_PATH="${BASH_SOURCE[0]}"

# The browser launches us without Omarchy's environment, so locate the repo from
# our own path when OMARCHY_PATH isn't already set. Export it — omarchy-shell (used
# by omarchy-osd) needs it to find the running shell, and silently no-ops without it.
export OMARCHY_PATH="${OMARCHY_PATH:-$(cd -- "$(dirname -- "$SCRIPT_PATH")/.." && pwd)}"

# Make sure the Omarchy bin and yt-dlp are reachable when launched by the browser.
export PATH="$OMARCHY_PATH/bin:/usr/local/bin:/usr/bin:$PATH"

DOWNLOAD_DIR="${OMARCHY_YTDLP_DIR:-$HOME/Videos}"

parse_url() {
  jq -r '.url // empty' 2>/dev/null <<<"$1" || true
}

valid_url() {
  [[ $1 =~ ^https?:// ]]
}

# Drive the Quickshell OSD — a single overlay that updates in place (like the
# volume/brightness bar), so download progress never stacks like notifications.
osd_progress() {
  omarchy-osd -i 󰇚 -p "$1" -d 8000 >/dev/null 2>&1 || true
}

osd_close() {
  omarchy-shell -q osd close >/dev/null 2>&1 || true
}

download_url() {
  local url="$1"

  mkdir -p "$DOWNLOAD_DIR"

  # Don't show anything until yt-dlp confirms there's actually a video to grab.
  if ! yt-dlp --no-playlist --simulate --quiet --no-warnings "$url" >/dev/null 2>&1; then
    omarchy-notification-send -u critical -g 󰅖 "No video found for download" "$url"
    exit 0
  fi

  osd_progress 0

  # Stream the download: OMARCHY_PROG carries the percent (drives the OSD),
  # OMARCHY_FILE (printed only after a successful move) carries title + path.
  local line rest pct intpct last="" er nowms lastms=0 title="" filepath=""
  while IFS= read -r line; do
    case $line in
    OMARCHY_PROG*)
      pct=${line#OMARCHY_PROG$'\t'}
      intpct=${pct%%.*}
      intpct=${intpct//[^0-9]/}
      [[ -n $intpct && $intpct != "$last" ]] || continue # skip no-op repeats
      # Throttle to ~4 redraws/sec so fast downloads don't spawn a flurry of processes.
      er=$EPOCHREALTIME
      nowms=$((${er%[.,]*} * 1000 + 10#${er##*[.,]} / 1000))
      ((nowms - lastms >= 250)) || continue
      last=$intpct
      lastms=$nowms
      osd_progress "$intpct"
      ;;
    OMARCHY_FILE*)
      rest=${line#OMARCHY_FILE$'\t'}
      title=${rest%%$'\t'*}
      filepath=${rest#*$'\t'}
      ;;
    esac
  done < <(PYTHONUNBUFFERED=1 yt-dlp --no-playlist --restrict-filenames --no-simulate \
    --quiet --no-warnings --progress --newline \
    --progress-template $'download:OMARCHY_PROG\t%(progress._percent_str)s' \
    --paths "$DOWNLOAD_DIR" -o '%(title)s [%(id)s].%(ext)s' \
    --print $'after_move:OMARCHY_FILE\t%(title)s\t%(filepath)s' \
    "$url" 2>&1)

  osd_close

  # after_move only prints on a successful download+move, so a captured path == success.
  if [[ -n $filepath ]]; then
    ((${#title} > 50)) && title="${title:0:50}…" # keep the toast compact

    # Square, center-cropped thumbnail so the notification preview isn't stretched.
    local preview
    preview="$(mktemp --suffix=.jpg)"
    ffmpeg -y -i "$filepath" -ss 00:00:00.1 -vframes 1 \
      -vf "crop='min(iw,ih)':'min(iw,ih)',scale=256:256" -q:v 2 \
      "$preview" -loglevel quiet 2>/dev/null || true

    # Best-effort: the download already succeeded, and under `set -e` a failed
    # toast would exit before the thumbnail cleanup below is ever scheduled.
    omarchy-notification-send -g 󰄬 "Download complete" "$title" \
      -t 10000 --image "${preview:-$filepath}" \
      --exec "$(printf 'mpv %q' "$filepath")" || true

    # The shell loads the thumbnail into memory when the toast appears and never
    # re-reads the file, so the preview only has to outlive that load, not the
    # toast.
    (
      sleep 2
      rm -f "$preview"
    ) &
  else
    omarchy-notification-send -u critical -g 󰅖 "Download failed" "$url"
  fi

  exit 0
}

main() {
  local length payload url

  # Detached worker: this is what actually runs yt-dlp and fires notifications.
  if [[ ${1:-} == "--download" ]]; then
    download_url "$2"
  fi

  # Native messaging frame: 4-byte little-endian length prefix, then UTF-8 JSON.
  length=$(head -c4 | od -An -v -tu4 --endian=little | tr -d ' ')
  [[ -n ${length:-} ]] && ((length > 0)) || exit 0

  payload=$(head -c "$length")

  # Ack with an empty message so the extension's sendNativeMessage callback resolves cleanly.
  printf '\x02\x00\x00\x00{}'

  url=$(parse_url "$payload")
  [[ -n $url ]] || exit 0
  valid_url "$url" || exit 0

  # Detach the download so this host exits promptly and frees the browser's port.
  setsid -f "$SCRIPT_PATH" --download "$url" </dev/null >/dev/null 2>&1
}

if [[ ${BASH_SOURCE[0]} == "$0" ]]; then
  main "$@"
fi