Last active
November 18, 2020 06:17
-
-
Save StefanHamminga/1d78baa1bc87f2d7383c4027c2b90ec8 to your computer and use it in GitHub Desktop.
piplay - Raspberry Pi Omxplayer wrapper script with support for wildcards, streaming (YouTube, etc) and skipping of played files.
This file contains hidden or 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 | |
# piplay - Raspberry Pi Omxplayer wrapper script. | |
# Required packages on Debian: omxplayer youtube-dl attr | |
# TODO / future plans: Use the D-Bus interface to store media playback position and resume from there. | |
REQUIREMENTS=(omxplayer youtube-dl find sort getfattr setfattr nice ionice) | |
# Subtitle languages, in order of preferences. Format: movie.mkv & movie.en.srt => en | |
SUBTITLELANGUAGES=( nl nld dut en eng ) | |
usage() { | |
echo -e " | |
\e[1mpiplay\e[0m Wrapper script for the Raspberry Pi Omxplayer. | |
Plays most things you throw at it. Wildcard support using find, http(s) | |
playback using youtube-dl. Marks fully played files with the extended user | |
attribute 'user.piplay'='played'. This allows using wildcards to play a bunch | |
of files, yet skipping already played files. Shuffle is also supported. | |
Sets ionice to class 2 (best-effort) and priority 0 (highest). Sets nice value | |
to -4 (if allowed, see limits.conf). | |
Usage: | |
\e[1mpiplay\e[0m [options] file|url|wildcard file2 ... | |
-u, --unwatched List all unwatched files in current directory and exit. | |
-r, --replay Replay media files, clearing played attributes. | |
-s, --shuffle Randomize playback order for anything after the option. | |
-w, --watched Don't play, just mark as watched. | |
-c, --clear Clear playing and watched flags from input and exit. | |
-d, --debug Don't execute, just echo each command. | |
file File, wildcard, url to play. Add as many as you want, | |
in any order you want. Go nuts. | |
" | |
exit $1 | |
} | |
YTGFORMAT="best[vcodec!=vp9][height<=?1080]" | |
NICE="-n -4" | |
IONICE="-c 2 -n 0" | |
OMXOPTS="-b -o hdmi" | |
OMX="nice $NICE ionice $IONICE omxplayer $OMXOPTS" | |
DEBUG="" | |
# Test if all required commands are present, if not, show the user what to install | |
for REQ in "${REQUIREMENTS[@]}"; do | |
command -v $REQ >/dev/null || { echo -e "piplay: Error, please install a package for command \e[91m$REQ\e[0m"; exit 1; } | |
done | |
if [ "$1" = "" ]; then | |
usage 0 | |
fi | |
shopt -s nocasematch | |
action() { | |
ACTION=$1 | |
shift | |
echo -e "$ACTION \e[92m$*\e[0m" | |
# echo -n -e "\033]2;$* | piplay\007" | |
echo -n -e "\033]30;$* | piplay\007" | |
} | |
# Disable this and CTRL-C will only break playback of the current item, instead of overall. | |
trap "echo -e '\e[91mUser requested exit\e[0m'; exit 1" SIGINT SIGTERM | |
# Store arguments in an array, for shuffle support | |
OPTS=( "$@" ) | |
shuffle() { | |
local i tmp size max rand | |
size=${#OPTS[*]} | |
max=$(( 32768 / size * size )) | |
for ((i=size-1; i>0; i--)); do | |
while (( (rand=$RANDOM) >= max )); do :; done | |
rand=$(( rand % (i+1) )) | |
tmp=${OPTS[i]} OPTS[i]=${OPTS[rand]} OPTS[rand]=$tmp | |
done | |
} | |
find_sub() { | |
FILENAME=${1%.*} | |
for SUBLANG in "${SUBTITLELANGUAGES[@]}"; do | |
if [ -f "$FILENAME.$SUBLANG.srt" ]; then | |
export SUB_FILE="$FILENAME.$SUBLANG.srt" | |
return | |
fi | |
done | |
if [ -f "$FILENAME.srt" ]; then | |
export SUB_FILE="$FILENAME.srt" | |
return | |
fi | |
unset SUB_FILE | |
} | |
while true; do | |
OPT=${OPTS[0]} | |
if [ "$OPT" = "" ]; then | |
action Finished | |
exit 0 | |
fi | |
OPTS=( "${OPTS[@]:1}" ) | |
if [ "$OPT" = "-u" ] || [ "$OPT" = "--unwatched" ]; then | |
find ./ \ | |
-regextype sed \ | |
-regex '.*\.*\(aac\|ac3\|avi\|cda\|flac\|m4a\|m4v\|mkv\|mp3\|mp4\|ogg\|ogm\|ogv\|wav\|wmv\)$' \ | |
-exec sh -c "getfattr --only-values -n user.piplay \"{}\" 2>/dev/null | grep -q played || echo \"{}\" | sed -r s,^\.\/,," \; | sort | |
# -exec sh -c "getfattr --only-values -n user.piplay \"{}\" 2>/dev/null | grep -q played || ls --color \"{}\"" \; | sort | |
exit 0 | |
elif [ "$OPT" = "-d" ] || [ "$OPT" = "--debug" ]; then | |
DEBUG="echo" | |
elif [ "$OPT" = "-r" ] || [ "$OPT" = "--replay" ]; then | |
REPLAY="true" | |
elif [ "$OPT" = "-s" ] || [ "$OPT" = "--shuffle" ]; then | |
SHUFFLE="-R" | |
shuffle | |
elif [ "$OPT" = "-w" ] || [ "$OPT" = "--watched" ]; then | |
JUSTMARK="true" | |
elif [ "$OPT" = "-c" ] || [ "$OPT" = "--clear" ]; then | |
JUSTCLEAR="true" | |
elif [[ $OPT =~ ^https?:// ]]; then | |
action Playing $OPT | |
$DEBUG $OMX `youtube-dl -g -f $YTGFORMAT "$OPT"` | |
elif [[ $OPT =~ ^rt(mp|sp):// ]]; then | |
action Playing $OPT | |
$DEBUG $OMX "$OPT" | |
else | |
while read -u 3 file; do | |
if [ "$JUSTCLEAR" = "true" ]; then | |
$DEBUG setfattr -x user.piplay "${file}" && \ | |
action "Cleared piplay status for:" $file | |
elif [ "$JUSTMARK" = "true" ]; then | |
$DEBUG setfattr -n user.piplay -v "played" "${file}" && \ | |
action "Marked as played:" $file | |
elif [ "$REPLAY" = "true" ]; then | |
$DEBUG setfattr -x user.piplay "${file}" | |
action Playing $file | |
find_sub "${file}" | |
$DEBUG setfattr -n user.piplay -v "playing" "${file}" | |
if [ "${SUB_FILE}" != "" ]; then | |
$DEBUG $OMX --subtitle "${SUB_FILE}" "${file}" && \ | |
$DEBUG setfattr -n user.piplay -v "played" "${file}" && \ | |
action "Marked as played:" $file | |
else | |
$DEBUG $OMX "${file}" && \ | |
$DEBUG setfattr -n user.piplay -v "played" "${file}" && \ | |
action "Marked as played:" $file | |
fi | |
elif [[ `getfattr --only-values -n user.piplay "${file}" 2>/dev/null` != "played" ]]; then | |
action Playing $file | |
find_sub "${file}" | |
$DEBUG setfattr -n user.piplay -v "playing" "${file}" | |
if [ "${SUB_FILE}" != "" ]; then | |
$DEBUG $OMX --subtitle "${SUB_FILE}" "${file}" && \ | |
$DEBUG setfattr -n user.piplay -v "played" "${file}" && \ | |
action "Marked as played:" $file | |
else | |
$DEBUG $OMX "${file}" && \ | |
$DEBUG setfattr -n user.piplay -v "played" "${file}" && \ | |
action "Marked as played:" $file | |
fi | |
else | |
echo -e "Alread played \e[91m${file}\e[0m" | |
fi | |
# Clean out pending keyboard commands: | |
read -t 0.05 -n 10000 discard || true | |
done 3<<< `find -L "$OPT" -type f | sort -f $SHUFFLE` | |
fi | |
# Clean out pending keyboard commands: | |
read -t 0.05 -n 10000 discard || true | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment