recording audio from web-based audio player using ALSA loop device

16,289

Solution 1

Interesting question, a long time ago I was thinking about simple recording of digital audio and video, possible via some virtual audio and video drivers, but never got there.

I used your configuration file and had exactly same problem as you described. (I removed OSS compatibility drivers from ALSA to be sure, tested different kernels - did not seem to matter, and used Debian Wheezy)

$ alsaplayer -d front audio.mp3

$ mplayer -vo null -ao alsa:device=front video.mp4
AO: [alsa] 44100Hz 2ch s16le (2 bytes per sample)

$ mplayer -ao alsa:device=front audio.mp3
AO: [alsa] 44100Hz 2ch s16le (2 bytes per sample)

the above commands all play OK to speakers

$ arecord -f cd -D loop | aplay -f cd -D front
Recording WAVE 'stdin' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
Playing WAVE 'stdin' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo

now recording from loop and playing to front

$ alsaplayer audio.mp3
$ alsaplayer -d loop audio.mp3

$ mplayer -vo null video.mp4
$ mplayer -vo null -ao alsa:device=loop video.mp4
AO: [alsa] 48000Hz 2ch s16le (2 bytes per sample)

$ mplayer -ao alsa:device=loop audio.mp3
AO: [alsa] 48000Hz 2ch floatle (4 bytes per sample)

all sending audio to loop and playing to speakers OK

$ mplayer audio.mp3
AO: [alsa] 48000Hz 2ch floatle (4 bytes per sample)

but here the sound is broken - very distorted!!! Just playing to default device. Playback specified via loop worked!

After trying various changes I tested this modification of asound.conf

pcm.!default {
    type plug
    slave.pcm "loopout"
}

It solved the problem! When the default device is loopout it works. Trying arecord -f cd -D loopin | aplay -f cd -D front did not have any effect. Not sure how the loop works but this was able to capture the audio. Or a bug in ALSA? Are you using Debian? Does it work for you?

Notes to other suggestions to solve the problem:

To dump the network stream: I assume if the application does not want you to save data, the transfer would be encrypted (https ???). In case the player does not check the server certificate how do you capture the data? What is your favorite quick & easy method how to become man in the middle and capture the stream?

Pulseaudio: How do I get it running on Debian Wheezy? The Wiki says it just works. It did not.

/etc/init.d/pulseaudio start
[warn] PulseAudio configured for per-user sessions ... (warning).

How do I troubleshoot what is going on? (Tools, diag?)

Jack: I did not find any simple instructions how to install Jack. It seems quite complex. Does it assume Pulseaudio running? The documentation is confusing. Do you have a link for a nice quickstart (how to install and test to make sure it is working?)

Do you assume that most audio applications (like Fios Voicemail Java player) will be able to play to Pulseaudio or Jack and not send audio to ALSA?

Solution 2

Did you remember to "modprobe snd-aloop"? I've tried it and it works for me with your asound.conf on youtube, pandora, tunein, vonage, and this java player. Could be something specific to Fios, but I don't have Fios to test with. Can you find another publicly available site that also causes the problem?

Also, try recording to a file, then play it back:

arecord -f cd -D loop > recording.wav
aplay -f cd -D hw:0,0 recording.wav

Solution 3

Best idea

Firstly, reading your question I wouldn't do it like this. I would be snooping the network and trying to capture the stream. It's probably in a pretty predictable place that can be scripted out with a simple call to tshark. That's another question though.

Improvement over ALSA

While your method is a valid approach, I wouldn't use ALSA. ALSA is a hardware abstraction layer. I'd be using the sound daemon which is almost everywhere PulseAudio. That makes more sense. Create a null-sink.

$ pactl load-module module-null-sink sink_name=MySink

That command will return your module id. That's of no use to us.

Now just set the environmental variable PULSE_SINK. (sink_name in the above example is "MySink")

export PULSE_SINK=MySink;

Or, start a program with PULSE_SINK=MySink and that null sink will capture the stream.

Whenever you want to stream it to a file, simply run:

parec -v -d MySink.monitor | opusenc --raw --downmix-mono --bitrate 64 - out.opus

Low bitrate opus is the best bet for recording telephone conversations.

Footnotes:

  • You may also want to trim out the the silence before and after. Add sox to the stream for that. See man sox, search for vad.
  • we're using --downmix-mono on a stereo stream. You may very well want to experiment with sending the channels=1 argument to module-null-sink in the first step. Telephones are all mono.

Solution 4

After spending more than one hour trying to vainly setup the ALSA loopback device on Debian, the most effective and least time-consuming solution was to solder an actual device in 5 minutes.

Seriously, I recompiled the kernel to enable the ALSA loopback, I tweaked the /etc/asound.conf and ~/.asound.rc without results.

Loopback device

Share:
16,289

Related videos on Youtube

Tam Borine
Author by

Tam Borine

Updated on September 18, 2022

Comments

  • Tam Borine
    Tam Borine over 1 year

    I am trying to save voicemail messages from Verizon Fios phone in best quality possible. The voicemail messages are available online, but for playing only (Java based player), no saving. Officially, there is no supported way how to save original digital voice messages as files from Fios Digital Voice service (no paid service, no anything, no reason why).

    My only idea was to record digital data from the player while on the way to the soundcard. I tried Linux ALSA configuration with loop device.

    # cat /etc/asound.conf
    
    # default device
    pcm.!default {
        type plug
        slave.pcm "loop"
    }
    
    # output device
    pcm.loopout {
        type dmix
        ipc_key 328211
        slave.pcm "hw:Loopback,0,0"
    }
    
    # input device
    pcm.loopin {
        type dsnoop
        ipc_key 686592
        slave.pcm "hw:Loopback,1,0"
    }
    
    # duplex plug device
    pcm.loop {
        type plug
        slave {
          pcm {
             type asym
             playback.pcm "loopout"
             capture.pcm "loopin"
          }
        }
    }
    

    This seems to be working and records audio, for example when playing something on Youtube the audio output goes to the loop device (default audio output) and I can capture it (not sure how it exactly works, I tested both 44.1kHz and 48 Khz)

    arecord -f cd -D loop | aplay -f cd -D hw:0,0
    arecord -f dat -D loop | aplay -f dat -D hw:0,0
    

    But when I tried to capture Verizon Java audio player output, it is garbled and the length does not seem to match. I suspect it might be mono at 8 kHz and I tried different things, changing the frequency and formats, but nothing helped.

    Do you have any idea what is wrong here and how to record the messages? Is the problem in ALSA configuration? Or possibly kernel issue? (I am using 3.4.88). Any ideas would be very welcome.

    • Brandon Condrey
      Brandon Condrey almost 10 years
      Why are you using alsa, and not pulse? Even if you want to work under the browser level, that's a better option for you.
    • Tam Borine
      Tam Borine almost 10 years
      @Evan Carroll - so how would I solve my problem using pulse?
    • Brandon Condrey
      Brandon Condrey almost 10 years
      Vegeter: find my answer below. I'd highly suggest reevaluating your approach though.
  • Brandon Condrey
    Brandon Condrey almost 10 years
    For what it's worth, this is exactly the wrong reason to use JACK. JACK is low latency. pavucontrol will do the same thing you as QjackCtl, and you can always move pacmd move-sink-input.
  • theherk
    theherk almost 10 years
    Genuine curiosity on my part here; why is low latency a bad thing?
  • Brandon Condrey
    Brandon Condrey almost 10 years
    It's not. But, there are two distros that use Jack by default. Advocating someone change their sound daemon from what has become the de facto choice for no reason other than "lower latency" is a rather bad answer direction.
  • theherk
    theherk almost 10 years
    You make it sound like it is difficult to install a program that operates just fine alongside pulseaudio, pasuspender -- jackd. Nevertheless, if the poster is having quality issues, it may be valuable to try something so easy. Also, QjackCtl makes it very easy to adjust settings that give visible feedback on latency and xruns, which are commonly a cause of garbled audio.
  • Brandon Condrey
    Brandon Condrey almost 10 years
    And when the poster wonders why other things that are using the Pulse driver stop working because one program is playing to a null sink (in JACK rather than Pulse), then what?
  • Brandon Condrey
    Brandon Condrey almost 10 years
    Anyway, I don't have any problem at all with this answer if JACK was already installed. It seems unlikely that it's installed. It's unlikely that it's his choice of daemon. It's unlikely that he knows how to use it. The reason giving for switching the default is insufficient in my mind. Your method is more complex then the Pulse answer and it's doesn't even mention disabling the native daemon.
  • Tam Borine
    Tam Borine almost 10 years
    Works great! after changing the config file, I can now record from fios. Thanks a lot.
  • H. Rittich
    H. Rittich over 4 years
    When I try using this solution, the recorded output contains a lot of stutters and dropouts.