I started a omx instance based on this script. it works great, but I can't quit the player with q or alt f4 or ctrl-z.in desktop the keyboard commands always arrive on the desktop. especially if I start the script on the raspberry in CLI mode, I would never get out of the video.
What can I do here?
#!/bin/bash
### BEGIN INIT INFO
# Provides: omxplayer
# Required-Start:
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Displays video file in a loop using omxplayer
# Description:
### END INIT INFO
# Video (replace with the path and file name of your video)
video_path=/home/pi/video.mp4
#---- There should be no need to edit anything below this line ----
# Start displaying the video loop
case "$1" in start)
screen -dmS videoloop sh -c "omxplayer -o both $video_path -b --loop --no-osd"
echo "Video Playback Started"
;;
# Stop displaying video loop
stop)
sudo killall omxplayer.bin
echo "Video Playback Stopped"
;;
# Restart video loop if it died
repair)
if !(ps -a | grep omx -q)
then
screen -dmS videoloop sh -c "omxplayer -o local $video_path -b --loop --no-osd"
echo "The Video is now running"
fi
;;
*)
echo "Usage: /etc/init.d/videoloop {start|stop|repair}"
exit 1
;;
esac
Related
In my script I need to work with the exit status of the non-last command of a pipeline:
do_real_work 2>&1 | tee real_work.log
To my surprise, $? contains the exit code of the tee. Indeed, the following command:
false 2>&1 | tee /dev/null ; echo $?
outputs 0. Surprise, because the csh's (almost) equivalent
false |& tee /dev/null ; echo $status
prints 1.
How do I get the exit code of the non-last command of the most recent pipeline?
Bash has set -o pipefail which uses the first non-zero exit code (if any) as the exit code of a pipeline.
POSIX shell doesn't have such a feature AFAIK. You could work around that with a different approach:
tail -F -n0 real_work.log &
do_real_work > real_work.log 2>&1
kill $!
That is, start following the as yet non-existing file before running the command, and kill the process after running the command.
I'm on a headless RaspberryPi (Raspbian) and I would like this service to autostart when system starts up:
#!/bin/bash
### BEGIN INIT INFO
# Provides: mnt
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: mount/unmount volumes from /etc/fstab
### END INIT INFO
#VARIABLES for the truecrypt volume
PROTECT_HIDDEN=no
KEYFILES=""
PASSWORD_FILE=/etc/truecrypt
mount_all(){
slot=0
while read line;
do
read -a fields <<< $line
VOLUME_PATH=${fields[0]}
MOUNT_DIRECTORY=${fields[1]}
FILESYSTEM=${fields[2]}
OPTIONS=${fields[3]}
slot=$((slot+1))
truecrypt \
--text \
--verbose \
--keyfiles=$KEYFILES \
--protect-hidden=$PROTECT_HIDDEN \
--slot=${slot} \
--fs-options=$OPTIONS \
--filesystem=$FILESYSTEM $VOLUME_PATH $MOUNT_DIRECTORY \
< <(grep $VOLUME_PATH $PASSWORD_FILE | sed "s,^${VOLUME_PATH}:,,") \
| grep -v "Enter password for"
done < <(grep '^##truecrypt' /etc/fstab | sed 's/##truecrypt://g')
}
# Function to redirect the output to syslog
log_to_syslog(){
# Temporal file for a named pipe
script_name=$(basename "$0")
named_pipe=$(mktemp -u --suffix=${script_name}.$$)
# On exit clean up
trap "rm -f ${named_pipe}" EXIT
# create the named pipe
mknod ${named_pipe} p
# start syslog and redirect the named pipe
# append the script name before the messages
logger <${named_pipe} -t $0 &
# Redirect stout and stderr to the named pipe
exec 1>${named_pipe} 2>&1
}
# If the script does not run on a terminal then use syslog
set_log_output(){
if [ ! -t 1 ]; then
log_to_syslog
fi
}
case "$1" in
''|start)
EXITSTATUS=0
set_log_output
mount_all || EXITSTATUS=1
exit $EXITSTATUS
;;
stop)
EXITSTATUS=0
set_log_output
truecrypt --verbose --force --dismount || EXITSTATUS=1
exit $EXITSTATUS
;;
restart|force-reload)
EXITSTATUS=0
$0 stop || EXITSTATUS=1
$0 start || EXITSTATUS=1
exit $EXITSTATUS
;;
status)
EXITSTATUS=0
truecrypt --list 2>/dev/null || echo "No truecrypt volumes mounted"
exit $EXITSTATUS
;;
*)
echo "Usage: $0 [start|stop|restart]"
exit 3
;;
esac
The service has 755 permisisons and is owned by root. After setting the permission I did (with no errors):
update-rc.d mnt defaults
When I start the service manually immediately after startup it works well.
Where may be the problem? It would be also great to use this service as a required prerequisite for autostarting Samba - is it possible?
The solution was pretty simple. I installed truecrypt only as a binary and I had environment variable path to truecrypt set only for user, not root or any other system user which is used for autostart.
The solution was to change truecrypt command to /path_to_truecrypt/truecrypt.
Problem: I can't find any way to reliably get the current playing file in an MPlayer playlist.
Here is how far I have gotten. This working ash script monitors a text file with the path to the current playlist. When I update the file, the script closes the old instance of MPlayer and opens a new one with the new playlist:
# POLL PLAYLIST FILE FOR CHANGES
CURRENTPLAYLISTPATH=/home/tc/currentplaylist
INFIFO=/tmp/mplayer-in
CURRENTPLAYLIST="NEVERMATCHAPLAYLIST"
FIRSTRUN=1
while [ 1 ];
do
# CHECK FOR NEW PLAYLIST
NEWPLAYLIST=$(head -n 1 $CURRENTPLAYLISTPATH)
if [[ "$NEWPLAYLIST" != "$CURRENTPLAYLIST" ]]; then
if [ "$FIRSTRUN" == 0 ]; then
echo "quit" > "$INFIFO"
fi
# CREATE NAMED PIPE, IF NEEDED
trap "rm -f $INFIFO" EXIT
if [ ! -p $INFIFO ]; then
mkfifo $INFIFO
fi
# START MPLAYER
mplayer -fixed-vo -nolirc -vc ffmpeg12vdpau,ffh264vdpau, -playlist $NEWPLAYLIST -loop 0 -geometry 1696x954 -slave -idle -input file=$INFIFO -quiet -msglevel all=0 -identify | tee -a /home/tc/mplayer.log &
CURRENTPLAYLIST=$NEWPLAYLIST
FIRSTRUN=0
fi
sleep 5;
done
My original plan was just to use the "-identify" flag and parse the log file. This actually works really well up until I need to truncate the log file to keep it from getting too large. As soon as my truncating script is run, MPlayer stops writing to the log file:
FILENAME=/home/tc/mplayer.log
MAXCOUNT=100
if [ -f "$FILENAME" ]; then
LINECOUNT=`wc -l "$FILENAME" | awk '{print $1}'`
if [ "$LINECOUNT" -gt "$MAXCOUNT" ]; then
REMOVECOUNT=`expr $LINECOUNT - $MAXCOUNT`
sed -i 1,"$REMOVECOUNT"d "$FILENAME"
fi
fi
I have searched and searched but have been unable to find any other way of getting the current playing file that works.
I have tried piping the output to another named pipe and then monitoring it, but only works for a few seconds, then MPlayer completely freezes.
I have also tried using bash (instead of ash) and piping the output to a function like the following, but get the same freezing problem:
function parseOutput()
{
while read LINE
do
echo "get_file_name" > /tmp/mplayer-in
if [[ "$LINE" == *ANS_FILENAME* ]]
then
echo ${LINE##ANS_FILENAME=} > "$CURRENTFILEPATH"
fi
sleep 1
done
}
# START MPLAYER
mplayer -fixed-vo -nolirc -vc ffmpeg12vdpau,ffh264vdpau, -playlist $NEWPLAYLIST -loop 0 -geometry 1696x954 -slave -idle -input file=/tmp/mplayer-in -quiet | parseOutput &
I suspect I am missing something very obvious here, so any help, ideas, points in the right direction would be greatly appreciated.
fodder
Alright then, so I'll post mine too.
Give this one a try (assuming there is only one instance running, like on fodder's machine):
basename "$(readlink /proc/$(pidof mplayer)/fd/* | grep -v '\(/dev/\|pipe:\|socket:\)')"
This is probably the safer way, since the file descriptors might not always be in the same order on all systems.
However, this can be shortened, with a little risk:
basename "$(readlink /proc/$(pidof mplayer)/fd/*)" | head -1
You might probably like to install this, too:
http://mplayer-tools.sourceforge.net/
Well, I gave up on getting the track from MPlayer itself.
My 'solution' is probably too hackish, but works for my needs since I know my machine will only ever have one instance of MPlayer running:
lsof -p $(pidof mplayer) | grep -o "/path/to/my/assets/.*"
If anyone has a better option I'm certainly still interested in doing this the right way, I just couldn't make any of the methods work.
fodder
You can use the run command.
Put this in ~/.mplayer/input.conf:
DEL run "echo ${filename} ${stream_pos} >> /home/knarf/out"
Now if you press the delete key while playing a file it will do what you expect i.e. append the current file playing and the position in the stream to the ~/out file. You can replace echo with your program.
See slave mod docs for more info (Ctrl-F somevar).
About getting properties from MPlayer
I have used a non-elegant solution, but it is working for me.
stdbuf -oL mplayer --slave --input=file=$FIFO awesome_awesome.mp3 |
{
while IFS= read -r line
do
if [[ "${line}" == ANS_* ]]; then
echo "${line#*=}" > ${line%=*} # echo property_value > property_name
fi
done
} &
mplayer_pid=&!
read filename < ./ANS_FILENAME
read timeLength < ./ANS_LENGTH
echo ($timeLength) $filename
and so on..
It is in another proccess, that's why I've used files to bring properties
'stdbuf' is for not to miss anything
I started putting together a bash library to handle tasks like this. Basically, you can accomplish this by dumping the mplayer output to a file. Then you grep that dump for "Playing " and take the last result with tail. This should give you the name of the file that's currently playing or that last finished playing.
Take a look at my bash code. You'll want to modify the playMediaFile function to your needs, but the getMediaFileName function should do exactly what you're asking. You'll find the code on my github.
If I have a script that plays a file using mplayer and I stop the playback half way through, is there a way to store the playback position where it stopped?
Try this
its quick and dirty but gives me the seconds of the played song after mplayer exited
mplayer your.mp3 | tr [:cntrl:] '\n' | bbe -e "s/\x0a\x5b\x4a//" | tail -n 4 | head -n 1 | cut -d ':' -f 2 | cut -d '(' -f 1
It should be noted that this does almost the same thing as 0800peter's answer but without the need to install bbe. Essentially, this is a rewrite of that answer with a friendly interface. This answer also accounts for the event that mplayer is prematurely terminated (as in with pkill mplayer).
#!/bin/bash
# desc: Runs mplayer to play input file and returns seconds of playback when stopped
# input:
# arg1: path to audio file
# arg2: pass either [seconds|timestamp]; default timestamp
# output: returns the timestamp or total seconds elapsed when playback stopped
# (ie. when mplayer terminated)
playAudioFile() {
audioFile="$1"
# if you need to modify mplayer switches, do so on the next line
stopPos=$(mplayer "$audioFile" 2> /dev/null | tr [:cntrl:] '\n' | grep -P "A: +\d+\.\d\b" | tail -n1)
# decide what to display
if [ "$2" == "seconds" ]; then
retval=$(awk '{print $2}' <<< "$stopPos")
else
retval=$(awk '{print $3}' <<< "$stopPos" | tr -d '()')
fi
echo "$retval"
}
#example usage
path="$1"
stopPosition=$(playAudioFile "$path")
echo "$stopPosition"
My script, as it is, accepts the path to an audio file and when mplayer terminates (normally or abnormally), a timestamp or seconds elapsed is returned. If you opt to receive a timestamp, note that the timestamp will not have a placeholder for any unit with a value zero. In other words, 00:00:07.3 would be returned as 07.3 and 00:10:01.2 would be returned as 10:01.2
What if I want to send mplayer to the background?
If you want to be able to start mplayer and send it to the background and still be able to query for this information, you might want to take a look at a bash script I wrote for tracking playback status information. That script incorporates two functions called getElapsedTimestamp and getElapsedSeconds, both of which return the playback time even if mplayer has already terminated. To use these functions, the media file must be started with my playMediaFile function. This function can be called like this to start mplayer and send to background ...
playMediaFile "path/to/your/file" &
I'm somewhat new to Linux and OpenXCAP and I'm trying to make an init.d script for OpenXCAP on CentOS 6.
My script can start and stop OpenXCAP service, but it returns this error for the status command (service openxcap status): openxcap dead but subsys locked
Maybe somebody can tell me if problem is in the init.d script or the openxcap service itself? Is openxcap missing some 'give-status' feature?
#!/bin/bash
#
# Startup script for OpenXCAP
#
# processname: openxcap
# pidfile: /var/run/openxcap/openxcap.pid
# chkconfig: - 85 15
# description: start, stop, restart OpenXCAP server
#
### BEGIN INIT INFO
# Provides: openxcap
# Required-Start: $local_fs $network
# Should-Start: mysqld
### END INIT INFO
# Source function library.
. /etc/rc.d/init.d/functions
APP_NAME=openxcap
APP_HOME=/usr/local/src/openxcap-2.0.1
PID_PATH=/var/run/openxcap/openxcap.pid
RETVAL=0
[ -f /etc/sysconfig/$APP_NAME ] && . /etc/sysconfig/$APP_NAME
start()
{
echo -n $"Starting $APP_NAME: "
daemon $APP_HOME/$APP_NAME $OPTIONS 2>/dev/null | tail -1
RETVAL=$?
echo
[ $RETVAL = 0 ] && touch /var/lock/subsys/$APP_NAME
}
stop()
{
echo -n $"Stopping $APP_NAME: "
killproc -p $PID_PATH
RETVAL=$?
echo
[ $RETVAL = 0 ] && rm -f /var/lock/subsys/$APP_NAME $PID_PATH
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status $APP_NAME
RETVAL=$?
;;
restart|reload)
stop
start
;;
*)
echo $"Usage: $APP_NAME {start|stop|reload|restart|status|help}"
exit 1
esac
exit $RETVAL
You are (hopefully) writing out a PID file as /var/run/openxcap/openxcap.pid.
I suspect that your program is writing out one PID, but then starting another process. The first process dies, so sysvinit doesn't know to look for a different one.
However, the lock file indicating that your process was started is still present.
You may not be able to directly use the daemon function for starting this program; you might need to create a customized version that is “smart enough” to identify the correct PID.