MPVF is a Bash script that runs MPV with optional MPV profiles on a set of files found with GNU Find by including and excluding shell patterns and setting the depth levels in the directory tree. Search patterns and directories are entered on the command line or in the script. File names can also be matched against an optional list of file extensions. With no options entered, the script's defaults are used.
Usage
mpvf {[<mpv profile,...>] [-a <pattern>] [-e <pattern>] [-i <pattern>] [-n <levels>] [-x <levels>] [directory...] | --help | --version}
Options
<mpv profile,...>
Name of the MPV profile to use.
-a, --alt <pattern>
-e, --exc <pattern>
-i, --inc <pattern>
GNU Find -ipath option. Compares the entered shell pattern, to which an asterisk will be appended before and after, with the entire filename starting from the highest directory entered. With the script's -a option, a filename must contain at least one match of the entered patterns. With the -e option, a file match is excluded from the search results, while with the -i option it is included. Case distinctions are ignored. Due to the added special pattern character that matches any string including the null string, matching leading and trailing characters in file names is not always effective with the entered patterns.
-n, --min <levels>
-x, --max <levels>
GNU Find options -maxdepth and -mindepth. The search starts in directories a minimum number of levels away with the script's -n option and descends into directories a maximum number of levels away with the -x option.
--help
Print a summary of the command-line usage of MPVF and exit.
--version
Print the MPVF version number and exit.
Dependencies
GNU Bourne-Again SHell (Bash)
GNU Coreutils
GNU Findutils (find)
GNU Grep
mpv
Changes in the last revision:
- Added search with default patterns.
- Various code improvements.
Last active
October 19, 2024 01:29
-
-
Save o770/98b00f5c54e4e134310834e67838b1fa to your computer and use it in GitHub Desktop.
Run MPV with optional MPV profiles on a set of files found with GNU Find.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# MPVF - run MPV with optional MPV profiles on a set of files found with GNU Find | |
# Version 0.7 | |
# Values in parentheses that exist as a directory will be displayed and searched | |
# if no directory is entered on the command line. A pathname must be enclosed in | |
# quotes if it contains whitespace. | |
#default_directories+=(/home/user/Videos/Dir1 "/home/user/Videos/Dir 2") | |
# Values in parentheses will be displayed and used as search patterns in the -a | |
# option if none are entered on the command line. With whitespace, the pattern | |
# must be enclosed in quotes. | |
#default_patterns+=(Earth "Infinite Blue") | |
# Pipe-separated filename extensions. Uncomment to have the file search only match | |
# names ending with these extensions, ignoring case distinctions. | |
#file_extensions=".3g2|.3gp|.asf|.avi|.flv|.f4v|.gif|.m4v|.mkv|.mov|.mp4|.m4v|.mpg|.mpeg|.MTS|.M2TS|.TS|.ogv|.ogg|.rm|.rmvb|.vob|.webm|.wmv" | |
# SORT command line for file sorting. If not set, defaults are used. | |
#file_sorting=(sort -R) | |
scp="$(basename "$0")" | |
hver() { | |
cat << '_EOF_' | |
mpvf 0.7 | |
Unlicense <http://unlicense.org/> | |
This is free and unencumbered software released into the public domain and | |
provided without warranty of any kind. | |
_EOF_ | |
} | |
hman() { | |
cat << '_EOF_' | |
MPVF - run MPV with optional MPV profiles on a set of files found with GNU Find | |
SYNOPSIS | |
mpvf {[<mpv profile,...>] [-a <pattern>] [-e <pattern>] [-i <pattern>] | |
[-n <levels>] [-x <levels>] [directory...] | --help | --version} | |
DESCRIPTION | |
MPVF is a Bash script that runs MPV with optional MPV profiles on a set of files | |
found with GNU Find by including and excluding shell patterns and setting the | |
depth levels in the directory tree. Search patterns and directories are entered | |
on the command line or in the script. File names can also be matched against an | |
optional list of file extensions. With no options entered, the script's defaults | |
are used. | |
OPTIONS | |
<mpv profile,...> | |
Name of the MPV profile to use. | |
-a, --alt <pattern> | |
-e, --exc <pattern> | |
-i, --inc <pattern> | |
GNU Find -ipath option. Compares the entered shell pattern, to which an asterisk | |
will be appended before and after, with the entire filename starting from the | |
highest directory entered. With the script's -a option, a filename must contain | |
at least one match of the entered patterns. With the -e option, a file match is | |
excluded from the search results, while with the -i option it is included. Case | |
distinctions are ignored. Due to the added special pattern character that matches | |
any string including the null string, matching leading and trailing characters in | |
file names is not always effective with the entered patterns. | |
-n, --min <levels> | |
-x, --max <levels> | |
GNU Find options -maxdepth and -mindepth. The search starts in directories a | |
minimum number of levels away with the script's -n option and descends into | |
directories a maximum number of levels away with the -x option. | |
--help | |
Print a summary of the command-line usage of MPVF and exit. | |
--version | |
Print the MPVF version number and exit. | |
DEPENDENCIES | |
GNU Bourne-Again SHell (Bash) | |
GNU Coreutils | |
GNU Findutils (find) | |
GNU Grep | |
mpv | |
_EOF_ | |
} | |
swdep() { | |
type grep >/dev/null 2>&1 || { echo >&2 "${scp}: GREP not found - aborting." ; exit ; } | |
type mpv >/dev/null 2>&1 || { echo >&2 "${scp}: MPV not found - aborting." ; exit ; } | |
type find >/dev/null 2>&1 || { echo >&2 "${scp}: GNU Find not found - aborting." ; exit ; } | |
} | |
addressing() { | |
if [ -v ifile ] ; then | |
for i in "${ifile[@]}" ; do | |
if [ -d "$i" ] ; then | |
idir+=("$i") | |
fi | |
done | |
else | |
if [ -v default_directories ] ; then | |
for i in "${default_directories[@]}" ; do | |
if [ -d "$i" ] ; then | |
idir+=("$i") | |
fi | |
done | |
if [ -v idir ] ; then | |
echo "${scp}: Search directories: ${idir[*]@Q}" | |
fi | |
fi | |
fi | |
} | |
searching() { | |
if [ -v file_extensions ] ; then | |
if [ -v depth ] ; then | |
readarray -t isch < <(find "${idir[@]}" "${depth[@]}" "${apat[@]}" -type f | grep -iE '.*('"${file_extensions}"')$' | "${file_sorting[@]:-sort}") | |
else | |
readarray -t isch < <(find "${idir[@]}" "${apat[@]}" -type f | grep -iE '.*('"${file_extensions}"')$' | "${file_sorting[@]:-sort}") | |
fi | |
else | |
if [ -v depth ] ; then | |
readarray -t isch < <(find "${idir[@]}" "${depth[@]}" "${apat[@]}" -type f | "${file_sorting[@]:-sort}") | |
else | |
readarray -t isch < <(find "${idir[@]}" "${apat[@]}" -type f | "${file_sorting[@]:-sort}") | |
fi | |
fi | |
} | |
playing() { | |
if [ -n "${isch[0]}" ] ; then | |
echo "${scp}: Starting mpv..." | |
if [ -v prf ] ; then | |
mpv --profile="$prf" "${isch[@]}" | |
else | |
mpv "${isch[@]}" | |
fi | |
else | |
echo "${scp}: No files found matching pattern criteria - exiting..." | |
fi | |
} | |
swdep | |
iall+=("$@") | |
for arg in "${iall[@]}" ; do | |
iter=$((iter + 1)) | |
if [ "${itersk:-0}" -ne "$iter" ] ; then | |
if [ '--help' = "$arg" ] ; then | |
eop+=(help) | |
elif [ '--version' = "$arg" ] ; then | |
eop+=(version) | |
elif [ '-e' = "$arg" ] || [ '--exc' = "$arg" ] ; then | |
itersk=$((iter + 1)) | |
wpat+=('!' -ipath '*'"${iall[$iter]}"'*') | |
elif [ '-i' = "$arg" ] || [ '--inc' = "$arg" ] ; then | |
itersk=$((iter + 1)) | |
wpat+=(-ipath '*'"${iall[$iter]}"'*') | |
elif [ '-a' = "$arg" ] || [ '--alt' = "$arg" ] ; then | |
itersk=$((iter + 1)) | |
itera=$((itera + 1)) | |
if [ "$itera" -eq 1 ] ; then | |
opat+=(-ipath '*'"${iall[$iter]}"'*') | |
else | |
opat+=(-o -ipath '*'"${iall[$iter]}"'*') | |
fi | |
elif [ '--min' = "$arg" ] || [ '-n' = "$arg" ] ; then | |
itersk=$((iter + 1)) | |
if [ ! -v min ] ; then | |
if grep -qE '^(0|[1-9]\d*)$' <<< "${iall[$iter]}" ; then | |
depth+=(-mindepth "${iall[$iter]}") | |
min=yes | |
else | |
eop+=(min) | |
fi | |
else | |
iop+=(min) | |
iopmin="${iall[$iter]}" | |
fi | |
elif [ '--max' = "$arg" ] || [ '-x' = "$arg" ] ; then | |
itersk=$((iter + 1)) | |
if [ ! -v max ] ; then | |
if grep -qE '^(0|[1-9]\d*)$' <<< "${iall[$iter]}" ; then | |
depth+=(-maxdepth "${iall[$iter]}") | |
max=yes | |
else | |
eop+=(max) | |
fi | |
else | |
iop+=(max) | |
iopmax="${iall[$iter]}" | |
fi | |
elif [ -e "$arg" ] ; then | |
shift $((iter - 1)) | |
ifile+=("$@") | |
break | |
else | |
if [ ! -v prf ] ; then | |
prf="$arg" | |
else | |
iop+=(prf) | |
iopprf="$arg" | |
fi | |
fi | |
fi | |
done | |
unset iter | |
if [ ! -v eop ] ; then | |
if [ -v iop ] ; then | |
for i in "${iop[@]}" ; do | |
if [ 'max' = "$i" ] ; then | |
echo >&2 "${scp}: Maximum depth is already defined - ignoring: $iopmax" | |
elif [ 'min' = "$i" ] ; then | |
echo >&2 "${scp}: Minimum depth is already defined - ignoring: $iopmin" | |
elif [ 'prf' = "$i" ] ; then | |
echo >&2 "${scp}: MPV profile is already defined - ignoring: $iopprf" | |
fi | |
done | |
fi | |
if [ -v wpat ] || [ -v opat ] ; then | |
if [ ! -v opat ] ; then | |
apat+=(\( "${wpat[@]}" \)) | |
elif [ ! -v wpat ] ; then | |
apat+=(\( "${opat[@]}" \)) | |
else | |
apat+=(\( "${wpat[@]}" \) \( "${opat[@]}" \)) | |
fi | |
addressing | |
if [ -v idir ] ; then | |
echo "${scp}: Searching..." | |
searching | |
playing | |
else | |
echo "${scp}: No search directories - aborting." | |
fi | |
else | |
if [ -v default_patterns ] ; then | |
echo "${scp}: Search patterns: ${default_patterns[*]@Q}" | |
for i in "${default_patterns[@]}" ; do | |
iterdp=$((iterdp + 1)) | |
if [ "$iterdp" -ne 1 ] ; then | |
opat+=(-o -ipath '*'"$i"'*') | |
else | |
opat+=(-ipath '*'"$i"'*') | |
fi | |
done | |
unset iterdp | |
apat+=(\( "${opat[@]}" \)) | |
addressing | |
if [ -v idir ] ; then | |
echo "${scp}: Searching..." | |
searching | |
playing | |
else | |
echo "${scp}: No search directories - aborting." | |
fi | |
else | |
echo "${scp}: Usage: $scp {[<mpv profile,...>] [-a <pattern>] [-e <pattern>] [-i <pattern>] [-n <levels>] [-x <levels>] [directory...] | --help | --version}" | |
echo "${scp}: No search pattern - aborting." | |
fi | |
fi | |
else | |
for i in "${eop[@]}" ; do | |
if [ 'help' = "$i" ] ; then | |
hman | |
exit | |
elif [ 'version' = "$i" ] ; then | |
hver | |
exit | |
fi | |
done | |
if [ 'max' = "${eop[0]}" ] ; then | |
echo >&2 "${scp}: Non-fractional positive number expected in depth options - aborting." | |
elif [ 'min' = "${eop[0]}" ] ; then | |
echo >&2 "${scp}: Non-fractional positive number expected in depth options - aborting." | |
fi | |
fi | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment