[opensuse] A question for the BASH gurus
Hi all. I have a question regarding redirecting output from mplayer to ffmpeg
for the purpose of downloading and converting an audio stream on the fly.
It is possible to dump a real audio stream that cannot otherwise be downloaded
using the following:
mplayer -dumpstream -dumpfile <filename> -playlist "<url>"
This save the .rm file which can then be converted using:
ffmpeg -i
On Saturday 12 July 2008 09:12, Rodney Baker wrote:
Hi all. I have a question regarding redirecting output from mplayer to ffmpeg for the purpose of downloading and converting an audio stream on the fly.
It is possible to dump a real audio stream that cannot otherwise be downloaded using the following:
mplayer -dumpstream -dumpfile <filename> -playlist "<url>"
This save the .rm file which can then be converted using:
ffmpeg -i
. To reduce the time taken I have created a named pipe called 'streamdump'. In one Konsole window I start 'ffmpeg -i streamdump
', then in another start 'mplayer -dumpstream -dumpfile streamdump -playlist "<url>". What I would like to know is if there is a way to redirect the output from mplayer directly to ffmpeg without having to use the named pipe and two konsole sessions. So far nothing I've tried has worked. I'm guessing that there is likely to be more than one way to do this in a single step but I haven't been able to make it work yet.
You can simply detach the first (or both) commands by ending them with the ampersand ('&') character. When a program attempts to read from a named pipe with no writer, it will wait (as opposed to getting an end-of-file indication). Likewise when attempting to write to named pipe with no reader. So in fact you're free to launch the programs in either order and they'll synchronize as necessary. The same goes for flow control. Pipes will simply block the writer if it's faster than the reader at the other end of the pipe. So, something like this should work: % mplayer -dumpstream -dumpfile streamdump -playlist "URL" & % ffmpeg -i streamdump outputFile & Lastly, you can use the shell's built in "wait" command to cause it to wait for pending detached children to complete.
Any hints/pointers/suggestions/solutions gratefully received.
Thanks, Rodney.
Randall Schulz -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
On Sun, 13 Jul 2008 03:50:16 Randall R Schulz wrote:
[...snip...] You can simply detach the first (or both) commands by ending them with the ampersand ('&') character. When a program attempts to read from a named pipe with no writer, it will wait (as opposed to getting an end-of-file indication). Likewise when attempting to write to named pipe with no reader.
So in fact you're free to launch the programs in either order and they'll synchronize as necessary.
I did not realise that. Thanks for the tip.
The same goes for flow control. Pipes will simply block the writer if it's faster than the reader at the other end of the pipe.
So, something like this should work:
% mplayer -dumpstream -dumpfile streamdump -playlist "URL" & % ffmpeg -i streamdump outputFile &
Lastly, you can use the shell's built in "wait" command to cause it to wait for pending detached children to complete.
That's another one I've never tried...could be useful. Regards, -- =================================================== Rodney Baker VK5ZTV rodney.baker@iinet.net.au =================================================== How can you be in two places at once when you're not anywhere at all?
On Sun, 13 Jul 2008, Rodney Baker wrote:- <snip>
To reduce the time taken I have created a named pipe called 'streamdump'. In one Konsole window I start 'ffmpeg -i streamdump
', then in another start 'mplayer -dumpstream -dumpfile streamdump -playlist "<url>".
No need to have two consoles open. Using the named pipe you can use:
ffmpeg -i streamdump What I would like to know is if there is a way to redirect the output from
mplayer directly to ffmpeg without having to use the named pipe and two
konsole sessions. I don't know about not using the named pipe, but I don't think so. My
own tests trying to use dumpstream with an RM file on my drive and
sending it through an ordinary pipe failed. So far nothing I've tried has worked. I'm guessing that
there is likely to be more than one way to do this in a single step but I
haven't been able to make it work yet. A simple way would be to write a script to do it and just pass the URL
and output name to it. That way you can hide the various steps away and
only need to worry about the one command.
You might want to add in a bit more error-checking, but something like
this should do:
#!/bin/bash
URL="$1"
OUTPUT="$2"
# make sure there's an input and an output specified
#
[ -z "${URL}" -o -z "${OUTPUT}" ] && exit
# check for pre-existing output file and abort if present
#
[ -s "${OUTPUT}" ] && exit 1
# get a temporary filename
#
TEMPFILE=$(mktemp)
# and then use it to create named pipe
#
rm "${TEMPFILE}"
mkfifo "${TEMPFILE}"
# have ffmpeg read from the named pipe, write the mp3 as 160kbits, and
# background it. Redirect stdin so it doesn't try reading from the
# keyboard.
#
ffmpeg -f rm -i "${TEMPFILE}" -f mp3 -ab 160k "${OUTPUT}" http://www.distributed.net/ OGR-P2 @ ~100Mnodes RC5-72 @ ~15Mkeys
SUSE 10.1 32 | | openSUSE 10.3 32bit | openSUSE 11.0 32bit
| openSUSE 10.2 64bit | openSUSE 10.3 64bit | openSUSE 11.0 64bit
RISC OS 3.6 | TOS 4.02 | openSUSE 10.3 PPC | RISC OS 3.11
--
To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse+help@opensuse.org
On Sun, 13 Jul 2008 04:11:50 David Bolt wrote:
[...snip...] A simple way would be to write a script to do it and just pass the URL and output name to it. That way you can hide the various steps away and only need to worry about the one command.
You might want to add in a bit more error-checking, but something like this should do:
#!/bin/bash
URL="$1" OUTPUT="$2"
# make sure there's an input and an output specified # [ -z "${URL}" -o -z "${OUTPUT}" ] && exit
# check for pre-existing output file and abort if present # [ -s "${OUTPUT}" ] && exit 1
# get a temporary filename # TEMPFILE=$(mktemp)
# and then use it to create named pipe # rm "${TEMPFILE}" mkfifo "${TEMPFILE}"
# have ffmpeg read from the named pipe, write the mp3 as 160kbits, and # background it. Redirect stdin so it doesn't try reading from the # keyboard. # ffmpeg -f rm -i "${TEMPFILE}" -f mp3 -ab 160k "${OUTPUT}"
# have mplayer read the stream from the supplied URL and dump # it to the named pipe # mplayer -dumpstream -dumpfile "${TEMPFILE}" -playlist "${URL}"
# remove the pipe # rm "${TEMPFILE}"
# and quit # exit 0
Thanks, David. ffmpeg doesn't actually need the -f parameter to set the output format - it will auto-detect from the output file extension (which means that the script can automatically handle video as well as audio-only streams). That being said, I might play with adding a couple of optional command line parameters to specify output format details if needed. That could make it easy to download and convert to pal dvd format in one step :-). Regards, -- =================================================== Rodney Baker VK5ZTV rodney.baker@iinet.net.au =================================================== The rhino is a homely beast, For human eyes he's not a feast. Farewell, farewell, you old rhinoceros, I'll stare at something less prepoceros. -- Ogden Nash
On Tue, 22 Jul 2008, Rodney Baker wrote:-
On Sun, 13 Jul 2008 04:11:50 David Bolt wrote:
<Snip>
# get a temporary filename # TEMPFILE=$(mktemp)
# and then use it to create named pipe # rm "${TEMPFILE}" mkfifo "${TEMPFILE}"
<Snip>
ffmpeg -f rm -i "${TEMPFILE}" -f mp3 -ab 160k "${OUTPUT}"
<Snip>
Thanks, David. ffmpeg doesn't actually need the -f parameter to set the output format - it will auto-detect from the output file extension (which means that the script can automatically handle video as well as audio-only streams).
That only works when ffmpeg recognizes the extension. However, since the temporary pipe doesn't have an extension it will recognize[0], you need to specify the format.
That being said, I might play with adding a couple of optional command line parameters to specify output format details if needed. That could make it easy to download and convert to pal dvd format in one step :-).
That's easy: ffmpeg -i "<input filename>" -target pal-dvd -y "<output filename>" or ffmpeg -i "<input filename>" -target pal-dvd -acodec mp2 -y "<output filename>" depending on what you want the audio stream type to be. The default is to use an AC3 audio stream, which supports 5 and 7 audio channels, as opposed to mp2 which only supports stereo[1]. In both cases, the input streams are transcoded to an MPEG2 stream with the audio stream is up-sampled to 48KHz if required. Also, if required, the video is transcoded with a 25fps frame-rate and/or re-sized to 720x576. The same is true for making NTSC compatible MPEG2 streams, where you'd use either: ffmpeg -i "<input filename>" -target ntsc-dvd -y "<output filename>" or ffmpeg -i "<input filename>" -target ntsc-dvd -acodec mp2 -y "<output filename>" In this case, if it's required, the video is transcoded with a 29.97fps frame-rate and/or re-sized to 720x480. [0] It's created in the format /tmp/tmp.xxxxxxxxxx where the 'xxxxxxxxxx' is made up of the process ID and random alphanumeric characters [1] it also supports mono, but you won't be using that with a stream to be used on a DVD. Regards, David Bolt -- Team Acorn: http://www.distributed.net/ OGR-P2 @ ~100Mnodes RC5-72 @ ~15Mkeys SUSE 10.1 32 | | openSUSE 10.3 32bit | openSUSE 11.0 32bit | openSUSE 10.2 64bit | openSUSE 10.3 64bit | openSUSE 11.0 64bit RISC OS 3.6 | TOS 4.02 | openSUSE 10.3 PPC | RISC OS 3.11 -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
On Tue, 22 Jul 2008 09:04:04 David Bolt wrote:
<Snip>
Thanks, David. ffmpeg doesn't actually need the -f parameter to set the output format - it will auto-detect from the output file extension (which means that the script can automatically handle video as well as audio-only streams).
That only works when ffmpeg recognizes the extension. However, since the temporary pipe doesn't have an extension it will recognize[0], you need to specify the format.
My experience doing it manually has been that ffmpeg has detected the input file type from the stream header. I've not had to specify the input format to get it to work.
That being said, I might play with adding a couple of optional command line parameters to specify output format details if needed. That could make it easy to download and convert to pal dvd format in one step :-).
That's easy:
ffmpeg -i "<input filename>" -target pal-dvd -y "<output filename>"
or
ffmpeg -i "<input filename>" -target pal-dvd -acodec mp2 -y "<output filename>"
depending on what you want the audio stream type to be. The default is to use an AC3 audio stream, which supports 5 and 7 audio channels, as opposed to mp2 which only supports stereo[1].
Thanks - I'm aware of the command line parameters to do that. I just need to experiment with the best way to implement them as optional parameters to the script (in other words, if they're specified, use them, otherwise use sensible defaults). I know how to do that - I've written other scripts that do similar things for audio and video file format conversion (before I found SoundKonverter). Thanks again for your help; one of the best things about this list is how much one can learn if one is prepared to ask the right questions (and listen to the answers) ;-). Regards, -- =================================================== Rodney Baker VK5ZTV rodney.baker@iinet.net.au =================================================== Experience varies directly with equipment ruined.
----- Original Message -----
From: "Rodney Baker"
mplayer -dumpstream -dumpfile <fifo> -playlist "<url>" ffmpeg -i <fifo>
.
What I would like to know is if there is a way to redirect the output from mplayer directly to ffmpeg without having to use the named pipe and two konsole sessions. So far nothing I've tried has worked. I'm guessing that there is likely to be more than one way to do this in a single step but I haven't been able to make it work yet.
Because you have to do a little too much for a single command line in a web browser helper app definition, you might as well just put the commands into a script and run "myscript <url-in> <mp3-file-out>" streamrip: --- #!/bin/bash [ $# = 2 ] || { echo "usage: ${0##*/} <input playlist url> <output mp3 filename>" ; exit 1 ; } FIFO=/tmp/${0##*/}_${$}_fifo mkfifo $FIFO mplayer -dumpstream -dumpfile $FIFO -playlist "$1" & ffmpeg -i $FIFO "$2" rm $FIFO --- If you can't predict the output filename because this will be a browser helper, then you have to generate a generic one and rename it yourself later: "streamrip <url>" generates /shared/tunes/streamrip/<datetime>.mp3 #!/bin/bash [ $# = 1 ] || { echo "usage: ${0##*/} <input playlist url>" ; exit 1 ; } FIFO=/tmp/${SELF}_${$}_fifo mkfifo $FIFO mplayer -dumpstream -dumpfile $FIFO -playlist "$1" & ffmpeg -i $FIFO /shared/tunes/${0##*/}/`date +%Y%m%d%H%M%S`.mp3 rm $FIFO If mplayer -really-quiet is really quiet you could use /def/fd/1 or /dev/stdout or /dev/tty Some of those are somewhat portable to other *ix and old versions of linux, some only work on recent linux. #!/bin/bash [ $# = 1 ] || { echo "usage: ${0##*/} <input playlist url>" ; exit 1 ; } mplayer -really-quiet -dumpstream -dumpfile /dev/fd/1 -playlist "$1" | ffmpeg -i - /shared/tunes/${0##*/}/`date +%Y%m%d%H%M%S`.mp3 That is, do this test: mplayer -really-quiet -dumpstream -dumpfile /dev/null -playlist "$1" 2>/dev/null That captures the stream to /dev/null and stderr to /dev/null, and tells mplayer to be quiet, and allows stdout from mplayer to go to the screen as usual. If you see anything on the screen at all, any messages from mplayer, then you can't use a stdout|stdin pipeline simple as that. Unless there is some other option to mplayer to silence it. You will get junk inserted into your stream data. Enhancements: You might use Xdialog to prompt for an output mp3 filename instead of generating the generic one: #!/bin/bash [ $# = 1 ] || { echo "usage: ${0##*/} <input playlist url>" ; exit 1 ; } OUT=`Xdialog --title "Save stream $1 as: (output mp3 file name)" --fselect ~ 28 48 2>/dev/null` [ -z "$OUT" -o $? != 0 ] && exit mplayer -really-quiet -dumpstream -dumpfile /dev/fd/1 -playlist "$1" | ffmpeg -i - $OUT There is also kdialog, zenity, xmessage, gtkdialog, etc... for providing the gui input box. Not sure if any others have a file browser though, which is handier for this than a plain input box. Similarly, you could use *dialog to prompt for the input url if none was supplied on the command line, instead of merely printing an error message as I'm doing above. You might be able to get ID3 data from the stream and massage that into a filename, and fallback to a generic filename if no id3 data available, but that would take more scripting and more detailed knowledge of mplayer or some other utility. I wouldn't do any of this junk however. http://streamripper.sourceforge.net -- Brian K. White brian@aljex.com http://www.myspace.com/KEYofR +++++[>+++[>+++++>+++++++<<-]<-]>>+.>.+++++.+++++++.-.[>+<---]>++. filePro BBx Linux SCO FreeBSD #callahans Satriani Filk! -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
On Sun, 13 Jul 2008 06:31:49 Brian K. White wrote:
----- Original Message ----- From: "Rodney Baker"
To: Sent: Saturday, July 12, 2008 12:12 PM Subject: [opensuse] A question for the BASH gurus mplayer -dumpstream -dumpfile <fifo> -playlist "<url>" ffmpeg -i <fifo>
. What I would like to know is if there is a way to redirect the output from mplayer directly to ffmpeg without having to use the named pipe and two konsole sessions. So far nothing I've tried has worked. I'm guessing that there is likely to be more than one way to do this in a single step but I haven't been able to make it work yet.
Because you have to do a little too much for a single command line in a web browser helper app definition, you might as well just put the commands into a script and run "myscript <url-in> <mp3-file-out>" [...snip...] I wouldn't do any of this junk however.
Thanks Brian, David (Bolt) and Randall for your responses - all useful and informative. I've checked out streamripper but it doesn't seek to support .rm streams from my initial investigations. I have also been searching for a way to handle rtmp:// streams; some of these have links that are really obfuscated to make them hard to capture. For one particular site I've only found one solution that works, so far; unfortunately it is a Windoze app so I need to keep that XP partition on the laptop a little longer...:-(. Regards, -- =================================================== Rodney Baker VK5ZTV rodney.baker@iinet.net.au =================================================== Spark's Sixth Rule for Managers: If a subordinate asks you a pertinent question, look at him as if he had lost his senses. When he looks down, paraphrase the question back at him.
participants (4)
-
Brian K. White
-
David Bolt
-
Randall R Schulz
-
Rodney Baker