MediaStream Recording

This shows how to record and replay a live video stream. After stopping the recording, you can save the recorded video as a file. You can combine this with WebRTC to record a video stream from a remote location.
RESETRUNFULL
<!DOCTYPE html><html><body>
   <video id="live" playsinline autoplay muted style="width:320px; height:240px;"></video>
   <video id="recorded" playsinline loop style="width:320px; height:240px;"></video>
   <button id="record" disabled>Start Recording</button>
   <button id="play" disabled>Play</button>
   <button id="download" disabled>Download</button>
   <script>
      let mediaRecorder, recordedBlobs, stream, buffer;
      const constraints = {
         audio: {echoCancellation: {exact: true}},
         video: true
      };
      navigator.mediaDevices.getUserMedia(constraints).then(strm=>{
         recordButton.disabled = false;
         document.querySelector('video#live').srcObject = stream = strm;
      });
      let recordedVideo = document.querySelector('#recorded');
      
      let recordButton = document.querySelector('#record');
      recordButton.onclick = () => {
         if (recordButton.textContent === 'Start Recording') {
            startRecording();
         } else {
            mediaRecorder.stop();
            recordButton.textContent = 'Start Recording';
            playButton.disabled = false;
            downloadButton.disabled = false;
         }
      };
      
      let playButton = document.querySelector('#play');
      playButton.onclick = () => {
         recordedVideo.src = URL.createObjectURL(buffer);
         recordedVideo.controls = true;
         recordedVideo.play();
      };
      
      let downloadButton = document.querySelector('#download');
      downloadButton.onclick = () => {
         const url = window.URL.createObjectURL(buffer);
         const a = document.createElement('a');
         a.style.display = 'none';
         a.href = url;
         a.download = 'test.webm';
         document.body.appendChild(a);
         a.click();
         setTimeout(() => {
            document.body.removeChild(a);
            window.URL.revokeObjectURL(url);
         }, 100);
      };
      
      function startRecording() {
         recordedBlobs = [];
         let options = {mimeType: 'video/webm;codecs=vp9,opus'};
         if (!MediaRecorder.isTypeSupported(options.mimeType)) {
            console.error(`${options.mimeType} is not supported`);
            options = {mimeType: 'video/webm;codecs=vp8,opus'};
            if (!MediaRecorder.isTypeSupported(options.mimeType)) {
               console.error(`${options.mimeType} is not supported`);
               options = {mimeType: 'video/webm'};
               if (!MediaRecorder.isTypeSupported(options.mimeType)) {
                  console.error(`${options.mimeType} is not supported`);
                  options = {mimeType: ''};
               }
            }
         }
         mediaRecorder = new MediaRecorder(stream, options);
         recordButton.textContent = 'Stop Recording';
         playButton.disabled = true;
         downloadButton.disabled = true;
         mediaRecorder.onstop = event => {
            console.log('Recorder stopped: ', event);
            console.log('Recorded Blobs: ', recordedBlobs);
            buffer = new Blob(recordedBlobs, {type: 'video/webm'});
         };
         mediaRecorder.ondataavailable = event =>{
           if (event.data && event.data.size > 0) recordedBlobs.push(event.data);
         }
         mediaRecorder.start();
      }
   </script>
</body></html>

To record an audio clip, do this instead:

buffer = new Blob(recordedBlobs, {type: 'audio/ogg; codecs=opus' });

with the rest of the code being identical. (use <audio> instead of <video>)