codeblog code is freedom — patching my itch

4/19/2009

recording from PulseAudio

Filed under: Blogging,Debian,General,Multimedia,Ubuntu — kees @ 11:42 am

Every PulseAudio “Sink” has a “Source” named “monitor”. This lets you attach to a given Sink and chain more stuff to it, for example, recording the audio that is playing through PulseAudio at any given moment. This is very handy for creating, for example, PubQuiz-style clips of songs, movies, etc.

Here is a script to find the monitor for the most recently added Sink, record from it, and shove it through “sox” to get a WAV instead of raw sound data (requires recent sox, Pulse, etc):

#!/bin/bash
WAV="$1"
if [ -z "$WAV" ]; then
    echo "Usage: $0 OUTPUT.WAV" >&2
    exit 1
fi
rm -f "$WAV"

# Get sink monitor:
MONITOR=$(pactl list | egrep -A2 '^(\*\*\* )?Source #' | \
    grep 'Name: .*\.monitor$' | awk '{print $NF}' | tail -n1)
echo "set-source-mute ${MONITOR} false" | pacmd >/dev/null

# Record it raw, and convert to a wav
echo "Recording to $WAV ..."
echo "Close this window to stop"
parec -d "$MONITOR" | sox -t raw -r 44k -sLb 16 -c 2 - "$WAV"

© 2009 – 2011, Kees Cook. This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License.
Creative Commons License

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Technorati
  • Identi.ca
  • Reddit
  • Twitter

19 Comments »

  1. Hehe: sox sox: Rate value `44k’ is not a positive number

    Full info here: http://paste.pocoo.org/show/113298/

    Comment by Vadim P. — 4/19/2009 @ 5:05 pm

  2. Right, you need a newer sox for that command line.

    Comment by kees — 4/19/2009 @ 8:14 pm

  3. Would you provide a link for an updated sox? The latest version in the Ubuntu repositories still causes this problem. Thanks.

    Comment by 3pipe — 4/20/2009 @ 1:50 am

  4. The sox from Ubuntu Jaunty (9.04) works for this example. If you can’t use sox, just record to the raw file, and import it manually into audacity or something to save it.

    Comment by kees — 4/20/2009 @ 7:17 am

  5. The GStreamer version :)

    $ gst-launch-0.10 pulsesrc device=$(pactl list | grep -A1 ‘^\*\*\* Source #’ | \
    grep ‘^Name: .*\.monitor$’ | cut -d” ” -f2 | tail -n1) \
    ! queue ! audio/x-raw-int,rate=44100,channels=2 \
    ! audioconvert ! lame vbr=4 vbr-quality=2 \
    ! filesink location=dump.mp3

    Comment by xuzo — 4/20/2009 @ 7:35 am

  6. Thanks xuzo! Your script worked great.

    Comment by Vadim P. — 4/20/2009 @ 3:07 pm

  7. Thanks for the quick and easy solution to ‘loop back’ recording. I like this variation, for outputting an ogg file:
    parec –format=s16le –device=”$MONITOR” | oggenc –raw –quiet –quality=4 -o $WAV -

    Comment by Ben B — 5/15/2009 @ 7:41 pm

  8. Excellent, thanks for that: works a treat!

    Comment by the_phoenix — 9/24/2009 @ 11:47 pm

  9. Thanks, works great!

    I replaced “44k” by “44100″. This avoids the SOX problem pointed out by vadim, kees and 3pipe and, at the same time, gets you 44.1khz files, not 44khz ones.

    (44.1khz is what you’d want for burning on CDs or converting to MP3)

    Comment by hacklschorsch — 10/26/2009 @ 4:39 am

  10. Update the script for more recent PulseAudio (as found in Karmic):
    http://outflux.net/software/pa-clone

    Comment by kees — 11/18/2009 @ 7:39 am

  11. Thanks so much. I just wasted a bunch of time trying to do this the wrong way and it is such a relief to have found your solution.

    Comment by Ben Smith — 1/14/2010 @ 8:24 am

  12. Thank you for this script !
    I added the ability to start when a sound occurs and to split in multiple files after 2s of silence. Just replace the line begining with “parec -d “$MONITOR” | sox…” with this one :
    parec -d “$MONITOR” | sox -t raw -r 44100 -sLb 16 -c 2 – “$WAV” silence 1 0.50 0.1% 1 2.0 0.1% : newfile : restart

    Comment by Youch — 8/15/2010 @ 7:17 am

  13. Can we do same thing with ffmpeg?

    Comment by Jahil — 8/17/2010 @ 11:53 pm

  14. pactl is a localised application so you should call it with LANG=C.

    Comment by josef — 10/10/2010 @ 2:11 am

  15. pactl found in Ubuntu 10.10 (Maverick) has slightly different output. Change lines 10 and 11 to:

    MONITOR=$(pactl list | grep -A2 ‘^\Source ‘ | \
    grep ‘Name: .*\.monitor$’ | cut -d” ” -f2)

    Comment by kaapstorm — 1/16/2011 @ 12:36 pm

  16. (Sorry about that. That regex should be “^Source”, not “^\Source”. The “\” will be ignored, so it doesn’t really matter. But I’m picky.)

    Comment by kaapstorm — 1/16/2011 @ 12:38 pm

  17. Very useful script.
    On my machine I had to insert these lines before recording:

    # Unmute monitor :
    echo “set-source-mute ${MONITOR} false” | pacmd

    Without them I was just recording silence..

    Comment by eric — 3/6/2011 @ 2:05 pm

  18. Thanks for the updates! I’ve adjusted the script for new “pactl list” output and added the unmuting.

    Comment by kees — 4/6/2011 @ 12:01 pm

  19. Just what I was looking for. I did make a slight change:

    #!/bin/bash
    WAV=”$1″
    if [ -z "$WAV" ]; then
    echo 1>&2 Usage: pa-rec wavefile
    exit 1
    fi
    rm -f “$WAV”
    # Get sink monitor:
    MONITORS=$(pactl list | egrep -A2 ‘^(\*\*\* )?Source #’ | grep ‘Name: .*\.monitor$’ | awk ‘{print $NF ” ” $NF }’)
    MONITOR=$(kdialog –menu “Select Monitor:” $MONITORS)
    echo “set-source-mute ${MONITOR} false” | pacmd >/dev/null
    # Record it raw, and convert to a wav
    echo “Recording $MONITOR to $WAV …”
    echo “^C to stop”
    parec -d $MONITOR | sox -t raw -r 44k -sLb 16 -c 2 – $WAV

    Obviously I use KDE.

    Comment by Al Williams — 7/12/2011 @ 12:24 pm

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress