Merge branch 'master' of git.opaque.tech:denis/strm

This commit is contained in:
Denis Lehmann 2021-04-28 11:18:49 +02:00
commit 50e3a147df
2 changed files with 36 additions and 25 deletions

View file

@ -3,7 +3,7 @@
*strm* is a small Bash script that lets you stream media files over SSH. *strm* is a small Bash script that lets you stream media files over SSH.
No need for mounting and navigating through complex directory structures anymore. No need for mounting and navigating through complex directory structures anymore.
Just provide a query and the media files are played locally via [[https://mpv.io/][mpv]]. Just provide a query and the matching media files are played locally via [[https://mpv.io/][mpv]].
Here is an example.. let's assume you have the shortfilm [[https://www.dailydweebs.com/][The Daily Dweebs]] stored on a remote machine in the following directory structure: Here is an example.. let's assume you have the shortfilm [[https://www.dailydweebs.com/][The Daily Dweebs]] stored on a remote machine in the following directory structure:
@ -23,8 +23,11 @@
#+end_src #+end_src
Every argument which is not assigned to a flag is interpreted as part of the query. Every argument which is not assigned to a flag is interpreted as part of the query.
The query arguments are then surrounded by wildcards (=*=) and the case gets ignored. The query arguments are interpreted as [[https://en.wikipedia.org/wiki/Glob_(programming)][glob patterns]], additionally surrounded by wildcards (=*=).
If every argument matches any filepath in the configured media directories, the matched filepaths are interpreted as result. If every pattern matches any filepath in the configured media directories, the matched filepaths are interpreted as result.
The =--or= flag can be set to get results which match at least one pattern.
Matchings are always done case-insensitive.
The shortfilm from the example above could have also been played with one of the following commands: The shortfilm from the example above could have also been played with one of the following commands:
#+begin_src sh #+begin_src sh
@ -70,21 +73,22 @@
** Usage ** Usage
#+begin_src text #+begin_src text
Usage: strm [OPTIONS] QUERY ... [OPTIONS] Usage: strm [OPTIONS] QUERIES ... [OPTIONS]
Stream media files over SSH. Stream media files over SSH.
OPTIONS OPTIONS
-h, --help Show this help message -h, --help Show this help message
-c, --config CONFIG_FILE Path to config file -c, --config CONFIG_FILE Path to config file (default: ~/.config/strm/strm.config)
-l, --list List files instead of playing -l, --list List files instead of playing
-m, --media-directories MEDIA_DIRECTORIES Use given media directories, config is ignored -m, --media-directories MEDIA_DIRECTORIES Use given media directories, config is ignored
-o, --or Use a logical OR for queries (default: AND)
-s, --shuffle Play files in random order -s, --shuffle Play files in random order
EXAMPLES EXAMPLES
strm -l . # List all available files strm -l . # List all available files
strm Elephants Dream # Play files whose path contain 'elephants' and 'dream' strm Elephants Dream # Play files whose path contain 'elephants' and 'dream'
strm e*phants # Play files whose path matches the wildcard 'e*phants' strm e*phants # Play files whose path matches the glob pattern 'e*phants'
#+end_src #+end_src
The usual [[https://mpv.io/manual/master/#interactive-control][mpv controls]] are available while playback. The usual [[https://mpv.io/manual/master/#interactive-control][mpv controls]] are available while playback.
@ -94,6 +98,7 @@
- =p= and =SPACE= :: Pause (pressing again unpauses). - =p= and =SPACE= :: Pause (pressing again unpauses).
- =<= and =>= :: Go backward/forward in the playlist. - =<= and =>= :: Go backward/forward in the playlist.
- =q= :: Stop playing and quit. - =q= :: Stop playing and quit.
- =Q= :: Like =q=, but store the current playback position. Playing the same file later will resume at the old playback position if possible.
** Configuration ** Configuration

44
strm
View file

@ -5,21 +5,22 @@ text_reset="\e[0m"
text_bold="\e[1m" text_bold="\e[1m"
function print_usage { function print_usage {
echo "Usage: strm [OPTIONS] QUERY ... [OPTIONS]" echo "Usage: strm [OPTIONS] QUERIES ... [OPTIONS]"
echo echo
echo "Stream media files over SSH." echo "Stream media files over SSH."
echo echo
echo "OPTIONS" echo "OPTIONS"
echo " -h, --help Show this help message" echo " -h, --help Show this help message"
echo " -c, --config CONFIG_FILE Path to config file" echo " -c, --config CONFIG_FILE Path to config file (default: ~/.config/strm/strm.config)"
echo " -l, --list List files instead of playing" echo " -l, --list List files instead of playing"
echo " -m, --media-directories MEDIA_DIRECTORIES Use given media directories, config is ignored" 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 " -s, --shuffle Play files in random order" echo " -s, --shuffle Play files in random order"
echo echo
echo "EXAMPLES" echo "EXAMPLES"
echo " strm -l . # List all available files" echo " strm -l . # List all available files"
echo " strm Elephants Dream # Play files whose path contain 'elephants' and 'dream'" echo " strm Elephants Dream # Play files whose path contain 'elephants' and 'dream'"
echo " strm e*phants # Play files whose path matches the wildcard 'e*phants'" echo " strm e*phants # Play files whose path matches the glob pattern 'e*phants'"
exit exit
} }
@ -41,8 +42,9 @@ fi
# Set default values # Set default values
config="$HOME/.config/strm/strm.config" config="$HOME/.config/strm/strm.config"
list=false list=false
or=false
shuffle=false shuffle=false
query=() queries=()
media_directories="" media_directories=""
# Parse arguments # Parse arguments
@ -71,6 +73,10 @@ while (( "$#" )); do
error "Argument for $1 is missing" error "Argument for $1 is missing"
fi fi
;; ;;
-o|--or)
or=true
shift
;;
-s|--shuffle) -s|--shuffle)
shuffle=true shuffle=true
shift shift
@ -79,14 +85,14 @@ while (( "$#" )); do
error "Unsupported flag $1" error "Unsupported flag $1"
;; ;;
*) *)
query+=("$1") queries+=("$1")
shift shift
;; ;;
esac esac
done done
# Print usage if no query was given # Print usage if no queries were given
if [ "${#query[@]}" == 0 ]; then if [ "${#queries[@]}" == 0 ]; then
print_usage print_usage
fi fi
@ -113,17 +119,17 @@ media_directories=${media_directories//[[:blank:]]/}
IFS="," read -a media_directories <<< "$media_directories" IFS="," read -a media_directories <<< "$media_directories"
# Construct find argument array # Construct find argument array
find_arguments=() # Ignore hidden files and directories and list only files and symlinks
for i in "${!query[@]}"; do find_arguments=("-not" "-path" "'*/\.*'" "-type" "f,l")
for i in "${!queries[@]}"; do
# If more than one query is given add a logical AND # If -o flag is set and more than one query is given, add a logical OR
if [ "$i" -ge 1 ]; then if [ "$or" == true ] && [ "$i" -ge 1 ]; then
find_arguments+=("-a") find_arguments+=("-o" "-not" "-path" "'*/\.*'" "-type" "f,l")
fi fi
# Use the ipath argument to search case-insensitive # Use the ipath argument to search case-insensitive and surround query with wildcards
find_arguments+=("-ipath") find_arguments+=("-ipath" "'*${queries[$i]}*'")
find_arguments+=("'*${query[$i]}*'")
done done
# Initialize result arrays # Initialize result arrays
@ -139,7 +145,7 @@ for media_directory in "${media_directories[@]}"; do
# Get connection string and remote directory # Get connection string and remote directory
IFS="/" read -r connection_string directory <<< "$media_directory" IFS="/" read -r connection_string directory <<< "$media_directory"
echo -ne "Fetching results from $text_bold$connection_string$text_reset\n" 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 # Add leading and trailing slash to directory if missing
[[ "$directory" != /*/ ]] && directory="/$directory/" [[ "$directory" != /*/ ]] && directory="/$directory/"
@ -147,7 +153,7 @@ for media_directory in "${media_directories[@]}"; do
# Get search results from remote # Get search results from remote
# Look for paths matching given queries in visible directories, listing only filenames and links # 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" -not -path \"*/\.*\" -type l,f "${find_arguments[@]}" | sort) mapfile -t tmp_results < <(ssh -o ConnectTimeout=10 "$connection_string" find "$directory" "${find_arguments[@]}" | sort)
# Build SFTP strings and printable strings # Build SFTP strings and printable strings
for i in "${!tmp_results[@]}"; do for i in "${!tmp_results[@]}"; do
@ -192,8 +198,8 @@ if [ "$list" == false ]; then
# Play all remote files # Play all remote files
if [ "$shuffle" == true ]; then if [ "$shuffle" == true ]; then
mpv --msg-level=all=error,statusline=status --term-status-msg='${playlist-pos-1}/${playlist-count} - ${time-pos}/${duration} - \e[1m${media-title}\e[0m' --shuffle "${sftp_results[@]}" mpv --shuffle --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' "${sftp_results[@]}"
else else
mpv --msg-level=all=error,statusline=status --term-status-msg='${playlist-pos-1}/${playlist-count} - ${time-pos}/${duration} - \e[1m${media-title}\e[0m' "${sftp_results[@]}" 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' "${sftp_results[@]}"
fi fi
fi fi