software (svp2.sh)

#!/bin/bash
#  Notice, must be run explicitly as "/bin/bash", not "/bin/sh",
#  because advanced bash features like arrays are used.

#  svp2.sh
#  Sheila Video Player
#
#  svp2:  This is the second version of the player, which now uses
#  a few keys on a regular USB computer keyboard instead of the custom
#  switches going into Raspberry Pi GPIO inputs.  The switch inputs can
#  still be provided by custom hardware, but by exploiting a regular keyboard
#  interface, the system can run on any Linux host, instead of requiring
#  a Raspberry Pi or similar unit with available GPIO inputs.

#  You can specify the BASEDIR on cmdline, which should contain the
#  subdirectories videos and images (mainly for testing/development).
#  Otherwise, /mnt is used (which is expected to be a user-supplied
#  USB data stick; see example fstab).  There's no error handling if
#  the directories or expected files don't exist.
if [ -n "${1}" ]; then
    BASEDIR="${1}"
else
    BASEDIR="/mnt"  #  externally-supplied USB data stick
fi

#  With a second cmdline param, you can shorten/adjust the startup delay
#  (possibly to 0), again mainly for development.
SLEEPTIME=10
if [ -n "${2}" ]; then
    SLEEPTIME="${2}"
fi

#  Note that videos must have the suffix .mpg, and images must have the
#  suffix .jpg, even if they are not really those filetypes.
#  The video and image player programs can probably handle many other
#  filetypes, but this naming inflexibility makes string processing simpler.
VID_LOCATION="${BASEDIR}/videos"
VID_SUFFIX='.mpg'
IMG_LOCATION="${BASEDIR}/images"
IMG_SUFFIX='.jpg'
IMG_NOTFOUND='notfound.jpg'
#VID_CMD='mpv --fs --ontop --no-resume-playback --audio-device=alsa/hdmi:CARD=vc4hdmi,DEV=0'
#VID_CMD='mpv --fs --ontop --no-resume-playback --no-terminal'
VID_CMD='mpv --fs --ontop --no-resume-playback --vo=vaapi,drm,'
IMG_CMD='fim -N -q'

exec 2> /dev/null

#  Find the list of video filenames and store in array VID[], then create
#  the associated cover image filenames in array IMG[].  If one of the
#  video files does not have an associated cover image, then the
#  IMG_NOTFOUND image is displayed instead.
N=0
for F in `ls -1 ${VID_LOCATION}`; do
    BN=`basename ${F} ${VID_SUFFIX}`
    VID[${N}]="${VID_LOCATION}/${BN}${VID_SUFFIX}"
    I="${IMG_LOCATION}/${BN}${IMG_SUFFIX}"
    IMG[${N}]="${I}"
    if [ ! -r "${I}" ]; then
        echo "didn't find image file ${I}"
        IMG[${N}]="${IMG_LOCATION}/${IMG_NOTFOUND}"
    fi
    N=`expr $N + 1`
done
TOP=`expr $N - 1`
echo "found $N videos"

#  Delay for 10 seconds after startup before trying to display anything.
#  This is a kluge (obviously).  The .service file has the
#  "WantedBy=multi-user.target" line, which is supposed to pause activity
#  until the system is ready, but this doesn't work.  Maybe I should be using
#  a different .target?  Anyway, without the delay here, the first image
#  does not get displayed, instead there is just a mess of console text on
#  the screen until the first button is pressed, because the initial image
#  display occurred before the graphics system was ready.
echo "waiting for video system to initialize..."
sleep "${SLEEPTIME}"
echo
echo "OK, let's try it"

#  This is the main running loop.  Initially, the first cover image is
#  displayed.  If forward or back arrows are hit, then the image changes
#  accordingly.  When the play button is hit, the corresponding video
#  for the cover image currently onscreen is played.  Any button hits
#  during video playback will terminate the playback and return to the
#  cover images.  (There's no pause/resume capability: videos always
#  play from the start until finished or interrupted, because that's
#  how Sheila likes it.)
SEL=0
result=0
playing=0
img_active=0
while true; do
    if [ ${playing} -eq 0 ]; then
        if [ ${img_active} -eq 0 ]; then
            ( ${IMG_CMD} ${IMG[${SEL}]} ) &
            ourpid=$!
            img_active=1
        fi
    fi
    stty -echo -icanon time 0 min 0
    while true; do
        result=0
        key=$( dd bs=1 count=1 2> /dev/null; printf "." )
        key=${key%.}
        case $key in
            1) result=1 ;;
            2) result=2 ;;
            q) result=2 ;;
            3) result=3 ;;
        esac
        if [ ${result} -eq 1 ]; then SEL=`expr $SEL - 1`; break;
        elif [ ${result} -eq 2 ]; then break;
        elif [ ${result} -eq 3 ]; then SEL=`expr $SEL + 1`; break;
        fi
        if [ ${playing} -eq 1 ]; then
            if kill -0 ${vid_pid}; then
                #  video is still actually playing
                playing=1
            else
                #  video has ended
                playing=0
                break
            fi
        fi
    done
    stty sane
    if [ ${SEL} -ge ${N} ]; then
        SEL=0
    fi
    if [ ${SEL} -lt 0 ]; then
        SEL=${TOP}
    fi
    if [ ${img_active} -eq 1 ]; then
        kill ${ourpid}
        img_active=0
    fi
    if [ ${result} -eq 2 ]; then
        if [ ${playing} -eq 0 ]; then
            playing=1
            ( ${VID_CMD} ${VID[${SEL}]} ) &
            vid_pid=$!
        else
            playing=0
            kill ${vid_pid}
        fi
    else
        if [ ${playing} -eq 1 ]; then
            playing=0
            kill ${vid_pid}
        fi
    fi
done

exit 0
exit 0
exit 0

##  Thanks to "cfajohnson" on unix.com.
#
#stty -echo -icanon time 0 min 0
#while :
#do
#  key=$( dd bs=1 count=1 2> /dev/null; printf "." )
#  key=${key%.}
#  case $key in
#    q) break ;;
#    ?) printf "%d\n" "'$key" ;;
#  esac
#done
#stty sane

#  Thanks to Stuart P. Bentley on stackoverflow.com.
#
#You can write a function to close each of Bash's 10 inheritable file descriptors:
#
#fdcloexec () {
#  "$@" 0>&- 1>&- 2>&- 3>&- 4>&- 5>&- 6>&- 7>&- 8>&- 9>&-
#}
#
#Then you would call fdcloexec your command here to execute your command without inheriting file descriptors.
#


Comments

Popular posts from this blog

keyboard interface

installed!