What platforms are supported?
Connection to another screen, which uses WebRTC, has been tested successfully with desktop Chrome and Firefox. It has also been tested successfully on Android with Chrome and Firefox. All other OS and browser combinations are either untested or have been tested and are known to not work (yet).
Sharing screens, which uses the Screen Capture API, has been tested successfully with desktop Chrome and Firefox. No other OS/browser combinations have been shown to support screen capturing (yet), including all mobile configurations.
Do you have a configuration that works for either connection or sharing that is not mentioned above? Please open an issue to let us know.
Why isn't this working for me?
This service does not work for all users. The most common reasons for failure are:
- Unsupported platform - see the above FAQ entry. Many platforms do not yet support these features.
- Peer connectivity - due to network connectivity setups, not every set of browsers can make direct peer-to-peer connections. Ones that cannot, some estimate as many as 30%, require a relay server called a TURN server. Since this type of server relays all of the screen video, it can be expensive to run. This free service does not offer a TURN server or the option to set your own at this time, though those features may be available in the future.
- Third party outage - This uses a Google service for determining your IP and Gun.js's shared server to signal the peers. If either are down, this service will fail.
- Share expired - While the maximum amount of time a screen share may technically work is 72 hours, it can be as little as 24 hours. In the future the service may support longer term screen sharing.
Do you believe your platform and network setup should work but aren't? Please open an issue with browser logs to let us know.
How secure is this?
This service is reasonably secure, assuming your phrase is fairly unique or a strong password is used. All screen video is end-to-end encrypted and the mechanism used to find the peer is also encrypted. It is possible for another to see your screen if you are sharing it, and they have the password (or you aren't using one), and they guess the phrase. For more details on how the service works, see the high-level and low-level explanations of how the service works below.
Can I download and run this locally?
Sure! This service is a simple set of HTML and JS hosted on GitHub Pages. You can download a zip or tarball of the current site, extract it, and open myscreen.live-gh-pages/index.html
in your browser to get the same site experience.
If you want to hack on it and/or build it yourself, see the source code on GitHub.
Note, running locally is still the same site and still uses the external Google and Gun.js servers for IP determination and signaling respectively.
How does this work at a high level?
In general, this relies on Gun.js to signal WebRTC peers to share a video stream started via the Screen Capture API.
For the user sharing their screen:
- They go to the screen share page which has a default phrase and empty password.
- They optionally change the phrase and/or enter a password and click the share button.
- The browser then starts a Screen Capture session by asking the user what screen to share.
- Once chosen, the screen is set to a little preview video and, based on the phrase and password, the browser listens for requests by users wanting to connect.
- The user then sends the phrase and password to anyone they want to connect.
- Once a connection request happens, a WebRTC peer connection is created with and some data to send back to the connecting user on how to connect.
- The connection information is sent back to the connecting user who in turn sends back some connection info of their own.
- A WebRTC connection is then established with this information sending the screen video directly to the connecting user.
For the user connecting to another screen:
- Upon receiving the phrase and password to connect, the user enters it into the connection page.
- Based on the phrase and password, the browser sends a connection request to the listening screen sharing user.
- The browser receives the WebRTC connection info from the sharing user and starts a WebRTC connection.
- The browser sends its own connection info back to the screen sharing user and proceeds to connect to the peer.
- The browser receives the screen video feed from the sharing user and shows the video.
How does this work in more technical detail?
For the user sharing their screen:
- The user visits
#host
and is presented with a form requesting a phrase and optional password.
- The default phrase, which can be regenerated via a link, is in the form of "
<2-33> <random 1 of 128 adjectives> <random 1 of 128 animals> <random 1 of 64 verbs> <random 1 of 128 adverbs>
" which has ~4 billion possibilities as described in this post. Randomization is via browser crypto random via TweetNaCl.js.
- Once share is clicked, getDisplayMedia is called (with cursor visible and no audio) to request the user pick a screen or application feed to share which is set as the stream of the preview video element.
- A URL with the phrase in the URL fragment is provided to give to the connecting user (e.g. https://myscreen.live/#some-phrase).
- Then the page subscribes to 3 pubsub queues named after the phrase and the date. Specifically, it subscribes to queues named
base64(sha512(phrase + date))
for dates of yesterday, today, and tomorrow. Currently the pubsub implementation is Gun.js.
- Once a successfully decrypted offer request containing the other user's public key is received (see connecting part below for offer request encryption), a NaCl box key pair is generated for the signaling session. It is important to note that unrecognized messages/requests are simply ignored, there is no error response.
- A RTCPeerConnection is created with the only ICE server as the Google STUN server at
stun.l.google.com:19302
.
- The screen share media stream is added to the connection and an offer is created and set as the WebRTC local description.
- Once the candidates are collected, the offer is NaCl-box encrypted with the other user's public key and newly created private key. It is combined with the newly created public key and sent back awaiting an answer for up to one minute.
- Once a successfully decrypted answer is received for a pending answer (see connecting part below for answer encryption), it is set as the WebRTC remote description which begins the WebRTC handshake. It is important to note that unrecognized messages/answers are simply ignored, there is no error response.
- The connected peer counter is incremented and the video is shared until it is stopped or the peer disconnects.
For the user connecting to another screen:
- The URL with the phrase, e.g. https://myscreen.live/#some-phrase, is visited.
- The phrase is decoded and put in the connection form along with the password field to populate if required.
- Once connect is clicked, a NaCl box key pair is generated for the signaling session.
- A NaCl-secretbox-encrypted offer request is created containing the newly created public key. The encryption key is
sha512(date + phrase + password)
(may have empty password).
- The offer request is published to the signaling pubsub with the queue name
base64(sha512(phrase + date))
, and waits up to a minute for an offer.
- Upon successful decryption of an offer and other user's public key (see user sharing above for offer encryption), a RTCPeerConnection is created with the remote description set as the offer. It is important to note that unrecognized messages/offers are simply ignored, there is no error response.
- An answer is created and set as the local description of the connection which sets it as ready to begin the handshake.
- Once candidates have been gathered, the answer is NaCl-box encrypted with the session private key and other user's public key, and sent back.
- Once the WebRTC handshake is complete, the screen sharing video stream is set on the video and the video is adjusted to match the stream.
Why was this built?
Fun. And selfishly, once I saw these features are now deployed in stable browsers, I wanted to be able to quickly share a view of my screen without downloading anything. I also want easy remote screen control too, so I am building a downloadable tool for that (connection side won't need the tool, only the sharing side).
One of the goals is to make it easy to do just a quick screen share in situations such as family members with computer trouble or coworkers wanting to show something real quick.