Compare commits

...

8 Commits

Author SHA1 Message Date
7d47044e5c update 2026-02-02 02:57:29 -08:00
baa897573e udpate 2026-02-02 02:56:45 -08:00
6ce0155364 remove immersion tracker 2026-02-02 01:38:25 -08:00
d32f79f406 update 2026-02-01 23:09:36 -08:00
f301f16949 update 2026-02-01 23:09:20 -08:00
cf14d30091 add mpv-yomitan config 2026-02-01 23:07:49 -08:00
b238daee8c add linux websocket 2026-02-01 20:36:14 -08:00
61c4425c6e remove linux websocket 2026-02-01 16:37:48 -08:00
19 changed files with 306 additions and 127 deletions

View File

@@ -16,7 +16,7 @@
"hooks": [ "hooks": [
{ {
"type": "command", "type": "command",
"command": "powershell.exe -WindowStyle Hidden -Command \"& { Add-Type -AssemblyName System.Windows.Forms; $balloon = New-Object System.Windows.Forms.NotifyIcon; $balloon.Icon = [System.Drawing.SystemIcons]::Information; $balloon.BalloonTipIcon = 'Info'; $balloon.BalloonTipTitle = 'Claude Code'; $balloon.BalloonTipText = 'Awaiting your input'; $balloon.Visible = $true; $balloon.ShowBalloonTip(5000); Start-Sleep -Seconds 5; $balloon.Dispose() }\"" "command": "notify-send 'Claude Code' 'Claude Code needs your attention'"
} }
] ]
} }
@@ -28,7 +28,7 @@
"clangd-lsp@claude-plugins-official": true "clangd-lsp@claude-plugins-official": true
}, },
"sandbox": { "sandbox": {
"enabled": true, "enabled": false,
"autoAllowBashIfSandboxed": true, "autoAllowBashIfSandboxed": true,
"network": { "network": {
"allowUnixSockets": [ "allowUnixSockets": [
@@ -39,5 +39,6 @@
"excludedCommands": [ "excludedCommands": [
"docker" "docker"
] ]
} },
"model": "haiku"
} }

View File

@@ -2,7 +2,7 @@
#* Name of a btop++/bpytop/bashtop formatted ".theme" file, "Default" and "TTY" for builtin themes. #* Name of a btop++/bpytop/bashtop formatted ".theme" file, "Default" and "TTY" for builtin themes.
#* Themes should be placed in "../share/btop/themes" relative to binary or "$HOME/.config/btop/themes" #* Themes should be placed in "../share/btop/themes" relative to binary or "$HOME/.config/btop/themes"
color_theme = "/home/kyasuda/.config/btop/themes/catppuccin_macchiato.theme" color_theme = "TTY"
#* If the theme set background should be shown, set to False if you want terminal background transparency. #* If the theme set background should be shown, set to False if you want terminal background transparency.
theme_background = true theme_background = true

View File

@@ -191,13 +191,15 @@ animations {
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more # See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
dwindle { dwindle {
pseudotile = true # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below pseudotile = false # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
preserve_split = true # You probably want this preserve_split = true
split_width_multiplier = 1.69
} }
# See https://wiki.hyprland.org/Configuring/Master-Layout/ for more # See https://wiki.hyprland.org/Configuring/Master-Layout/ for more
master { master {
new_status = master new_status = slave
allow_small_split = false
} }
# https://wiki.hyprland.org/Configuring/Variables/#misc # https://wiki.hyprland.org/Configuring/Variables/#misc

View File

@@ -92,7 +92,7 @@ bindl = , XF86AudioPrev, exec, mpc prev
# rofi # rofi
bind = $mainMod SHIFT, v, exec, uwsm app -sb -- rofi-rbw bind = $mainMod SHIFT, v, exec, uwsm app -sb -- rofi-rbw
bind = $mainMod, w, exec, rofi -show window -theme $HOME/.config/rofi/launchers/type-2/style-2.rasi -dpi 96 -theme-str 'window {width: 35%;}' # bind = $mainMod, w, exec, rofi -show window -theme $HOME/.config/rofi/launchers/type-2/style-2.rasi -dpi 96 -theme-str 'window {width: 35%;}'
bind = $mainMod SHIFT, w, exec, "$HOME/.config/rofi/scripts/rofi-wallpaper.sh" bind = $mainMod SHIFT, w, exec, "$HOME/.config/rofi/scripts/rofi-wallpaper.sh"
bind = $mainMod SHIFT, d, exec, "$HOME/.config/rofi/scripts/rofi-docs.sh" bind = $mainMod SHIFT, d, exec, "$HOME/.config/rofi/scripts/rofi-docs.sh"
bind = SUPER, j, exec, "$HOME/.config/rofi/scripts/rofi-jellyfin-dir.sh" bind = SUPER, j, exec, "$HOME/.config/rofi/scripts/rofi-jellyfin-dir.sh"
@@ -146,4 +146,10 @@ bind = SUPER, l, exec, hyprlock
# ANKI # ANKI
bind = $mainMod, a, exec, ~/.config/rofi/scripts/rofi-anki-script.sh bind = $mainMod, a, exec, ~/.config/rofi/scripts/rofi-anki-script.sh
bind = $mainMod SHIFT, a, exec, ~/projects/scripts/screenshot-anki.sh -cdMinecraft # bind = $mainMod SHIFT, a, exec, ~/projects/scripts/screenshot-anki.sh -cdMinecraft
# GSM
bindl = , mouse:275, exec, xdotool key alt+w # top mouse to texthooker
bindl = , mouse:276, exec, xdotool key alt+grave # bottom mouse to overlay
bind = ALT, g, exec, /opt/mpv-yomitan/mpv-yomitan.AppImage --toggle
# bind = ALT SHIFT, Y, exec, "$HOME/.config/rofi/scripts/rofi-mpv-yomitan.sh"

View File

@@ -0,0 +1,123 @@
{
"subtitlePosition": {
"yPercent": 15.376111685625649
},
"keybindings": [
{
"key": "Space",
"command": [
"cycle",
"pause"
]
},
{
"key": "ArrowRight",
"command": [
"seek",
5
]
},
{
"key": "ArrowLeft",
"command": [
"seek",
-5
]
},
{
"key": "Ctrl+Shift+KeyN",
"command": [
"script-binding",
"mpvacious-export-note"
]
},
{
"key": "Ctrl+KeyC",
"command": [
"script-binding",
"mpvacious-copy-primary-sub-to-clipboard"
]
},
{
"key": "Ctrl+Shift+KeyV",
"command": [
"script-binding",
"mpvacious-secondary-sid-toggle"
]
},
{
"key": "Shift+KeyL",
"command": [
"script-binding",
"mpvacious-sub-seek-forward"
]
},
{
"key": "Shift+KeyH",
"command": [
"script-binding",
"mpvacious-sub-seek-back"
]
},
{
"key": "Ctrl+Shift+KeyH",
"command": [
"script-binding",
"mpvacious-sub-replay"
]
},
{
"key": "Ctrl+Shift+KeyL",
"command": [
"script-binding",
"mpvacious-sub-play-up-to-next"
]
},
{
"key": "Ctrl+KeyV",
"command": [
"script-binding",
"animecards/update-anki-card"
]
},
{
"key": "KeyQ",
"command": [
"quit"
]
},
{
"key": "Ctrl+KeyW",
"command": [
"quit"
]
}
],
"texthooker": {
"openBrowser": false
},
"websocket": {
"enabled": "auto",
"port": 6677
},
"ankiConnect": {
"enabled": true,
"url": "http://127.0.0.1:8765",
"deck": "Minecraft",
"pollingRate": 200,
"audioField": "ExpressionAudio",
"imageField": "Picture",
"sentenceField": "Sentence",
"generateAudio": true,
"generateImage": true,
"imageType": "avif",
"imageFormat": "webp",
"miscInfoPattern": "[mpv-yomitan] %f (%t)",
"overwriteAudio": true,
"overwriteImage": true,
"highlightWord": true,
"showNotificationOnUpdate": true,
"audioPadding": 0.5,
"fallbackDuration": 3
}
}

View File

@@ -111,7 +111,7 @@ demuxer-max-back-bytes=200MiB # Keep recent data handy for quick reverse seeks
cache-secs=30 cache-secs=30
demuxer-readahead-secs=30 demuxer-readahead-secs=30
msg-level=subs2srs=warn msg-level=subs2srs,animecards,mpvacious=error
[anime] [anime]
profile-desc="Anime upscaling with ArtCNN" profile-desc="Anime upscaling with ArtCNN"
@@ -165,6 +165,7 @@ glsl-shaders="~~/shaders/ArtCNN_C4F32.glsl"
scale=ewa_lanczossharp scale=ewa_lanczossharp
dither=error-diffusion dither=error-diffusion
deband=yes # Crucial for anime gradients deband=yes # Crucial for anime gradients
input-ipc-server=/tmp/mpv-yomitan-socket
[anime-subs] [anime-subs]
profile-cond=p["slang"] == "ja" or p["slang"] == "ja.hi" profile-cond=p["slang"] == "ja" or p["slang"] == "ja.hi"

View File

@@ -129,6 +129,9 @@ cache-pause=no
cache-secs=30 cache-secs=30
demuxer-readahead-secs=30 demuxer-readahead-secs=30
msg-level=subs2srs,animecards,mpvacious=error
############ ############
# Profiles # # Profiles #
############ ############
@@ -195,6 +198,7 @@ glsl-shaders="~~/shaders/ArtCNN_C4F32.glsl"
scale=ewa_lanczossharp scale=ewa_lanczossharp
dither=error-diffusion dither=error-diffusion
deband=yes # Crucial for anime gradients deband=yes # Crucial for anime gradients
input-ipc-server=/tmp/mpv-yomitan-socket
# Anime subtitles profile # Anime subtitles profile
[anime-subs] [anime-subs]

Binary file not shown.

View File

@@ -8,6 +8,7 @@
# Anki Field Names # Anki Field Names
# These must match the field names in your Anki note type # These must match the field names in your Anki note type
# ================================================= # =================================================
DEBUG_MODE=no
FRONT_FIELD=Expression FRONT_FIELD=Expression
SENTENCE_FIELD=Sentence SENTENCE_FIELD=Sentence
IMAGE_FIELD=Picture IMAGE_FIELD=Picture
@@ -28,12 +29,12 @@ ASK_TO_OVERWRITE=yes
OVERWRITE_LIMIT=8 OVERWRITE_LIMIT=8
# Keep bold formatting added by yomitan? (yes/no) # Keep bold formatting added by yomitan? (yes/no)
HIGHLIGHT_WORD=no HIGHLIGHT_WORD=yes
# Use MPV's built-in clipboard API (requires v0.40+)? (yes/no) # Use MPV's built-in clipboard API (requires v0.40+)? (yes/no)
# Alternative clipboard method that may reduce latency on Windows. # Alternative clipboard method that may reduce latency on Windows.
# Supported on macOS and Wayland as well. Not supported on X11. # Supported on macOS and Wayland as well. Not supported on X11.
USE_MPV_CLIPBOARD_API=no USE_MPV_CLIPBOARD_API=yes
# ========================================================== # ==========================================================
# Audio Settings # Audio Settings

View File

@@ -30,6 +30,6 @@ menu_timeout=5
show_errors=yes show_errors=yes
ytdlp_file_format=mp4 ytdlp_file_format=mp4
ytdlp_output_template=%(uploader)s/%(title)s.%(ext)s ytdlp_output_template=%(uploader)s/%(title)s.%(ext)s
use_history_db=yes use_history_db=no
backend_host=http://localhost backend_host=http://localhost
backend_port=42069 backend_port=42069

View File

@@ -364,7 +364,7 @@ use_custom_trim=no
# and automatically update them with media if they match the configured note type # and automatically update them with media if they match the configured note type
# I.e., you create a note with GoldenDict, Rikaitan, etc., # I.e., you create a note with GoldenDict, Rikaitan, etc.,
# then mpvacious updates the note and adds audio and image automatically. # then mpvacious updates the note and adds audio and image automatically.
enable_new_note_timer=yes enable_new_note_timer=no
# Interval in seconds for checking for new notes. # Interval in seconds for checking for new notes.
# This setting controls how often mpvacious checks for new notes in Anki. # This setting controls how often mpvacious checks for new notes in Anki.

View File

@@ -1 +0,0 @@
../submodules/immersion-tracker

View File

@@ -1,6 +1,8 @@
-- mpv_websocket -- mpv_websocket
-- https://github.com/kuroahna/mpv_websocket -- https://github.com/kuroahna/mpv_websocket
local use_secondary_subs = false
local utils = require("mp.utils") local utils = require("mp.utils")
local platform = mp.get_property_native("platform") local platform = mp.get_property_native("platform")
@@ -8,76 +10,101 @@ local platform = mp.get_property_native("platform")
local config_file_path = mp.find_config_file("mpv.conf") local config_file_path = mp.find_config_file("mpv.conf")
local config_folder_path, config_file = utils.split_path(config_file_path) local config_folder_path, config_file = utils.split_path(config_file_path)
local mpv_websocket_path = local mpv_websocket_path =
utils.join_path(config_folder_path, platform == "windows" and "mpv_websocket.exe" or "mpv_websocket") utils.join_path(config_folder_path, platform == "windows" and "mpv_websocket.exe" or "mpv_websocket")
local initialised_websocket local initialised_websocket
local _, err = utils.file_info(config_file_path) local _, err = utils.file_info(config_file_path)
if err then if err then
error("failed to open mpv config file `" .. config_file_path .. "`") error("failed to open mpv config file `" .. config_file_path .. "`")
end end
local _, err = utils.file_info(mpv_websocket_path) local _, err = utils.file_info(mpv_websocket_path)
if err then if err then
error("failed to open mpv_websocket") error("failed to open mpv_websocket")
end end
local function find_mpv_socket(config_file_path) local function find_mpv_socket(config_file_path)
local file = io.open(config_file_path, "r") -- First, try to get from mpv properties (includes command-line options)
if file == nil then local mpv_socket = mp.get_property("input-ipc-server")
error("failed to read mpv config file `" .. config_file_path .. "`") if mpv_socket and mpv_socket ~= "" then
end return mpv_socket
end
local mpv_socket -- Fall back to reading config file
for line in file:lines() do local file = io.open(config_file_path, "r")
mpv_socket = line:match("^input%-ipc%-server%s*=%s*(%g+)%s*") if file == nil then
if mpv_socket then error("failed to read mpv config file `" .. config_file_path .. "`")
break end
end
end
file:close() for line in file:lines() do
mpv_socket = line:match("^input%-ipc%-server%s*=%s*(%g+)%s*")
if mpv_socket then
break
end
end
if not mpv_socket then file:close()
error("input-ipc-server option does not exist in `" .. config_file_path .. "`")
end
return mpv_socket if not mpv_socket then
error("input-ipc-server option does not exist in `" .. config_file_path .. "`")
end
return mpv_socket
end end
local mpv_socket = find_mpv_socket(config_file_path) local mpv_socket = find_mpv_socket(config_file_path)
if platform == "windows" then if platform == "windows" then
mpv_socket = "\\\\.\\pipe" .. mpv_socket:gsub("/", "\\") mpv_socket = "\\\\.\\pipe" .. mpv_socket:gsub("/", "\\")
end end
local function start_websocket() local function start_websocket()
initialised_websocket = mp.command_native_async({ local args = {
name = "subprocess", mpv_websocket_path,
playback_only = false, "-m",
capture_stdout = true, mpv_socket,
capture_stderr = true, "-w",
args = { "6677",
mpv_websocket_path, }
"-m",
mpv_socket, if use_secondary_subs then
"-w", table.insert(args, "-s")
"6677", end
},
}) initialised_websocket = mp.command_native_async({
name = "subprocess",
playback_only = false,
capture_stdout = true,
capture_stderr = true,
args = args,
})
end end
local function end_websocket() local function end_websocket()
mp.abort_async_command(initialised_websocket) mp.abort_async_command(initialised_websocket)
initialised_websocket = nil initialised_websocket = nil
end end
local function toggle_websocket() local function toggle_websocket()
local paused = mp.get_property_bool("pause") local paused = mp.get_property_bool("pause")
if initialised_websocket and paused then if initialised_websocket and paused then
end_websocket() end_websocket()
elseif not initialised_websocket and not paused then elseif not initialised_websocket and not paused then
start_websocket() start_websocket()
end end
end
local function toggle_subs_type()
if use_secondary_subs then
use_secondary_subs = false
else
use_secondary_subs = true
end
if initialised_websocket then
end_websocket()
start_websocket()
end
end end
mp.register_script_message("togglewebsocket", toggle_websocket) mp.register_script_message("togglewebsocket", toggle_websocket)
mp.register_script_message("togglesubstype", toggle_subs_type)
start_websocket() start_websocket()

View File

@@ -157,7 +157,6 @@ set -gq @catppuccin_window_flags_icon_format "##{?window_activity_flag,#{E:@catp
set -gq allow-passthrough on set -gq allow-passthrough on
set -g visual-activity off set -g visual-activity off
set -g @catppuccin_window_status_style "rounded" # basic, rounded, slanted, custom, or none set -g @catppuccin_window_status_style "rounded" # basic, rounded, slanted, custom, or none
run ~/.config/tmux/plugins/catppuccin/tmux/catppuccin.tmux run ~/.config/tmux/plugins/catppuccin/tmux/catppuccin.tmux

45
.gitconfig Normal file
View File

@@ -0,0 +1,45 @@
[includeIf "gitdir:~/.local/share/yadm/repo.git"]
path = .gitconfig.submodules
[gpg]
format = ssh
[user]
signingkey = /home/sudacode/.ssh/yuh.pub
name = sudacode
email = suda@sudacode.com
[commit]
gpgsign = true
[init]
defaultBranch = main
[push]
default = simple
autoSetupRemote = true
[diff]
algorithm = histogram
[merge]
conflictstyle = zdiff3
[pull]
rebase = true
[rebase]
autostash = true
autosquash = true
[fetch]
prune = true
[branch]
autosetuprebase = always
[core]
fsmonitor = true
untrackedCache = true
editor = nvim
pager = delta
[alias]
st = status
co = checkout
br = branch
lg = log --oneline --graph --decorate --all
fixup = commit --fixup
undo = reset --soft HEAD~1
[interactive]
diffFilter = delta --color-only
[delta]
navigate = true # use n and N to move between diff sections
dark = true # or light = true, or omit for auto-detection

3
.gitmodules vendored
View File

@@ -19,9 +19,6 @@
[submodule ".config/mpv-modules/autosubsync-mpv"] [submodule ".config/mpv-modules/autosubsync-mpv"]
path = .config/mpv-modules/autosubsync-mpv path = .config/mpv-modules/autosubsync-mpv
url = git@github.com:joaquintorres/autosubsync-mpv.git url = git@github.com:joaquintorres/autosubsync-mpv.git
[submodule ".config/mpv-modules/immersion-tracker"]
path = .config/mpv-modules/immersion-tracker
url = git@gitea.suda.codes:sudacode/immersion-tracker.git
[submodule ".config/mpv-modules/mpvacious"] [submodule ".config/mpv-modules/mpvacious"]
path = .config/mpv-modules/mpvacious path = .config/mpv-modules/mpvacious
url = git@github.com:ksyasuda/mpvacious.git url = git@github.com:ksyasuda/mpvacious.git

View File

@@ -1,9 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
THEME="${THEME:-$HOME/.config/rofi/launchers/type-2/style-2.rasi}" THEME="${THEME:-/opt/mpv-yomitan/catppuccin-macchiato.rasi}"
THUMBNAIL_PATH="/tmp/rmpv-thumbnail.jpg"
FONTCONFIG_FILE=$HOME/.config/mpv/mpv-fonts.conf FONTCONFIG_FILE=$HOME/.config/mpv/mpv-fonts.conf
COMMAND=mpv COMMAND=mpv
VIDEO_EXTENSIONS="mkv|mp4|avi|webm|mov|flv|wmv|m4v|ts|m2ts"
# Parse command-line options first # Parse command-line options first
while getopts ":it:" opt; do while getopts ":it:" opt; do
@@ -26,81 +26,56 @@ while getopts ":it:" opt; do
done done
shift $((OPTIND - 1)) shift $((OPTIND - 1))
generate_thumbnail() { find_videos() {
local video_file="$1" find "$PWD" -maxdepth 1 -type f -regextype posix-extended \
local temp_thumb="/tmp/rmpv-thumbnail-$$.jpg" -iregex ".*\.($VIDEO_EXTENSIONS)$" 2>/dev/null | sort -V
local thumbnail_file="${video_file%.*}.jpg" }
# Clean up previous thumbnail build_rofi_menu() {
rm -f "$THUMBNAIL_PATH" while IFS= read -r video; do
[ -z "$video" ] && continue
local display_name
display_name=$(basename "$video")
printf '%s\0icon\x1fthumbnail://%s\n' "$display_name" "$video"
done < <(find_videos)
}
# Validate input get_video_thumbnail() {
if [[ -z "$video_file" ]]; then local video="$1"
echo "Error: No video file specified" >&2 local thumb_dir="$HOME/.cache/thumbnails/large"
return 1 local video_uri="file://$(realpath "$video")"
local thumb_hash=$(echo -n "$video_uri" | md5sum | cut -d' ' -f1)
local thumb_path="$thumb_dir/$thumb_hash.png"
if [[ -f "$thumb_path" ]]; then
echo "$thumb_path"
return 0
fi fi
if [[ ! -f "$video_file" ]]; then local tmp_thumb="/tmp/rmpv-thumb-$$.jpg"
echo "Error: Video file '$video_file' not found" >&2 if command -v ffmpegthumbnailer &>/dev/null; then
return 1 ffmpegthumbnailer -i "$video" -o "$tmp_thumb" -s 512 -q 5 2>/dev/null && echo "$tmp_thumb"
fi elif command -v ffmpeg &>/dev/null; then
ffmpeg -i "$video" -ss 00:00:30 -vframes 1 -vf "scale=512:-1" "$tmp_thumb" 2>/dev/null && echo "$tmp_thumb"
# Check if it's a video file
if ! file "$video_file" | grep -qE "(video|Video)"; then
echo "Error: '$video_file' doesn't appear to be a video file" >&2
return 1
fi
# Generate thumbnail if it doesn't exist
if [[ ! -f "$thumbnail_file" ]]; then
echo "Generating thumbnail for $(basename "$video_file")..."
# Try generating thumbnail side-by-side
if ! ffmpeg -ss 00:00:01 -i "$video_file" \
-vf "scale=320:240:force_original_aspect_ratio=decrease,pad=320:240:(ow-iw)/2:(oh-ih)/2" \
-frames:v 1 \
-q:v 4 \
"$thumbnail_file" \
-loglevel error -y 2>/dev/null; then
# Fallback to temp file if side-by-side fails (e.g. read-only fs)
echo "Warning: Failed to write to $thumbnail_file, trying temp location" >&2
thumbnail_file="$temp_thumb"
if ! ffmpeg -ss 00:00:01 -i "$video_file" \
-vf "scale=320:240:force_original_aspect_ratio=decrease,pad=320:240:(ow-iw)/2:(oh-ih)/2" \
-frames:v 1 \
-q:v 4 \
"$thumbnail_file" \
-loglevel error -y 2>/dev/null; then
echo "Error: Failed to generate thumbnail" >&2
return 1
fi
fi
fi
# Copy to consistent location for notify-send
# We use a fixed path so notify-send always finds it
if cp "$thumbnail_file" "$THUMBNAIL_PATH" 2>/dev/null; then
echo "Thumbnail ready at: $THUMBNAIL_PATH"
ls -l "$THUMBNAIL_PATH"
file "$THUMBNAIL_PATH"
else
echo "Error: Failed to copy thumbnail to $THUMBNAIL_PATH" >&2
fi fi
} }
choice="$(find . -iname "*[.mkv|.mp4]" | sort -h | rofi -dmenu -i -theme "$THEME" -theme-str 'listview {columns: 1; lines: 15;} window {width: 88%;}' -p "Choose Video")" selection=$(build_rofi_menu | rofi -dmenu -i -show-icons -theme "$THEME" \
if [[ -z "$choice" ]]; then -theme-str 'listview {columns: 1; lines: 15;} window {width: 88%;}' -p "Choose Video ")
if [[ -z "$selection" ]]; then
echo "No video selected." echo "No video selected."
exit 1 exit 1
fi fi
generate_thumbnail "$choice" choice="./$selection"
if [[ ! -f "$THUMBNAIL_PATH" ]]; then
echo "Warning: Thumbnail not created, notification will have no icon" >&2 THUMBNAIL_PATH=$(get_video_thumbnail "$choice")
if [[ -n "$THUMBNAIL_PATH" && -f "$THUMBNAIL_PATH" ]]; then
notify-send -i "$THUMBNAIL_PATH" "Playing Video" "$(basename "$choice")"
else
notify-send "Playing Video" "$(basename "$choice")"
fi fi
notify-send -i "$THUMBNAIL_PATH" "Playing Video" "$(basename "$choice")"
$COMMAND "$choice" & $COMMAND "$choice" &
# vim: ft=sh # vim: ft=sh