Skip to content

Instantly share code, notes, and snippets.

@Ravenstine
Last active August 18, 2022 21:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Ravenstine/066880c9e1ae59870103644dc7a446f3 to your computer and use it in GitHub Desktop.
Save Ravenstine/066880c9e1ae59870103644dc7a446f3 to your computer and use it in GitHub Desktop.
Apple Screen Sharing w/ Sound

Apple Screen Sharing w/ Sound

macOS comes with a remote desktop application called "Screen Sharing." It is essentially a VNC server and client, and it works really well.

Unfortunately, VNC protocol doesn't include sound, hence neither Screen Sharing for macOS or other VNC clients.

I needed a way to be able to hear various application notifications through Screen Sharing, as well as watch videos or any media hosted by my company. To solve this problem, I came up with a way to support forwarding sound between two Macs.

The idea is to use BlackHole to capture output audio, record it with SoX, and pipe the output to the play command (from SoX) on the remote client. It's not an ideal setup, especially since there's about a second of lag, but it's sufficient if you need to remotely watch videos or hear sound for whatever reason.

Prerequisites

You will need to install the following on the remote machine:

  • BlackHole
  • SoX
  • switchaudio-osx

Homebrew is the easiest way to install these prerequisites. Once you've installed Homebrew, you can then run the following to get those prerequisites:

brew install sox
brew install blackhole-2ch
brew install switchaudio-osx

The client machine only needs SoX installed.

Setup

You must turn on SSH on the remote machine. This can either be done by going to System Preferences > Sharing and checking Remote Login.

Enabling remote login can also be done via the command line:

sudo systemsetup -setremotelogin on

It's a good idea to only allow it for a specific user and to make sure the password for the user is strong.

You will probably want to setup passwordless login with a private-public key pair. This not only makes things easier but it's also more secure.

If the client machine doesn't already have a key pair, runssh-keygen to do so.

Then copy the public key to the remote machine:

cat ~/.ssh/id_rsa.pub | ssh <user>@<remote host> 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys'

Now you will be able to SSH into the remote machine without the need to enter a password every time.

We are now ready to play audio from the remote machine on the client. Here's how we do it with a script:

ssh "<user name>"@<remote host> "\
  source ~/.zprofile && \
  killall -9 sox || true && \
  SwitchAudioSource -s \"BlackHole 2ch\" && \
  sox \
    -r 44100 \
    -t coreaudio \"BlackHole 2ch\" \
    -C 96.99 \
    -t mp3 - \
  " | play -t mp3 -

How this works is we're executing a command on the remote machine we first set the audio source to BlackHole, which is a virtual audio input/output device, then we use SoX to capture that audio again from BlackHole and pipe it out as compressed mp3 audio; on the client, the play command captures the piped output via SSH and immediately starts playing it.

If you save this script on the client, you can run it whenever you want to immediatley forward the audio.

You may want to play with the settings for SoX to adjust the quality and so-forth. I've yet to get the latency lower than what is in this example script.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment