Created
March 18, 2013 04:49
-
-
Save Minoru/5185160 to your computer and use it in GitHub Desktop.
Bash (sorry!) script that implements idea from here: https://bnw.im/p/QBRE4F In short: it plays an audio file, pausing periodically to check if user is asleep already. If user doesn't respond (by making some noise), the script remembers current position in the file and quits. Next time script is run on the same file, playback is resumed from the…
This file contains 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 | |
# I hereby place this script into public domain. | |
# database is CSV file containing position (in seconds) and filename, separated by a comma | |
db="$HOME/.mama.db" | |
# timeout is number of seconds to wait between checks if user is asleep | |
# default is 10 minutes | |
timeout="600" | |
# how much seconds to rewind when pausing to ask user if he's asleep | |
rewind_on_pause="5" | |
# turn filename into canonical one | |
input_file="`readlink -f \"$1\"`" | |
# check if there's a database of played tracks | |
if [ ! -f "$db" ]; then | |
touch "$db" | |
seekpoint="0" | |
else | |
# we only care about the first record found, thus max-count | |
seekpoint="`grep --max-count 1 \"$input_file\" \"$db\" | cut -f1 -d','`" | |
fi | |
# create temporary directory to hold FIFO pipes | |
tmp="`mktemp -d --tmpdir 'mama.XXX'`" | |
# create pipes that would be used to control MPlayer | |
mplayer_control="$tmp/mplayer_control" | |
mkfifo "$mplayer_control" | |
mplayer_output="$tmp/mplayer_output" | |
mkfifo "$mplayer_output" | |
# spawn mplayer | |
mplayer -slave -input file="$mplayer_control" "$input_file" 2>/dev/null | grep --line-buffered -i ans_time_position > "$mplayer_output" & | |
disown % | |
# seek to absolute position specified in seconds | |
echo "seek $seekpoint 2" > "$mplayer_control" | |
while true; do | |
sleep "$timeout" | |
echo "pause" > "$mplayer_control" | |
# rewind the file a bit so user won't loose track of what's going on | |
# because of pause | |
echo "seek -$rewind_on_pause" > "$mplayer_control" | |
# Basic idea of the following few lines: we can listen to the background | |
# noise and then ask user to say something. We then calculate how much we | |
# can amplify each file without making it clip (audio term for overflow). | |
# Those numbers are called "volume adjustment". The bigger the adjustment, | |
# the quiter is the file. We set an empirical limit: if adjustments differ | |
# by more than 1.5 times, we say that user said something. | |
# recording background noise to check how much we can amplify it without | |
# clipping | |
echo "Please be silent for a few seconds..." | festival --tts | |
noise_adjustment="`rec -q -c 1 -n trim 0 3 stat 2>&1 | grep -i adjustment | cut -f 2 -d':' | sed 's/ //g'`" | |
# now the same but for signal | |
echo "If you're not asleep, please say so" | festival --tts | |
signal_adjustment="`rec -q -c 1 -n trim 0 3 stat 2>&1 | grep -i adjustment | cut -f 2 -d':' | sed 's/ //g'`" | |
result="`echo 1.2*$signal_adjustment \< $noise_adjustment | bc`" | |
if [ $result -eq 1 ] ; then | |
# continue playback | |
echo "pause" > "$mplayer_control" | |
else | |
echo "Good night!" | festival --tts | |
# remove previous record about the file | |
escaped_input_file="`echo \"$input_file\" | sed 's#/#\\\\/#g'`" | |
sed -i "/$seekpoint,$escaped_input_file/d" "$db" | |
# save position and quit | |
echo "get_time_pos" > "$mplayer_control" | |
seekpoint="`head -1 \"$mplayer_output\" | sed 's/ANS_TIME_POSITION=//'`" | |
echo "$seekpoint,$input_file" >> "$db" | |
echo "quit" > "$mplayer_control" | |
break | |
fi | |
done | |
rm -rf "$tmp" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment