com.harryaskham.pulsecast · Swift · menu bar · ffmpeg · PulseAudio

pulsecast

A menu-bar app that joins a Mac audio device to a device on a PulseAudio server, such as PulseServer on a phone. Play the Mac's sound on the phone's speaker, or a remote source through the Mac's.

Two directions

A send cast and a receive cast pulsecast's two directions. A send cast captures a local input, such as a loopback device carrying the Mac's own audio, with ffmpeg, which resamples continuously to follow the remote clock, and pipes it into pacat, which plays it to a sink on the PulseAudio server. A receive cast runs parec against a remote source and pipes it into ffmpeg, which plays it through a local output. Each cast is two processes joined by a pipe, started through a login shell so Stop ends the whole pipeline. local inpute.g. a loopback device ffmpegaresample=async pacatplay remote sinkPulseAudio server remote sourcePulseAudio server parecrecord ffmpegaudiotoolbox out local outputspeakers pipe send receive pipe

A send cast captures a local input, for example a loopback device carrying the Mac's own audio, and plays it to a sink on the server. A receive cast captures a source on the server and plays it through a local output.

Each cast is two processes joined by a pipe, started through a login shell so they find ffmpeg and pacat wherever you installed them. Stop ends the whole pipeline at once. Casts live in ~/.config/pulsecast/config.yaml, which the Settings window edits.

Clean over a network

A Mac's capture clock and the remote server's clock drift apart, and a fixed-ratio pipeline eventually runs a buffer dry or over: a pop. pulsecast has ffmpeg resample continuously to follow the remote clock, and leaves out the low-delay input flags. If clicks remain, a cast's correction budget and latency can go up. A cast marked low-latency trades that safety for less delay.

# a send cast with the default settings
ffmpeg -f avfoundation -i ":<input>" \
    -af aresample=async=1000:min_hard_comp=0.100:first_pts=0 -ar 44100 -ac 2 -f s16le - \
  | pacat -p --server=<server> --rate=44100 --channels=2 --format=s16le --latency-msec=500