On Fri, Oct 27, 2006 at 11:12:08AM +0200, Jan Stary wrote:
> I have this little sh script which saves an ogg audio stream,
> streamed by an internet radio. It's short enough to quote it:
>
>
> --- cut --
>
> #!/bin/sh
>
> # $1 is length in seconds, $2 is the output filename.
>
> # The stream itself is prefixed by a HTTP header, which needs to be
> # trimmed off up to (and not including) the ^OggS
>
> # HTTP/1.0 200 OK
>
> # Content-Type: application/ogg
>
> # icy-br:128
>
> # icy-description:European-style cultural station
>
> # icy-genre:classical
>
> # icy-name:CRo3 - Vltava
>
> # icy-pub:1
>
> # Server: Icecast 2.2.0
>
> #
>
> # OggS......
>
> if test $# -lt 2 ; then
> echo "usage: $0 length output" 2>&1
> exit 1
> fi
>
> NC=`which nc` 2>/dev/null
> test -x $NC || exit 1
>
> HOST="amp1.cesnet.cz"
> FILE="cro3.ogg"
> PORT="8000"
>
> LENGTH="$1"
> OUTPUT="$2"
> STREAM="/tmp/vltava.$$"
>
> test -e $OUTPUT && { echo "$OUTPUT already exists" >&2 ; exit 1 ; }
> mkfifo $STREAM || { echo "Cannot create output stream $STREAM" >&2; exit 1; }
>
> sed -n -e '/^OggS/,$ p' < $STREAM > $OUTPUT &
> { echo "GET /$FILE HTTP/1.0" ; echo ; } \
> | $NC $HOST $PORT > $STREAM &
>
> PID=$! && sleep $LENGTH && kill $PID
> rm -f $STREAM
>
> echo "Recorded $LENGTH seconds of http://$HOST:$PORT/$FILE"
> echo "into $OUTPUT"
>
> --- cut --
>
>
> The idea is that the stream is just dumped by nc(1) to a fifo,
> from which a sed one-liner copies everything starting with the
> ^OggS header (so that we trim off the HTTP header).
>
>
> I run this script from cron, obviously, as in
>
> 05 00 * * 7 $HOME/bin/vltava 5100 $HOME/vltava/`date
> +\%Y\%m\%d`-jazzclub.ogg
>
>
> Now, *sometimes* (I know) the script results in cron saying
>
> /home/hans/bin/vltava[43]: kill: 15062: No such process
> Recorded 5100 seconds of http://amp1.cesnet.cz:8000/cro3.ogg
> into /home/hans/vltava/20061024-jazzclub.ogg
>
> *Usually* (I know) it finishes OK, and the *ogg is a valid ogg stream.
> In this failing case, it *also* is a valid ogg stream, but much
> shorter than usual.
>
> So I suppose the background nc dies before I try to kill it myself
> (that is, after sleeping for $LENGTH seconds).
>
> One reason for this to happen is that the ogg being streamed out just
> finishes before $LENGTH (a special case being it returns immediately,
> possibly getting a HTTP error and an immediate EOF. But I doubt that
> - it's a continuously streamed radio station). Or the running nc(1)
> loses connection?
>
> Or maybe the inner structure of live-streamed OGG's is such that the
> (in fact) HTTP response is EOFed when one show finishes and another
> starts?
>
> Or, obviously, my script is somehow wrong - any hints?
> Sorry if this is trivial.
Hi Jan,
I would suspect not the script but the inner workings of HTTP protocol
instead. Your script seems fine; moreover it is simple and also working
reliably under most situations as you testify.
It will be hard to predict what goes wrong unless we have some statistics or
data. For instance, how often does this occur? And by what amount does it fall
short? Let us assume the radio station is playing 24 / 7.
In which case we need to test it and obtain enuf stats.
Not to say that stats mean anything but I find them very good for debugging.
Since I don't have the luxury of data, let me make a few guesses.
a) There are several situations in which the TCP connection can get
terminated, or cause a buffer underrun which might affect streaming
b) Your network card/kernel buffers might overflow
There are many other possibilities.
Could you get back with some test statistics please?
regards,
Girish
--
Be different. conform.