#!/bin/bash
# http://www.crystalfaeries.net/linux/bin/media
# Wed May 26 14:18:18 HST 2010 angela@crystalfaeries.net http://www.kahealani.com/kahealani/angela_kahealani.html
# Collects from Second Life's public chatlog the ShoutCast streams selected for the SHOUTCAST2SL JUKEBOX in Second Life (TM)
# into a playlist for Real Life listening, and manages removal from the playlist of streams you later find undesirable.
# It first plays local files in the music directory and allows their deletion if unwanted.
# It also supports cleaning up the streamrips of http://sl.magnatune.com/New%20Age
# It also supports cleaning up the streamrips of http://sl.magnatune.com/Jazz
# Sat Jun 26 19:12:15 HST 2010 Added -s flag and improved local file playlist generation
# Sun Jun 27 16:05:58 HST 2010 Added editing of local files with audacity
# Thu Jul 1 09:20:08 HST 2010 Added tracking of listened files to avoid duplication thus expediting reviewing entire collection
# Fri Jul 2 16:32:20 HST 2010 Improved playlist sorting for local files
# Mon Jul 5 18:00:59 HST 2010 Improved status messages for file disposition
# Tue Jul 13 13:00:13 HST 2010 Added videos into the mix
# Sun Jul 18 06:14:42 HST 2010 cannonicalized temporary file handling
# Tue Aug 3 13:35:56 HST 2010 Added deferral of viewing
# 2010-09-10 01:39:45+00:00 Added sorting of .music.txt
# 2010-09-17 21:28:02+00:00 Added cron grep of streams from viewer log
# 2011-01-02 20:45:22+00:00 auto-skip zero-length files which are mostly gcn talk shows pending download
# 2011-01-14 04:42:47+00:00 redesigned the code for building list of existing files to be viewed / heard.
# 2011-02-02 01:06:46+00:00 yeah, still hardcoded audio and video locations changed to ~/{audio,video}
# 2011-02-12 03:47:26+00:00 updated cron entry for SpotON3D as well as Phoenix viewers:
# 2011-03-07 06:03:56+00:00 updated to find audio and video in /home rather than in $HOME
# Playlist for streaming URLs:
playlist=shoutcast2sl.txt
# userland crontab entry (edit according to your Second Life(TM) viewers):
# 04 2 * * * grep "Starting internet stream: " $HOME/.secondlife/logs/PhoenixViewer.log $HOME/.spoton3d/logs/SpotON3D.log | sed 's/^.*Starting internet stream: //' >> /home/www/playlists/$playlist
# Temporary file:
exitval=1 ;default to error condition because we have not yet chosen to intend to exit
appname="$(basename $0)"
tmpfile=$(mktemp /tmp/${appname}.XXXXXX) || exit $exitval
trap "rm -f $tmpfile /tmp/$playlist.$$; exit $exitval" 0 1 2 15
# Audio Player and Alert Sound:
alert="/usr/share/sounds/gnome/default/alerts/bark.ogg"
player='/usr/bin/mplayer'
player_options='-fs'
porn_player='/usr/bin/xine --fullscreen --loop=loop --session volume=69'
exitval=$("$player" "$alert") > /dev/null
#
# HELP
#
if [ "$1" = "-h" ]
then
echo "$(basename $0) Usage:"
echo "If you don't skip them with the -s flag, then first we play local files,"
echo "and after each file we give you an opportunity to enter 'rm' to remove that file,"
echo "or enter 'de' to defer that file, or enter 'ed' to edit that file in audacity."
echo "Yes, the script should be updated to choose like kino vs audacity for videos."
echo "Changing stations is as easy as typing: 'q<enter>'"
echo "To remove a station from your playlist, type: 'qrm<enter>'"
echo "To stop listening, type: 'q^C>'"
echo "To pause or resume listening, type: ' '"
echo "Some streams may not be resumable, so you 'resume' the next 'station'."
exit 0
fi
#
# STREAMS ONLY FLAG?
#
let streams_only=1 # false
if [ -n "$1" ] # any arguments on command line?
then
if [ "$1" = "-s" ] # yes, "-s" tells us to play only streams_only sources
then
let streams_only=0 # true
shift
fi
fi
#
# 1 Infinite Loop (ref: where is the flagpole holding the pirate flag in "Pirates of Silicon Valley"? in the center of)
#
cd $HOME/audio/ # work at the relative root level of the Music itself
touch .music.txt # keep a record of what we hear so we only hear each file once
while sleep 1;do #loop forever, presuming concurrency with Second Life (TM) and streamripper
if [ $streams_only = 0 ]
then
echo Playing Streams only, as requested
else
echo Playing Local Files followed by Streams, as requested
#
# PLAY LOCAL FILES FIRST
#
# build the list of existing files
cp /dev/null "$tmpfile"
for directories in /media/cdrom $HOME/audio $HOME/video /media /mnt /opt ~/Downloads /usr/local/src /home/www ; do
for extensions in .asx .avi .flac .flv .mov .mp1 .mp2 .mp3 .mp4 .mpg .ogg .ra .rm .ram .wma .wmv ; do
nice find $directories -iname "*$extensions" -exec du {} \; 2>/dev/null | grep -v kartrons_whores >> "$tmpfile"
done
done
# in decreasing size order
sort -rn "$tmpfile" | cut -f 2- > /tmp/$$.music.txt
mv /tmp/$$.music.txt "$tmpfile"
# clean the list of pre-viewed files
sort -u .music.txt > /tmp/$$.music.txt
mv /tmp/$$.music.txt .music.txt
# iterate, iterate, dance to the music...
for f in $(cat "$tmpfile");do
if [ -s "$f" ]
then # the audio file has content
if [ -s .music.txt ]
then # there are entries in .music.txt to filter out
grep "$f" .music.txt > /dev/null
if [[ $? = 0 ]]
then
echo PREHEARD: $f
else
echo HEARING_: $f
# play the file and ask to delete
porn=$(echo "$f" | sed 's/^.*porn/porn/' | sed 's/porn.*$/porn/')
if [ "$porn" == "porn" ]
then
exitval=$($porn_player $f > /dev/null 2>&1 &)
else
exitval=$($player $player_options $f)
fi
echo -n "Disposition: ('de' to defer, 'ed' to edit, 'rm' to remove/mute, else KEEP)?: "
read a
if [ "$a" = "rm" ]
then
rm "$f"
elif [ "$a" = "ed" ]
then
audacity "$f"
else
echo "KEPT: $f"
fi
if [ -f "$f" ]
then # user did not choose to remove the file
if [ "$a" = "de" ]
then
echo DEFERRED: "$f"
else
echo "$f" >> .music.txt # record that we heard the file
sort -u .music.txt > /tmp/$$.music.txt
mv /tmp/$$.music.txt .music.txt
echo HEARD+KEPT: "$f"
fi
else # user did choose to remove the file
echo REMOVED: "$f"
fi
fi
else # there are no entries in .music.txt to filter out
echo HEARING_: $f
# play the file and ask to delete
exitval=$("$player" "$player_options" "$f")
echo -n "Disposition: ('de' to defer, 'ed' to edit, 'rm' to remove/mute, else KEEP)?: "
read a
if [ "$a" = "rm" ]
then
rm "$f"
elif [ "$a" = "ed" ]
then
audacity "$f"
else
echo "KEPT: $f"
fi
if [ -f "$f" ]
then # user did not choose to remove the file
if [ "$a" = "de" ]
then
echo DEFERRED: "$f"
else
echo "$f" >> .music.txt # record that we heard the file
sort -u .music.txt > /tmp/$$.music.txt
mv /tmp/$$.music.txt .music.txt
echo HEARD+KEPT: "$f"
fi
else # user did choose to remove the file
echo REMOVED: "$f"
fi
fi
else # the audio file is null, probably a gcn talk show awaiting download
echo NULLFILE: $f
fi
done
fi # end of local files
#
# UPDATE STREAMS PLAYLIST FROM SECOND LIFE (TM) SHOUTCAST2SL JUKEBOX
#
if [ -d "$HOME"/chatlogs ]
then
if [ -f "$HOME"/chatlogs/chat.txt ]
then
echo "Good: I found your chatlog."
else
echo "I can not find your chatlog, so please:"
echo "ln -s "$HOME"/.secondlife/avatar_name/ "$HOME"/chatlogs"
echo "I do not presume which 'avatar name' you use."
exit 1
fi
else
echo "I can not find your chatlogs, so please:"
echo " ln -s "$HOME"/.secondlife/avatar_name/ "$HOME"/chatlogs"
echo "I do not presume which 'avatar name' you use."
exit 1
fi
if [ -d $HOME/audio ]
then
if [ -d /home/www/playlists ]
then
echo "Good: playlists directory found."
else
mkdir -p /home/www/playlists
echo "Good: playlists directory created."
fi
else
mkdir -p /home/www/playlists
echo "Good: playlists directory created."
fi
echo "Good: Refreshing Playlist from Second Life (TM) Public Chatlog..."
if [ -f /home/www/playlists/$playlist ]
then
cp /home/www/playlists/$playlist /tmp/$playlist.$$
else
touch /tmp/$playlist.$$
fi
grep "SHOUTCAST2SL JUKEBOX" "$HOME"/chatlogs/chat.txt | cut -c 64- | sort -u | grep http >> /tmp/$playlist.$$
sort -u /tmp/$playlist.$$ > /home/www/playlists/$playlist
rm /tmp/$playlist.$$
echo "Good: Pruning the streams previously removed from the playlist:"
if [ -f /home/www/playlists/."$playlist" ]
then
if [ -z /home/www/playlists/."$playlist" ]
then
echo "OK: Empty Mute List."
else
echo -n "Good: Processing Mute List"
for u in $(cat /home/www/playlists/."$playlist");do
grep -v "$u" /home/www/playlists/$playlist > /tmp/$playlist.$$
mv /tmp/$playlist.$$ /home/www/playlists/$playlist
echo -n "."
done
echo ""
echo "Good: Processed Mute List."
fi
else
echo "OK: NonExistant Mute List."
fi
#
# PLAY STREAMS FROM INTERNET LISTED IN PLAYIST
#
for f in $(cat /home/www/playlists/$playlist);do
echo "======= Begin: $f ======="
# ping -c 1 `echo $f \
# | sed 's/http:\/\///' \
# | sed 's/\/.*$//' \
# | sed 's/:.*$//'`
# if [[ $? = 0 ]]
# then
exitval=$("$player" "$player_options" "$f")
if [ $? == 0 ]
then
echo "========= End: $f ======="
echo -n "Disposition: ('rm' to remove/mute)?: "
read a
if [ "$a" = "rm" ]
then
echo "$f" >> /home/www/playlists/."$playlist"
echo "MUTED: $f"
else
echo "KEPT: $f"
fi
else
echo "$f" >> /home/www/playlists/."$playlist"
echo "FAILED: $f"
fi
# else
# echo "$f" >> /home/www/playlists/."$playlist"
# echo "OFFLINE: $f"
# fi
done
#
# ASK IF WE SHOULD REENABLE ALL KNOWN CHANNELS
#
echo ======= END OF PLAYLIST, READY TO START OVER =======
echo -n "Clear Mute List ('yes' to reenable all streams)?: "
read a
if [ "$a" = "yes" ]
then
mv /home/www/playlists/."$playlist" /home/www/playlists/."$playlist"-
cat /home/www/playlists/"$playlist" /home/www/playlists/."$playlist"- | sort -u > /home/www/playlists/."$playlist"
mv /home/www/playlists/."$playlist" /home/www/playlists/"$playlist"
echo "MUTE LIST CLEARED."
else
echo "MUTE LIST RETAINED."
fi
echo ======= 1 Infinite Loop =======
done
exitval=0
exit $exitval
# if the variable "file" contains a file's basename,
# we can substitute the existing extension to be ".ext" by:
# ${file%.*}.ext
syntax highlighted by Code2HTML, v. 0.9.1