Now, you and your roommate can terrorize your other roommates with loud music. This script can play a MP3 file completely synchronously on two separate computers. Well, actually both computers need a good network connection and fast enough CPU. But it works for me, and maybe you'll like to try it out.
[download]
#!/bin/sh
#########
# SSNA: Synchonious Streaming Network Audio
#
# Functionality: Play one MP3 on two hosts synchroniously
# (It can play from fifo's too!)
#
# Requirements: 1) A fast network
# 2) The 'nc' (netcat) utility somewhere in your path
# 3) An MP3 file
# 4) Two hosts would be nice, although one will work too
# 5) sh, cut, cat, grep, ps, ifconfig, rm, mkdir, mknod, kill
#
# ChangeLog:
# v4: added --clean to clean up leftover netcat/cat sessions
# v3: protects against root running this script
# v2: accepts MP3-files with spaces in the name
# v1: first release
echo "SSNA - Synchonious Streaming Network Audio version 4"
echo "Copyright (C) 2001 S. Smeenk"
echo "This software is released under the GPL license"
echo
# Protection against root running this script...
IDGREP=`id | grep "uid=0"`
if [ "x$IDGREP" != "x" ]; then
echo " ! Never run this shellscript as root please..."
fi
if [ "x$1" == "x--clean" ]; then
echo " * Cleaning up leftover netcat & cat sessions as you requested..."
LGO=`ps ax | grep "nc -l -p 31331" | grep -v grep | cut -b 1-5`
LGT=`ps ax | grep "nc -l -p 31332" | grep -v grep | cut -b 1-5`
CGO=`ps ax | grep "cat /tmp/SSNA/host1" | grep -v grep | cut -b 1-5`
CGT=`ps ax | grep "cat /tmp/SSNA/host2" | grep -v grep | cut -b 1-5`
if [ "$LGO" ] || [ "$LGT" ] || [ "$CGO" ] || [ "$CGT" ]; then
echo " ? Found netcat or cat leftovers ..."
echo " Killing them..."
kill $LGO $LGT $CGO $CGT 2>&1 >/dev/null
fi
echo " - Done ..."
exit 0
fi
# Check the essential parameters...
if [ "x$1" == "x" ]; then
echo "Usage: ./SSNA.sh [ <mp3-file> | --clean ] [--one]"
echo -e "Example: ./SSNA.sh ~/music.mp3\n"
echo " --one: run test with one listening host on port 31331"
echo -e " --clean: clean up leftover netcat & cats after C-c'ing out\n";
exit 255
fi
# Check if the file is > 0 bytes, exists and is readable for you ...
if [ ! -s "$1" ] || [ ! -e "$1" ] || [ ! -r "$1" ]; then
echo "Access error to $1..."
#exit 255
fi
# Find out the local IP for display purposes only...
LOCALIP=`ifconfig eth0 | grep inet | sed -e 's/ /:/g' | cut -d':' -f13`
if [ "x$LOCALIP" == "x" ]; then
echo -e "Hmm.. Couldn't figure out your local IP address! (non-fatal)\n"
LOCALIP='thishost'
fi
# Try to create fifo's...
echo " * Creating temporary directory /tmp/SSNA, and fifo's ..."
if [ -e /tmp/SSNA ] && [ -d /tmp/SSNA ]; then
echo " ? Looks like there is leftover SSNA runs still here..."
echo " Trying to removing them ..."
set +e
rm -r /tmp/SSNA
set -e
fi
mkdir /tmp/SSNA
mknod /tmp/SSNA/host1 p
mknod /tmp/SSNA/host2 p
# Sets up the listening netcat services on ports 31331 and 31332
# Also kills leftover netcat sessions...
echo " * Setting up listening netcats in the background ..."
LGO=`ps ax | grep "nc -l -p 31331" | grep -v grep | cut -b 1-5`
LGT=`ps ax | grep "nc -l -p 31332" | grep -v grep | cut -b 1-5`
CGO=`ps ax | grep "cat /tmp/SSNA/host1" | grep -v grep | cut -b 1-5`
CGT=`ps ax | grep "cat /tmp/SSNA/host2" | grep -v grep | cut -b 1-5`
if [ "$LGO" ] || [ "$LGT" ] || [ "$CGO" ] || [ "$CGT" ]; then
echo " ? Found netcat or cat leftovers ..."
echo " Killing them..."
kill $LGO $LGT $CGO $CGT 2>&1 >/dev/null
fi
cat /tmp/SSNA/host1 | nc -l -p 31331 &
cat /tmp/SSNA/host2 | nc -l -p 31332 &
# Asks for user to start the connecting netcat | mpg123 -
echo " * Start listening on this host, ports 31331 and 31332!"
echo " For the first host: nc $LOCALIP 31331 | mpg123 -"
echo " For the second host: nc $LOCALIP 31332 | mpg123 -"
echo " + Press enter if the two hosts are connected..."
read
# Cats the file through tee which puts the data in fifo 1 and 2
# Unless user specified a ARGV[2], in that case only use fifo 1
echo " * Streaming the file... (you should hear audio now)"
if [ "x$2" != "x" ]; then
cat "$1" > /tmp/SSNA/host1
else
cat "$1" | tee /tmp/SSNA/host1 > /tmp/SSNA/host2
fi
# Kill the netcat & cat sessions and remove the temporary directory...
echo " * Cleaning up..."
LGO=`ps ax | grep "nc -l -p 31331" | grep -v grep | cut -b 1-5`
LGT=`ps ax | grep "nc -l -p 31332" | grep -v grep | cut -b 1-5`
CGO=`ps ax | grep "cat /tmp/SSNA/host1" | grep -v grep | cut -b 1-5`
CGT=`ps ax | grep "cat /tmp/SSNA/host2" | grep -v grep | cut -b 1-5`
if [ "$LGO" ] || [ "$LGT" ] || [ "$CGO" ] || [ "$CGT" ]; then
kill $LGO $LGT $CGO $CGT 2>&1 >/dev/null
fi
set +e
rm -r /tmp/SSNA
set -e
# And we are done...
echo " - Done..."