mirror of
https://github.com/arthur-pbty/arthur-os.git
synced 2026-08-01 20:28:16 +02:00
Add omarchy menu transcoding
This commit is contained in:
@@ -63,6 +63,7 @@ GROUP_DESCRIPTIONS[swayosd]="SwayOSD status display helpers"
|
|||||||
GROUP_DESCRIPTIONS[system]="Reboot, shutdown, logout, and lock"
|
GROUP_DESCRIPTIONS[system]="Reboot, shutdown, logout, and lock"
|
||||||
GROUP_DESCRIPTIONS[theme]="Theme management"
|
GROUP_DESCRIPTIONS[theme]="Theme management"
|
||||||
GROUP_DESCRIPTIONS[toggle]="Toggle Omarchy features"
|
GROUP_DESCRIPTIONS[toggle]="Toggle Omarchy features"
|
||||||
|
GROUP_DESCRIPTIONS[transcode]="Image and video transcoding"
|
||||||
GROUP_DESCRIPTIONS[tui]="Terminal UI launchers"
|
GROUP_DESCRIPTIONS[tui]="Terminal UI launchers"
|
||||||
GROUP_DESCRIPTIONS[tz]="Timezone selection"
|
GROUP_DESCRIPTIONS[tz]="Timezone selection"
|
||||||
GROUP_DESCRIPTIONS[update]="Omarchy and system updates"
|
GROUP_DESCRIPTIONS[update]="Omarchy and system updates"
|
||||||
|
|||||||
+11
-1
@@ -93,8 +93,9 @@ show_learn_menu() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
show_trigger_menu() {
|
show_trigger_menu() {
|
||||||
case $(menu "Trigger" " Capture\n Share\n Toggle\n Hardware") in
|
case $(menu "Trigger" " Capture\n Transcode\n Share\n Toggle\n Hardware") in
|
||||||
*Capture*) show_capture_menu ;;
|
*Capture*) show_capture_menu ;;
|
||||||
|
*Transcode*) show_transcode_menu ;;
|
||||||
*Share*) show_share_menu ;;
|
*Share*) show_share_menu ;;
|
||||||
*Toggle*) show_toggle_menu ;;
|
*Toggle*) show_toggle_menu ;;
|
||||||
*Hardware*) show_hardware_menu ;;
|
*Hardware*) show_hardware_menu ;;
|
||||||
@@ -166,6 +167,14 @@ show_share_menu() {
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
show_transcode_menu() {
|
||||||
|
case $(menu "Transcode" " Picture\n Video") in
|
||||||
|
*Picture*) present_terminal "omarchy-transcode --path '$HOME/Pictures'" ;;
|
||||||
|
*Video*) present_terminal "omarchy-transcode --path '$HOME/Videos'" ;;
|
||||||
|
*) back_to show_trigger_menu ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
show_toggle_menu() {
|
show_toggle_menu() {
|
||||||
local options=" Screensaver\n Nightlight\n Idle Lock\n Notifications\n Top Bar\n Workspace Layout\n Window Gaps\n 1-Window Ratio\n Monitor Scaling\n Direct Boot\n Passwordless Sudo"
|
local options=" Screensaver\n Nightlight\n Idle Lock\n Notifications\n Top Bar\n Workspace Layout\n Window Gaps\n 1-Window Ratio\n Monitor Scaling\n Direct Boot\n Passwordless Sudo"
|
||||||
|
|
||||||
@@ -672,6 +681,7 @@ go_to_menu() {
|
|||||||
*toggle*) show_toggle_menu ;;
|
*toggle*) show_toggle_menu ;;
|
||||||
*hardware*) show_hardware_menu ;;
|
*hardware*) show_hardware_menu ;;
|
||||||
*share*) show_share_menu ;;
|
*share*) show_share_menu ;;
|
||||||
|
*transcode*) show_transcode_menu ;;
|
||||||
*background*) show_background_menu ;;
|
*background*) show_background_menu ;;
|
||||||
*capture*) show_capture_menu ;;
|
*capture*) show_capture_menu ;;
|
||||||
*style*) show_style_menu ;;
|
*style*) show_style_menu ;;
|
||||||
|
|||||||
Executable
+231
@@ -0,0 +1,231 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# omarchy:group=transcode
|
||||||
|
# omarchy:name=
|
||||||
|
# omarchy:summary=Transcode pictures and videos for sharing
|
||||||
|
# omarchy:args=[--path path] [input] [format] [resolution]
|
||||||
|
# omarchy:examples=omarchy transcode|omarchy transcode --path ~/Downloads|omarchy transcode ~/Videos/demo.mov mp4 1080p|omarchy transcode ~/Pictures/wallpaper.heic jpg medium
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
Usage:
|
||||||
|
omarchy transcode [--path path] [input] [format] [resolution]
|
||||||
|
|
||||||
|
With no input, fuzzy-pick a picture or video from ~/Pictures and ~/Videos,
|
||||||
|
or only from --path when provided. Then pick the output format and resolution.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--path path Limit interactive fuzzy file selection to this path
|
||||||
|
|
||||||
|
Formats:
|
||||||
|
Pictures: jpg, png
|
||||||
|
Videos: mp4, gif
|
||||||
|
|
||||||
|
Resolutions:
|
||||||
|
Pictures: high, medium, low
|
||||||
|
Videos: 4k, 1080p, 720p
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
pick_file() {
|
||||||
|
local search_path="$1"
|
||||||
|
local paths=()
|
||||||
|
|
||||||
|
if [[ -n $search_path ]]; then
|
||||||
|
[[ -e $search_path ]] || { echo "Path not found: $search_path" >&2; return 1; }
|
||||||
|
paths=("$search_path")
|
||||||
|
else
|
||||||
|
paths=("$HOME/Pictures" "$HOME/Videos")
|
||||||
|
fi
|
||||||
|
|
||||||
|
find "${paths[@]}" -type f \
|
||||||
|
\( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.webp' -o -iname '*.gif' -o -iname '*.heic' -o -iname '*.avif' \
|
||||||
|
-o -iname '*.mp4' -o -iname '*.mov' -o -iname '*.m4v' -o -iname '*.mkv' -o -iname '*.webm' -o -iname '*.avi' \) \
|
||||||
|
2>/dev/null | fzf --prompt="Transcode file> "
|
||||||
|
}
|
||||||
|
|
||||||
|
pick_option() {
|
||||||
|
local prompt="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
gum choose --header "$prompt" "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
media_type() {
|
||||||
|
local mime
|
||||||
|
mime=$(file -b --mime-type "$1")
|
||||||
|
|
||||||
|
case "$mime" in
|
||||||
|
image/*) echo picture ;;
|
||||||
|
video/*) echo video ;;
|
||||||
|
*)
|
||||||
|
echo "Unsupported file type: $mime" >&2
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
output_path() {
|
||||||
|
local input="$1"
|
||||||
|
local format="$2"
|
||||||
|
local resolution="$3"
|
||||||
|
local dir base stem
|
||||||
|
|
||||||
|
dir=$(dirname -- "$input")
|
||||||
|
base=$(basename -- "$input")
|
||||||
|
stem="${base%.*}"
|
||||||
|
|
||||||
|
printf '%s/%s-%s.%s' "$dir" "$stem" "$resolution" "$format"
|
||||||
|
}
|
||||||
|
|
||||||
|
transcode_picture() {
|
||||||
|
local input="$1" format="$2" resolution="$3" output="$4"
|
||||||
|
local resize
|
||||||
|
|
||||||
|
case "$resolution" in
|
||||||
|
high) resize='3160x>' ;;
|
||||||
|
medium) resize='2160x>' ;;
|
||||||
|
low) resize='1080x>' ;;
|
||||||
|
*)
|
||||||
|
echo "Invalid picture resolution: $resolution" >&2
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$format" in
|
||||||
|
jpg)
|
||||||
|
magick "$input" -resize "$resize" -quality 85 -strip "$output"
|
||||||
|
;;
|
||||||
|
png)
|
||||||
|
magick "$input" -resize "$resize" -strip -define png:compression-filter=5 \
|
||||||
|
-define png:compression-level=9 \
|
||||||
|
-define png:compression-strategy=1 \
|
||||||
|
-define png:exclude-chunk=all \
|
||||||
|
"$output"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Invalid picture format: $format" >&2
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
transcode_video() {
|
||||||
|
local input="$1" format="$2" resolution="$3" output="$4"
|
||||||
|
local scale
|
||||||
|
|
||||||
|
case "$resolution" in
|
||||||
|
4k) scale='scale=-2:2160' ;;
|
||||||
|
1080p) scale='scale=-2:1080' ;;
|
||||||
|
720p) scale='scale=-2:720' ;;
|
||||||
|
*)
|
||||||
|
echo "Invalid video resolution: $resolution" >&2
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$format" in
|
||||||
|
mp4)
|
||||||
|
if [[ $resolution == "4k" ]]; then
|
||||||
|
ffmpeg -i "$input" -vf "$scale" -c:v libx265 -preset slow -crf 24 -c:a aac -b:a 192k "$output"
|
||||||
|
else
|
||||||
|
ffmpeg -i "$input" -vf "$scale" -c:v libx264 -preset fast -crf 23 -c:a copy "$output"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
gif)
|
||||||
|
ffmpeg -i "$input" -vf "fps=10,$scale:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" "$output"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Invalid video format: $format" >&2
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
copy_to_clipboard() {
|
||||||
|
local output="$1"
|
||||||
|
local uri
|
||||||
|
|
||||||
|
uri="file://$(realpath -- "$output")"
|
||||||
|
printf '%s\n' "$uri" | wl-copy --type text/uri-list
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local input="" format="" resolution="" search_path=""
|
||||||
|
local type output positional=()
|
||||||
|
|
||||||
|
while (( $# > 0 )); do
|
||||||
|
case "$1" in
|
||||||
|
--path)
|
||||||
|
shift
|
||||||
|
[[ $# -gt 0 ]] || { echo "Missing value for --path" >&2; return 2; }
|
||||||
|
search_path="$1"
|
||||||
|
;;
|
||||||
|
--help | -h)
|
||||||
|
usage
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
positional+=("$@")
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
--*)
|
||||||
|
echo "Unknown option: $1" >&2
|
||||||
|
usage >&2
|
||||||
|
return 2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
positional+=("$1")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
input="${positional[0]:-}"
|
||||||
|
format="${positional[1]:-}"
|
||||||
|
resolution="${positional[2]:-}"
|
||||||
|
|
||||||
|
if [[ -z $input ]]; then
|
||||||
|
input=$(pick_file "$search_path")
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ -n $input ]] || return 1
|
||||||
|
[[ -f $input ]] || { echo "File not found: $input" >&2; return 1; }
|
||||||
|
|
||||||
|
type=$(media_type "$input")
|
||||||
|
|
||||||
|
if [[ -z $format ]]; then
|
||||||
|
if [[ $type == "picture" ]]; then
|
||||||
|
format=$(pick_option "Select format..." jpg png)
|
||||||
|
else
|
||||||
|
format=$(pick_option "Select format..." mp4 gif)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z $resolution ]]; then
|
||||||
|
if [[ $type == "picture" ]]; then
|
||||||
|
resolution=$(pick_option "Select resolution..." high medium low)
|
||||||
|
else
|
||||||
|
resolution=$(pick_option "Select resolution..." 4k 1080p 720p)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
output=$(output_path "$input" "$format" "$resolution")
|
||||||
|
|
||||||
|
if [[ $type == "picture" ]]; then
|
||||||
|
transcode_picture "$input" "$format" "$resolution" "$output"
|
||||||
|
else
|
||||||
|
transcode_video "$input" "$format" "$resolution" "$output"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
copy_to_clipboard "$output"
|
||||||
|
echo "Your $type has been transcoded into $format as $resolution. It's on your clipboard."
|
||||||
|
echo ""
|
||||||
|
echo "It's also in $output"
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
@@ -1,58 +1,33 @@
|
|||||||
# Transcode a video to a good-balance 1080p that's great for sharing online
|
# Transcoding helpers have moved to omarchy-transcode.
|
||||||
|
|
||||||
transcode-video-1080p() {
|
transcode-video-1080p() {
|
||||||
ffmpeg -i "$1" -vf scale=1920:1080 -c:v libx264 -preset fast -crf 23 -c:a copy "${1%.*}-1080p.mp4"
|
omarchy-transcode "$1" mp4 1080p
|
||||||
}
|
}
|
||||||
|
|
||||||
# Transcode a video to a good-balance 4K that's great for sharing online
|
|
||||||
transcode-video-4K() {
|
transcode-video-4K() {
|
||||||
ffmpeg -i "$1" -c:v libx265 -preset slow -crf 24 -c:a aac -b:a 192k "${1%.*}-optimized.mp4"
|
omarchy-transcode "$1" mp4 4k
|
||||||
}
|
}
|
||||||
|
|
||||||
# Transcode a video to an animated GIF using a palette for accurate colors
|
|
||||||
transcode-video-gif() {
|
transcode-video-gif() {
|
||||||
ffmpeg -i "$1" -vf "fps=10,scale=800:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" "${1%.*}.gif"
|
omarchy-transcode "$1" gif 1080p
|
||||||
}
|
}
|
||||||
|
|
||||||
# Transcode any image to JPG image that's great for shrinking wallpapers
|
|
||||||
img2jpg() {
|
img2jpg() {
|
||||||
img="$1"
|
omarchy-transcode "$1" jpg high
|
||||||
shift
|
|
||||||
|
|
||||||
magick "$img" "$@" -quality 85 -strip "${img%.*}-converted.jpg"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Transcode any image to a small JPG (max 1080px wide)
|
|
||||||
img2jpg-small() {
|
img2jpg-small() {
|
||||||
img="$1"
|
omarchy-transcode "$1" jpg low
|
||||||
shift
|
|
||||||
|
|
||||||
magick "$img" "$@" -resize 1080x\> -quality 85 -strip "${img%.*}-small.jpg"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Transcode any image to a 4K JPG (max 2160px wide)
|
|
||||||
img2jpg-medium() {
|
img2jpg-medium() {
|
||||||
img="$1"
|
omarchy-transcode "$1" jpg medium
|
||||||
shift
|
|
||||||
|
|
||||||
magick "$img" "$@" -resize 2160x\> -quality 85 -strip "${img%.*}-medium.jpg"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Transcode any image to a 6K JPG (max 3160px wide)
|
|
||||||
img2jpg-large() {
|
img2jpg-large() {
|
||||||
img="$1"
|
omarchy-transcode "$1" jpg high
|
||||||
shift
|
|
||||||
|
|
||||||
magick "$img" "$@" -resize 3160x\> -quality 85 -strip "${img%.*}-large.jpg"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Transcode any image to compressed-but-lossless PNG
|
|
||||||
img2png() {
|
img2png() {
|
||||||
img="$1"
|
omarchy-transcode "$1" png high
|
||||||
shift
|
|
||||||
|
|
||||||
magick "$img" "$@" -strip -define png:compression-filter=5 \
|
|
||||||
-define png:compression-level=9 \
|
|
||||||
-define png:compression-strategy=1 \
|
|
||||||
-define png:exclude-chunk=all \
|
|
||||||
"${img%.*}-optimized.png"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ bindd = SUPER CTRL, PRINT, Extract text (OCR) from screenshot, exec, omarchy-cap
|
|||||||
# File sharing
|
# File sharing
|
||||||
bindd = SUPER CTRL, S, Share, exec, omarchy-menu share
|
bindd = SUPER CTRL, S, Share, exec, omarchy-menu share
|
||||||
|
|
||||||
|
# Transcoding
|
||||||
|
bindd = SUPER CTRL, R, Transcode, exec, omarchy-menu transcode
|
||||||
|
|
||||||
# Waybar-less information
|
# Waybar-less information
|
||||||
bindd = SUPER CTRL ALT, T, Show time, exec, notify-send -u low " $(date +"%A %H:%M · %d %B %Y · Week %V")"
|
bindd = SUPER CTRL ALT, T, Show time, exec, notify-send -u low " $(date +"%A %H:%M · %d %B %Y · Week %V")"
|
||||||
bindd = SUPER CTRL ALT, B, Show battery remaining, exec, notify-send -u low "$(omarchy-battery-status)"
|
bindd = SUPER CTRL ALT, B, Show battery remaining, exec, notify-send -u low "$(omarchy-battery-status)"
|
||||||
|
|||||||
Reference in New Issue
Block a user