Something I didn’t know was that you can record audio and video on the browser without any plugins. You can combine audio from the microphone, video from a canvas, dynamically generated content… you name it. Even recording a window or the entire screen and exporting it as a video.
The best way to learn is by practising and, quoting Soledad, “we need you to play with it, contribute and help us make it better”. By trying these new APIs out we let browser-vendors know that these tools are useful, and we can test and provide early feedback.
I had this idea about creating a ScreenFlow-like prototype. I would show my webcam in a corner of the screen and I would generate a video combining audio from the mic and the image from the screen.
Note: As of December 2016 this demo is only supported on Firefox. Chrome is not supported out of the box, needing an extension and lots of custom code (see this WebRTC experiment for more information. It will show your camera, but won’t record anything.
Let’s have a look at the most important code fragments. First of all, we define functions to request access to the different media sources:
Now, we execute them, one after the other one. I tried to execute both in parallel, believing that the browser would combine both requests in the permission dialog, but that didn’t work. So the idea is to request access to the webcam, insert a
<video> element with the media from the camera and then request access to the screen and record it.
Now, we finally need to call
this.recorder.stop() whenever we want to stop the recording, which will make the browser save the file automatically. In my example, I’m attaching a key event listener for the “escape” key.
In order to make this work you will need to whitelist the domain trying to record your screen. On Firefox,
localhost will work out of the box. If you want to publish the code somewhere else, like GitHub Pages, make sure you whitelist it.
On Firefox, navigate to
about:config and look for the key
media.getusermedia.screensharing.allowed_domains. Add your domain to the list and restart the browser. Then, when you are running the code, the user will be able to grant access for both the webcam and the screen.
It is unclear whether this will be how a user lets a site record their screen, but it is how this works at the moment.
The example code worked fine, but I wanted to take it a bit further. What if I wanted to use this “recording” functionality in more than one project? Also, given that the user has to whitelist a domain, we could serve the code from an
iframe on that domain, so we wouldn’t need to add more domains to the
The final version of the prototype is based now on a script that you include on a page. The script appends an
iframe, which executes the code we saw above and shows the output from the webcam at full size. Apart from the
iframe, it also binds several key event listeners to toggle the visibility and size of the
These are the keys you can press to perform some actions:
- Escape: finishes the recording and saves the file
- s: Switches the camera between full page and picture-in-picture
- a: Toggles the visibility of the camera
You can then include the script to any page to get this screen recording functionality. For instance, we can include
https://jmperezperez.com/screenflow/lib/embed.js on a codepen and record a screencast.
Keep in mind this is only a proof of concept and doesn’t have any real utility. If you are serious about recording a screencast, don’t use this hack :)
There are, of course, some limitations:
- The iframe with the camera is shown on top of the hosting page, but it will be hidden if we put some other window on top.
- If we navigate from the hosting page to somewhere else we will lose the recording. This can be workaround by having, in the hosting page, an iframe for the camera and another iframe for the page we are recording, in full screen
- If we click on the iframe with the camera, the key events will stop working because the hosting page doesn’t receive those. This can be solved sending
postMessages from the iframe to the hosting page.