strm/strm

247 lines
6.9 KiB
Bash
Executable file

#!/usr/bin/env bash
# Text formatting variables
text_reset="\e[0m"
text_bold="\e[1m"
function print_usage {
echo "Usage: strm [OPTIONS] QUERIES ... [OPTIONS]"
echo
echo "Stream media files over SSH in a convenient way."
echo
echo "OPTIONS"
echo " -h, --help Show this help message"
echo " -c, --config CONFIG_FILE Path to config file (default: ~/.config/strm/strm.config)"
echo " -f, --fullscreen Play video files in fullscreen"
echo " -l, --list List files instead of playing"
echo " -m, --media-directories MEDIA_DIRECTORIES Use given media directories, config is ignored"
echo " -o, --or Use a logical OR for queries (default: AND)"
echo " -r, --remote SSH_CONNECTION_STRING Execute strm with other given arguments on remote machine (-f is set by default)"
echo " -s, --shuffle Play files in random order"
echo
echo "EXAMPLES"
echo " strm -l . # List all available files"
echo " strm Elephants Dream # Play files whose path contain 'elephants' and 'dream'"
echo " strm e*phants # Play files whose path matches the glob pattern 'e*phants'"
exit
}
function print_controls {
echo -ne "\n[${text_bold}p${text_reset}] Play/Pause, [${text_bold}<${text_reset}/${text_bold}>${text_reset}] Previous/Next, [${text_bold}q${text_reset}] Quit, [${text_bold}Q${text_reset}] Save position and quit\n"
}
function error {
echo -ne "${text_bold}ERROR${text_reset} $1\n" >&2
exit 1
}
# Check if mpv is installed
if ! command -v mpv &>/dev/null
then
error "mpv was not found, please install it"
fi
# Set default values
config="$HOME/.config/strm/strm.config"
fullscreen=false
list=false
media_directories=""
or=false
queries=()
remote=""
remote_arguments=()
shuffle=false
# Parse arguments
while (( "$#" )); do
case "$1" in
-c|--config)
if [ -n "$2" ] && [ "${2:0:1}" != "-" ]; then
config="$2"
remote_arguments+=("$1" "$2")
shift 2
else
error "Argument for $1 is missing"
fi
;;
-f|--fullscreen)
fullscreen=true
shift
;;
-h|--help)
print_usage
;;
-l|--list)
list=true
remote_arguments+=("$1")
shift
;;
-m|--media-directories)
if [ -n "$2" ] && [ "${2:0:1}" != "-" ]; then
media_directories="$2"
remote_arguments+=("$1" "$2")
shift 2
else
error "Argument for $1 is missing"
fi
;;
-o|--or)
or=true
remote_arguments+=("$1")
shift
;;
-r|--remote)
if [ -n "$2" ] && [ "${2:0:1}" != "-" ]; then
remote="$2"
shift 2
else
error "Argument for $1 is missing"
fi
;;
-s|--shuffle)
shuffle=true
remote_arguments+=("$1")
shift
;;
-*|--*=)
error "Unsupported flag $1"
;;
*)
queries+=("$1")
remote_arguments+=("$1")
shift
;;
esac
done
# Print usage if no queries were given
if [ "${#queries[@]}" == 0 ]; then
print_usage
fi
# Execute strm on remote if argument set
if [ "$remote" != "" ]; then
# Invert fullscreen argument
if [ "$fullscreen" == false ]; then
remote_arguments+=("-f")
fi
# Execute strm on remote machine
ssh -t "$remote" "DISPLAY=:0 strm ${remote_arguments[@]}; echo"
exit
fi
# If no media directory was set load config file
if [ "$media_directories" == "" ]; then
# Read config file
if test -f "$config"; then
. "$config"
else
error "Config file not found ($config)"
fi
# Throws error if still no media directory set
if [ "$media_directories" == "" ]; then
error "No media directory specified"
fi
fi
# Read media directories
IFS="," read -a media_directories <<< "$media_directories"
# Construct find argument array
# Ignore hidden files and directories and list only files and symlinks
find_arguments=("-not" "-path" "'*/\.*'" "-type" "f,l")
for i in "${!queries[@]}"; do
# If -o flag is set and more than one query is given, add a logical OR
if [ "$or" == true ] && [ "$i" -ge 1 ]; then
find_arguments+=("-o" "-not" "-path" "'*/\.*'" "-type" "f,l")
fi
# Use the ipath argument to search case-insensitive and surround query with wildcards
find_arguments+=("-ipath" "'*${queries[$i]}*'")
done
# Initialize result arrays
sftp_results=()
print_results=()
# Get results from every media directory
for media_directory in "${media_directories[@]}"; do
tmp_sftp_results=()
tmp_print_results=()
# Get connection string and remote directory
IFS="/" read -r connection_string directory <<< "$media_directory"
# Check validity of variables
if [ "$connection_string" == "" ] || [ "$directory" == "" ]; then
error "Not a valid media directory: $media_directory"
fi
echo -ne "Fetching results from $text_bold$(basename $directory)$text_reset on $text_bold$connection_string$text_reset\n"
# Add leading and trailing slash to directory if missing
[[ "$directory" != /*/ ]] && directory="/$directory/"
# Get search results from remote
# Look for paths matching given queries in visible directories, listing only filenames and links
mapfile -t tmp_results < <(ssh -o ConnectTimeout=10 "$connection_string" find "'$directory'" "${find_arguments[@]}" | sort)
# Build SFTP strings and printable strings
for i in "${!tmp_results[@]}"; do
tmp_sftp_results["$i"]="sftp://$connection_string${tmp_results[$i]}"
tmp_print_result="$text_bold$connection_string$text_reset ${tmp_results[$i]}"
tmp_print_results["$i"]="${tmp_print_result/$directory/}"
done
sftp_results=("${sftp_results[@]}" "${tmp_sftp_results[@]}")
print_results=("${print_results[@]}" "${tmp_print_results[@]}")
done
echo
# Exit if no results found
if [ "${#sftp_results[@]}" == 0 ]; then
echo "No files found"
exit
fi
# Print result header
if [ "$list" == true ]; then
echo "Found the following files:"
else
if [ "$shuffle" == true ]; then
echo "Playing the following files in random order:"
else
echo "Playing the following files:"
fi
fi
echo
# Print results
for result in "${print_results[@]}"; do
echo -ne "$result\n"
done
# Play results if --list flag not set
if [ "$list" == false ]; then
print_controls
# Construct addtitional mpv arguments
mpv_arguments=()
if [ "$shuffle" == true ]; then
mpv_arguments+=("--shuffle")
fi
if [ "$fullscreen" == true ]; then
mpv_arguments+=("--fullscreen")
fi
# Play all remote files
mpv --msg-level=all=error,statusline=status --term-status-msg='${playlist-pos-1}/${playlist-count} - ${time-pos}/${duration} - \e[1m${metadata/artist:}${?metadata/artist: - }${metadata/title:}${!metadata/title:${filename/no-ext}}\e[0m' "${mpv_arguments[@]}" "${sftp_results[@]}"
fi