I've been trying to do this with video, but I just couldn't get the permissions right to display mplayer on the screen. So I created a BASH script to wait for a file change with inotifywait
and then run mplayer as a user with permission to use it.
#!/bin/bash
# Mplayer server
# Watches for a file to be populated; then launches mplayer
PLAYFILE=/tmp/mserver_play.txt
CONTROL=/tmp/mserver_control
if [ -f $PLAYFILE ] ; then rm -f $PLAYFILE ; fi
while true ; do
touch $PLAYFILE
chmod a+w $PLAYFILE
r="$(inotifywait $PLAYFILE 2> /dev/null)"
if [ "$(echo $r | tail -1 | cut -d' ' -f2)" != "MODIFY" ] ; then
echo File removed or changed, exiting
exit 1
fi
# The wait is over! Play the file.
PLAYPATH="$(head -1 $PLAYFILE)"
rm $PLAYFILE
# TODO: Put in security checks on PLAYPATH.
if [[ -p $CONTROL ]]; then
rm -f $CONTROL
fi
mkfifo $CONTROL
chmod a+w $CONTROL
mplayer -autosync 30 -mc 2 -cache 10240 -cache-min 50 -ao sdl -lavdopts skiploopfilter=all -vf cropdetect -quiet -slave -input file=$CONTROL "$PLAYPATH" 2> /dev/null > /dev/null
done
Run that script as a user with permissions to run mplayer. mplayer probably has more tags here than are necessary for either of our purposes, but it works for both video and audio. Then in PHP you just write the path you want to play into the $PLAYFILE, e.g. with file_put_contents('/tmp/mserver_play.txt', $the_file_to_play)
.
Security, of course, is relative. Any user can write to the file to launch mplayer, and I couldn't find an easy way to restrict that; but adding www-data to your group and removing the chmods should probably work. You might, for example, want to restrict files to play to local files with test -f $PLAYPATH
, but I want the ability to use http URLs there.