Improve vifm filer
I wrote previewing script for image/video for better experience on vifm.
Finder
on MacOS is not so useful, but vifm
is faster & easy to use.
So I want to set it up as 2nd(1st?) image/video viewer too.
Add image/video previewing function to vifm
, with ffmpeg
& bash
script.
(More simple video previewing script is here.)
Newer version can be downloaded here
https://github.com/riodelphino/preview.vifm
Below codes are old and buggy.
Feature
- Image preview
- Video preview (jpg)
- Cache files with hash filename (for faster viewing)
- Async generation for all files in current dir
- Logging if needed
Ensured to work on
- MacOS
- kitty
- tmux on kitty
Code
~/.config/vifm/script/preview.sh
#!/bin/bash
# USAGE:
# ./preview.sh [filename] [ft_group] [process_type]
#
# ARGS:
# filename : target filename
# ft_group : image : Use imagemagick
# video : Use ffmpeg
# process_type : single : Generate preview for the single file
# all : Generate previews for all files in the dir
# --------------------------------------------------------------------------------
# Consts
# --------------------------------------------------------------------------------
# Cache dir
CACHE_DIR="$HOME/.cache/vifm/preview"
# Path for saving previous dir info
PREV_DIR_FILE="$HOME/.cache/vifm/preview/previous_dir"
# Log file path
LOG_FILE="$HOME/.cache/vifm/preview/log"
# Loggin or not
LOG_ENABLED=1 # 0: No logging | 1: Logging (cause timeloss)
# Images
IMAGE_PATTERNS="*.bmp *.jpg *.jpeg *.png *.gif *.xpm *.avif *.webp *.heic"
IMAGE_QUALITY=80
IMAGE_RESIZE="600x600" # the size of vifm window on full screen
# IMAGE_RESIZE="1376x1617" # Measured exact size for me, then remove '--scale-up' option from 'kitten icat'
# Videos
VIDEO_PATTERNS="*.avi *.mp4 *.wmv *.dat *.3gp *.ogv *.mkv *.mpg *.mpeg *.vob fl[icv] *.m2v *.mov *.webm *.ts *.mts *.m4v r[am] *.qt *.divx as[fx]"
VIDEO_FRAME=1000 # frame num for cut, from the movie's start
VIDEO_SCALE="640:360" # width:height
# VIDEO_SCALE="1376:774" # Measured exact size for me, then remove '--scale-up' option from 'kitten icat'
# --------------------------------------------------------------------------------
# Variables
# --------------------------------------------------------------------------------
prev_dir=""
cur_dir=""
# --------------------------------------------------------------------------------
# Functions
# --------------------------------------------------------------------------------
# Loging
function Log() {
label="$1"
value="$2"
length=12
if [[ $LOG_ENABLED == 1 ]]; then
printf "%-${length}s: %s\n" "$label" "$value" >>"$LOG_FILE"
fi
}
# Generate preview & return the hash path
function GeneratePreview() {
file="$1" # file path
ft_group="$2" # image | viode
# Get preview filename (hash)
hash=$(echo $(realpath "$file") | sha256sum | cut -d' ' -f1) # get hash
preview="$CACHE_DIR/$hash.jpg" # preview path
# Generate preview
if [ ! -f "$preview" ]; then
if [[ $ft_group == "image" ]]; then
# Image
magick "$file" -quality $IMAGE_QUALITY -resize $IMAGE_RESIZE "$preview" >/dev/null 2>&1
elif [[ $ft_group == "video" ]]; then
# Video
ffmpeg -y -i "$1" \
-vf "select='eq(n,$VIDEO_FRAME)',scale=$VIDEO_SCALE" \
-frames:v 1 \
"$preview" >/dev/null 2>&1
fi
fi
Log "preview" "$ft_group=$preview"
# echo $preview
printf "%s\n" "$preview"
}
# Record current directory
function RecordCurDir() {
echo $cur_dir >"$PREV_DIR_FILE"
}
# Generate image previews for all files in dir
function GenerateImagePreviewAll() {
# List files in the directory and loop through each pattern
for pat in $IMAGE_PATTERNS; do
Log "pat" "$pat"
# For each pattern, find matching files
for file in "$cur_dir"/$pat; do
# Only proceed if $file is a regular file
if [[ -f "$file" ]]; then
Log "file" "$file"
GeneratePreview "$file" image
fi
done
done
wait
}
# Generate video previews for all files in dir
function GenerateVideoPreviewAll() {
# List files in the directory and loop through each pattern
for pat in $VIDEO_PATTERNS; do
Log "pat" "$pat"
# For each pattern, find matching files
for file in "$cur_dir"/$pat; do
# Only proceed if $file is a regular file
if [[ -f "$file" ]]; then
Log "file" "$file"
GeneratePreview "$file" video
fi
done
done
wait
}
# --------------------------------------------------------------------------------
# Main script
# --------------------------------------------------------------------------------
# Get args
FILE_PATH="${1//\\ / }" # replace '\ ' to ' '
FT_GROUP="$2"
PROCESS_TYPE="$3"
PATTERNS="${4//,/ }" # replace ',' to ' ' for loop
# Get directories
cur_dir=$(dirname "$(realpath "$FILE_PATH")")
[ ! -f "$PREV_DIR_FILE" ] && prev_dir="" || prev_dir=$(cat "$PREV_DIR_FILE")
# Logging
Log "ft_group" "$FT_GROUP"
Log "process_type" "$PROCESS_TYPE"
Log "prev_dir" "$prev_dir"
Log "cur_dir" "$cur_dir"
Log "file" "$FILE_PATH"
# Create preview directory
mkdir -p "$CACHE_DIR"
if [[ $PROCESS_TYPE == "all" ]]; then
# GeneratePreviewAll()' (in background)
if [[ "$prev_dir" != "$cur_dir" ]]; then # Check if the directory has changed
Log "function" "GenerateImagePreviewAll()"
GenerateImagePreviewAll
Log "function" "GeneratePreviewAll()"
GenerateVideoPreviewAll
fi
Log "function" "RecordCurDir()"
RecordCurDir "$FILE_PATH"
elif [[ $PROCESS_TYPE == "single" ]]; then
# Generate preview for the single file
Log "function" "GeneratePreview()"
GeneratePreview "$FILE_PATH" $FT_GROUP
fi
Bash~/.config/vifmrc
" Image
fileviewer {*.bmp,*.jpg,*.jpeg,*.png,*.gif,*.xpm,*.avif,*.webp,*.heic},<image/*>
\ kitten icat --clear --transfer-mode=file --silent --scale-up --place=%pwx%ph@%pxx%py "$(~/.config/vifm/scripts/preview.sh '%c' image single)" >/dev/tty </dev/tty %N &
\ sh -c "$HOME/.config/vifm/scripts/preview.sh '%c' image all &"
\ %pc
\ kitten icat --clear --silent >/dev/tty </dev/tty %N &
" Video
fileviewer {*.avi,*.mp4,*.wmv,*.dat,*.3gp,*.ogv,*.mkv,*.mpg,*.mpeg,*.vob,*.fl[icv],*.m2v,*.mov,*.webm,*.ts,*.mts,*.m4v,*.r[am],*.qt,*.divx,*.as[fx]},
\ kitten icat --transfer-mode=file --silent --scale-up --place=%pwx%ph@%pxx%py "$(~/.config/vifm/scripts/preview.sh '%c' video single)" >/dev/tty </dev/tty %N &
\ sh -c "$HOME/.config/vifm/scripts/preview.sh '%c' video all &"
\ %pc
\ kitten icat --clear --silent >/dev/tty </dev/tty %N &
Plaintext%pc
is just a delimiter, between displaying command and cleaning command.
Note that kitten icat
and it’s options should be replaced to your own graphic protocol.
コメント