How to Screen Share from Windows to Mac Over LAN Using GStreamer and WebRTC

Share

Screen sharing between a Windows PC and a Mac was never easy because of the differences in protocols: Windows uses Miracast for screen sharing, and Apple uses its proprietary AirPlay protocol. This got me thinking, what if I want to quickly display something from my Windows PC on my Mac, only by utilizing the flexible GStreamer framework? I have tried it all, streaming over RTP, raw TCP, using modern codecs like H.265 and AV1, but there is however one solution which seemed the most universal, applicable and supported to me: using WebRTC with H.264 encoding. As it turns out, it is easier than I thought!

Why use WebRTC on a local network?

It would be an understatement if I said that WebRTC would be an odd choice for this use case. It is however very important to understand the main benefits of choosing WebRTC over something like RTP direct connections:

  • WebRTC is encrypted by default. Well, the signalling server technically still runs on non-secure websockets but the data transfer (video/audio) still always encrypts thanks to DTLS-SRTP.
  • No need to enter a peer's IP address: because we are using a signalling server, all peers are connected through a peer ID, and the signalling server does the rest for you.
  • WebRTC was purpose-made for video/audio streaming, many things you have to wire together when using raw TCP for example are already built-in.
💡
About the signalling server running in non-secure mode: yes, while session hijacking and tampering is still a risk, this will result in a failed transfer between the two designated peers which means that the media transfer drops out when a bad actor intervenes. If this is an issue for you: run the signalling server in secure mode with an SSL certificate.

Setting up GStreamer on Mac

For Windows, setting up GStreamer is as simple as running the installer. For Mac though, you need to have the Brew package manager installed. Then, run the following command to installer GStreamer on your Mac:

brew install gstreamer libnice-gstreamer

This will install the necessary tools to run GStreamer and a signalling server on your Apple computer. The signalling server is responsible for guiding the transport between the two types of peers: consumers and producers. You can run this on your Mac with this command:

gst-webrtc-signalling-server --port 8443

Running the pipelines on your computers

Now it's time for some action. This is the last part of this guide, and shows you how the audio/video transfer between your computers work.

To run the pipeline on your Windows PC, run this command:

gst-launch-1.0 -e ^
  webrtcsink name=ws signaller::uri="ws://<MAC_IP>:8443" video-caps="video/x-h264" ^
  d3d11screencapturesrc show-cursor=true ! queue ! d3d11convert ! d3d11download ! videoscale ! video/x-raw,height=1080 ! videoconvert ! ws. ^
  wasapi2src loopback=true ! audioconvert ! audioresample ! ws.

Make sure to replace MAC_IP with the IP address of your Mac. If everything went right, a counter should start. This means that your Windows computer has now started producing, and the signalling server should indicate that so while switching to your Mac you should see a peer ID in the output of the signalling server. Copy this ID and use it for the next command which you should run on your Mac:

gst-launch-1.0 -e \
  webrtcsrc signaller::uri="ws://127.0.0.1:8443" signaller::producer-peer-id=<PEER_ID_HERE> name=src \
  src. ! queue ! videoconvert ! osxvideosink sync=true \
  src. ! queue ! audioconvert ! audioresample ! osxaudiosink sync=true

As soon as you hit enter, a new window appears with the contents of your Windows PC screen! This is how easy it is to screen share by using WebRTC and GStreamer.