This content originally appeared on Modern Web Development with Chrome and was authored by Paul Kinlan
<p>You should be able to create and edit videos using just the web in the browser.
It should be possible to provide a user-interface akin to Screenflow that lets
you create an output video that combines multiple videos, images, and audio into
one video that can be uploaded to services like YouTube.</p>
<p>Following on from the my <a href="https://paul.kinlan.me/building-a-video-editor-on-the-web-with-the-web/">previous
post</a> that briefly describes
the requirements of the video editor, in this post I just wanted to quickly show
in a screencast how I built the web cam recorder, and also how how to build
a screencast recorder :)</p>
<p>It's all pretty neat and it uses the new <code>navigator.getDisplayMedia</code> API which
lets they user grant access to their screen contents. The code below is everything
that I used to create this video.</p>
<p>The video is very very raw, there are a lot of mistakes because at the moment
I can't edit the video :) my goal is that at the end of this project
I can create a good video end-to-end.</p>
<p><a href="https://glitch.com/edit/#!/screen-recorder-voice?path=script.js:1:0">Code for this
video</a>
<a href="https://screen-recorder-voice.glitch.me/">Demo</a></p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-javascript" data-lang="javascript">window.<span style="color:#a6e22e">onload</span> <span style="color:#f92672">=</span> () => {
<span style="color:#66d9ef">if</span>(<span style="color:#e6db74">'getDisplayMedia'</span> <span style="color:#66d9ef">in</span> <span style="color:#a6e22e">navigator</span>) <span style="color:#a6e22e">warning</span>.<span style="color:#a6e22e">style</span>.<span style="color:#a6e22e">display</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">'none'</span>;
<span style="color:#66d9ef">let</span> <span style="color:#a6e22e">blobs</span>;
<span style="color:#66d9ef">let</span> <span style="color:#a6e22e">blob</span>;
<span style="color:#66d9ef">let</span> <span style="color:#a6e22e">rec</span>;
<span style="color:#66d9ef">let</span> <span style="color:#a6e22e">stream</span>;
<span style="color:#66d9ef">let</span> <span style="color:#a6e22e">voiceStream</span>;
<span style="color:#66d9ef">let</span> <span style="color:#a6e22e">desktopStream</span>;
<span style="color:#a6e22e">captureBtn</span>.<span style="color:#a6e22e">onclick</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">async</span> () => {
<span style="color:#a6e22e">download</span>.<span style="color:#a6e22e">style</span>.<span style="color:#a6e22e">display</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">'none'</span>;
<span style="color:#a6e22e">desktopStream</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">await</span> <span style="color:#a6e22e">navigator</span>.<span style="color:#a6e22e">getDisplayMedia</span>({<span style="color:#a6e22e">video</span><span style="color:#f92672">:</span><span style="color:#66d9ef">true</span>});
<span style="color:#a6e22e">voiceStream</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">await</span> <span style="color:#a6e22e">navigator</span>.<span style="color:#a6e22e">mediaDevices</span>.<span style="color:#a6e22e">getUserMedia</span>({<span style="color:#a6e22e">video</span><span style="color:#f92672">:</span> <span style="color:#66d9ef">false</span>, <span style="color:#a6e22e">audio</span><span style="color:#f92672">:</span> <span style="color:#66d9ef">true</span>});
<span style="color:#66d9ef">let</span> <span style="color:#a6e22e">tracks</span> <span style="color:#f92672">=</span> [...<span style="color:#a6e22e">desktopStream</span>.<span style="color:#a6e22e">getTracks</span>(), ...<span style="color:#a6e22e">voiceStream</span>.<span style="color:#a6e22e">getAudioTracks</span>()]
<span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#e6db74">'Tracks to add to stream'</span>, <span style="color:#a6e22e">tracks</span>);
<span style="color:#a6e22e">stream</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> <span style="color:#a6e22e">MediaStream</span>(<span style="color:#a6e22e">tracks</span>);
<span style="color:#a6e22e">videoElement</span>.<span style="color:#a6e22e">srcObject</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">stream</span>;
<span style="color:#a6e22e">blobs</span> <span style="color:#f92672">=</span> [];
<span style="color:#a6e22e">rec</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> <span style="color:#a6e22e">MediaRecorder</span>(<span style="color:#a6e22e">stream</span>, {<span style="color:#a6e22e">mimeType</span><span style="color:#f92672">:</span> <span style="color:#e6db74">'video/webm; codecs=vp9,opus'</span>});
<span style="color:#a6e22e">rec</span>.<span style="color:#a6e22e">ondataavailable</span> <span style="color:#f92672">=</span> (<span style="color:#a6e22e">e</span>) => <span style="color:#a6e22e">blobs</span>.<span style="color:#a6e22e">push</span>(<span style="color:#a6e22e">e</span>.<span style="color:#a6e22e">data</span>);
<span style="color:#a6e22e">rec</span>.<span style="color:#a6e22e">onstop</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">async</span> () => {
<span style="color:#a6e22e">blob</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> <span style="color:#a6e22e">Blob</span>(<span style="color:#a6e22e">blobs</span>, {<span style="color:#a6e22e">type</span><span style="color:#f92672">:</span> <span style="color:#e6db74">'video/webm'</span>});
<span style="color:#66d9ef">let</span> <span style="color:#a6e22e">url</span> <span style="color:#f92672">=</span> window.<span style="color:#a6e22e">URL</span>.<span style="color:#a6e22e">createObjectURL</span>(<span style="color:#a6e22e">blob</span>);
<span style="color:#a6e22e">download</span>.<span style="color:#a6e22e">href</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">url</span>;
<span style="color:#a6e22e">download</span>.<span style="color:#a6e22e">download</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">'test.webm'</span>;
<span style="color:#a6e22e">download</span>.<span style="color:#a6e22e">style</span>.<span style="color:#a6e22e">display</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">'block'</span>;
};
<span style="color:#a6e22e">startBtn</span>.<span style="color:#a6e22e">disabled</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">false</span>;
<span style="color:#a6e22e">captureBtn</span>.<span style="color:#a6e22e">disabled</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
};
<span style="color:#a6e22e">startBtn</span>.<span style="color:#a6e22e">onclick</span> <span style="color:#f92672">=</span> () => {
<span style="color:#a6e22e">startBtn</span>.<span style="color:#a6e22e">disabled</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
<span style="color:#a6e22e">stopBtn</span>.<span style="color:#a6e22e">disabled</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">false</span>;
<span style="color:#a6e22e">rec</span>.<span style="color:#a6e22e">start</span>();
};
<span style="color:#a6e22e">stopBtn</span>.<span style="color:#a6e22e">onclick</span> <span style="color:#f92672">=</span> () => {
<span style="color:#a6e22e">captureBtn</span>.<span style="color:#a6e22e">disabled</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">false</span>;
<span style="color:#a6e22e">startBtn</span>.<span style="color:#a6e22e">disabled</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
<span style="color:#a6e22e">stopBtn</span>.<span style="color:#a6e22e">disabled</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
<span style="color:#a6e22e">rec</span>.<span style="color:#a6e22e">stop</span>();
<span style="color:#a6e22e">stream</span>.<span style="color:#a6e22e">getTracks</span>().<span style="color:#a6e22e">forEach</span>(<span style="color:#a6e22e">s</span>=><span style="color:#a6e22e">s</span>.<span style="color:#a6e22e">stop</span>())
<span style="color:#a6e22e">videoElement</span>.<span style="color:#a6e22e">srcObject</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">null</span>
<span style="color:#a6e22e">stream</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">null</span>;
};
};
</code></pre></div>
This content originally appeared on Modern Web Development with Chrome and was authored by Paul Kinlan