ffmpeg and AVFoundation

Dear Lazyweb, what magic incantations should I be using to make audio not drop out when doing:

ffmpeg -f avfoundation -i ":iShowU Audio Capture" -acodec libmp3lame -ab 128k -f mp3 -

I had been using Nicecast to capture and stream audio for approximately a thousand years, but they dropped support for that a couple years ago, and I'm finally being dragged into the future. They recommend replacing it with their other product, Audio Hijack, but Audio Hijack has no automation support (not even basic AppleScript) so it's useless to me. You can't even switch input sources from a script. (And yeah, I confirmed this with tech support.)

So we're back to ffmpeg. The hieroglyphics above work, mostly, but every few minutes the audio drops out for several seconds (with no error message printed) and it also, surprisingly, seems to get extra wonky whenever two audio sources are playing at once (e.g. when jwztv is doing a crossfade between two videos).

You can give a listen to the fuckery I am experiencing right now if you tune in to the DNA audio webcast at any time that the video webcast is showing music videos, e.g. right now and most mornings and afternoons.

Audio is clean in the OBS-encoded MP4 stream, so it's not a problem with the device itself.

Other suggestions on how to extract continuous 128kbps MP3 data from an arbitrary macOS audio device (to stdout or to a local icecast server) will also be entertained.

Update: I also tried "-b:a" in case that's not an exact synonym for "-ab", and tried having ffmpeg write directly to the Icecast server with:
-f mp3 -content_type audio/mpeg "icecast://source:PASS@HOST:8000/MOUNTPOINT"
and it has the same problems.


Tags: , , , , , ,

20 Responses:

  1. This is also another world of pain but should you feel with enough lust for self immolation to try GStreamer I can give you a hand with that.

    • k3ninho says:

      This smells like a buffering and context switching type of performance issue and then you'd want to know if it's macOS or ffmpeg itself. A little bit of lmgtfy.com magic found items in ffmpeg's trac which include 4437 and 4513 which are five years old and recently identified as still a problem -- with only a suggested but unproven fix that you have wide QUEUE_SIZE values (up to 400 from 4) which suggests that ffmpeg is allocating and destroying instead of allocating once and re-using in ring buffer pattern.

      It might not be ffmpeg, it might be macOS kernel having expensive context switching or terrible overheads for reading from devices -- and Jamie's going to hate the suggestion of a new media framework or a new OS kernel to fix this, right?


  2. Alias Cummins says:

    Not sure if this is the same issue but this has been raised on the ffmpeg trac here:
    and here:
    Looks like it's a known bug and it's still open, good news is there seems to be a patch in the works?

    • jwz says:

      Well, I tried applying this patch against ffmpeg git head, and it doesn't apply. Since it's five years old, I guess that isn't too surprising.

      If anyone has instructions for building a patched ffmpeg that is more likely to work than the released version, I'd love to hear it.

  3. Alias Cummins says:

    You might also like to try DarkIce:

    • jwz says:

      Well, it's in MacPorts, so that's promising. But I can't find any documentation about how to specify a macOS input device. Or even anyone else asking this question.

    • jwz says:

      The DarkIce author wrote back (and, incidentally, is a dick) and said "no, CoreAudio support doesn't work, you can use JackAudio." But as far as I can tell JackAudio doesn't work on macOS either. I'd ask them to confirm, but I can't find their email. Jack appears to be yet another abstraction layer that does the same thing as iShowU and Audio Hijack, because you can never have enough of those.

      • Alias Cummins says:

        Well, I'm guessing you've already seen this but there are OSX binaries for download here:

        As I understand it, jackaudio connects apps directly to the system drivers, so presumably circumvents CodeAudio? I've used it on mac before and it seems pretty stable, also popular with the OS live performance types, presumably because it's good with low latency stuff. Your mileage may vary though.

  4. Not Frank says:

    The fact it gets worse when doing cross-fade makes me think it's the issues others have highlighted above, but one question: do the dropouts last roughly 5s per minute of playback? If so, I'd be suspicious that it's getting in an audio sample rate of 44.1 kHz and assuming it's 48kHz.

    • jwz says:

      Maaaaaaaybe? However I don't see any way to tell ffmpeg what the sample rate of the input device is. Putting -ar 44100 before -f or -i gets "Option sample_rate not found." And putting it after affects the output encoding, not the input.

      Explicitly setting the output rate to either 44100 or 48000 doesn't seem to fix it, but I guess that would be expected if it was confused about what the input rate actually was.

  5. thielges says:

    Came here just to say I appreciate that I’m not the only one who uses the term hieroglyphs for incomprehensible code shorthand. Usually I’m referring to the two character bullshittery like $?, &*, or $! that appears in Perl or Cshell. Had I designed those languages those would be replaced with longer but descriptive string identifiers. Or have both: appeal to the keystroke rationers as well as the rational.

    And yeah, I’m the guy who codes redundant expression parenthesis because I can’t be bothered to memorize the operator precedence of all of the languages I wade through every week.

    • Zygo says:

      Had you designed those languages, you would have had to contend with issues like "64K is really quite a large amount of memory isn't it?" and "it takes multiple seconds to edit long variable names over crappy telnet connections". It also frees up the namespace for all alphanumeric identifiers, which is refreshing compared to certain other languages.

      Perl came along almost a decade later, and did give the variables long names that nobody ever uses.

    • No one ever uses them, but using the English module allows you to use longhand variable names. https://metacpan.org/pod/distribution/perl/pod/perlvar.pod

      • thielges says:

        Thanks. If I still authored anything in Perl these days that module would help. Today my Infrequent Perl experience is mostly reverse engineering to patch problems. So maybe I just need They Live glasses to translate the hieroglyphics.

        I’m not totally opposed to hieroglyphics: They’re fine used in condensed declarative languages like regexp. Or APL because the special symbols look so mysterious.

  6. Seamus says:

    OT: Am I going crazy or did I notice some fancy rendering of text entering from the bottom of the screen view today?

  7. mike says:

    You said you're using OBS and are happy with it; did you try hooking it up directly to icecast? The process for doing so seems unnecessarily convoluted, of course, but if it works…

    • jwz says:

      I saw that, but it precludes also saving the streamed video to .TS files, which is something I need.

  • Previously