Using Multiple WebRTC getUserMedia Calls to Split Audio and Video

I am working on developing a simple application that makes use of WebRTC and the RecordRTC library to download the video and audio from a webcam, as well as a single frame of the video as a PNG file. However, I need to separate the video and audio into separate files so that they can be handled differently by other programs. The solution I am currently working on uses two calls of getUserMedia to make separate streams for the audio and video, but I am currently getting an error for the audio stream of An error occurred: TypeError: Cannot set property 'srcObject' of null.

Is it possible to have multiple tracks of WebRTC running simultaneously? And if not, is there a different way to handle WebRTC so that saving an audio file and video file separately is possible?

Thank you very much!

<html>
<head> 
   <meta charset = "utf-8">
</head>
<body>
   <div class="camera">
      <audio style="display: none;"></audio>
      <video id="video" autoplay controls></video><br>
      <button id="startbutton">Start Recording</button>
      <button id="stopbutton">Stop Recording</button>
      <button id="photobutton">Take photo</button>
   </div>
   <canvas id="canvas" style="display: none;"></canvas>
   <div class="output">
      <img id="photo">
   </div>
   <button id="downloadbutton" style="display: none;">Download All</button>

   <script src = "RecordRTC.js"></script>
   <!-- web streams API polyfill to support Firefox -->
   <script src="https://unpkg.com/@mattiasbuelens/web-streams-polyfill/dist/polyfill.min.js"></script>

   <!-- ../libs/DBML.js to fix video seeking issues -->
   <script src="https://www.webrtc-experiment.com/EBML.js"></script>

   <!-- for Edge/FF/Chrome/Opera/etc. getUserMedia support -->
   <script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
   <script src="https://www.webrtc-experiment.com/DetectRTC.js"> </script>
   <script>
      var startbutton = document.getElementById('startbutton');
      var stopbutton = document.getElementById('stopbutton');
      var video = document.getElementById('video');
      var audio = document.getElementById('audio');
      var canvas = document.getElementById('canvas');
      var photo = document.getElementById('photo');
      var photobutton = document.getElementById('photobutton');
      var downloadbutton = document.getElementById('downloadbutton');
      var videorecorder;
      var audiorecorder;
      var videoData;
      var audioData;
      var imageData;
      var width = 320;
      var height = 0;
      var streaming = false;

      stopbutton.disabled = true;

      function stopVideoRecordingCallback() {
         video.src = video.srcObject = null;
         video.muted = false;
         video.volume = 1;
         video.src = URL.createObjectURL(videorecorder.getBlob());
         videorecorder.stream.stop();
         videorecorder.destroy();
         videorecorder = null;
      }

      function stopAudioRecordingCallback() {
         audiorecorder.stop();
      }

      function clearphoto() {
         var context = canvas.getContext('2d');
         context.fillStyle = "#AAA";
         context.fillRect(0, 0, canvas.width, canvas.height);

         var data = canvas.toDataURL('image/png');
         photo.setAttribute('src', data);
      }
         
      function takepicture() {
         var context = canvas.getContext('2d');
         if (width && height) {
            canvas.width = width;
            canvas.height = height;
            context.drawImage(video, 0, 0, width, height);
            
            var data = canvas.toDataURL('image/png');
            photo.setAttribute('src', data);
         } else {
            clearphoto();
         }
      }

      startbutton.addEventListener('click', function() {
         navigator.mediaDevices.getUserMedia({video: true, audio: false}).then(function(stream) {
            video.srcObject = stream;
            videorecorder = RecordRTC(stream, {
               type: 'video'
            });
            videorecorder.startRecording();
            startbutton.disabled = true;
            videorecorder.stream = stream;
            document.getElementById('stopbutton').disabled = false;
            video.addEventListener('canplay', function(ev){
               if (!streaming) {
                  height = video.videoHeight / (video.videoWidth/width);
                  if (isNaN(height)) {
                     height = width / (4/3);
                  }
                  
                  video.setAttribute('width', width);
                  video.setAttribute('height', height);
                  canvas.setAttribute('width', width);
                  canvas.setAttribute('height', height);
                  streaming = true;
               }
            }, false);

            photobutton.addEventListener('click', function(ev){
               takepicture();
               ev.preventDefault();
            }, false);
            
            clearphoto();
         }).catch(function(err) {
            console.log("An error occurred: " + err);
         });

         navigator.mediaDevices.getUserMedia({video: false, audio: true}).then(function(mic) {
            audio.srcObject = mic;
            audiorecorder = RecordRTC(microphone, options);
            audiorecorder.startRecording();
         }).catch(function(err) {
            console.log("An error occurred: " + err);
         });
      });

      stopbutton.addEventListener('click', function(){
         this.disabled = true;
         videorecorder.stopRecording(stopVideoRecordingCallback);
         audiorecorder.stopRecording(stopAudioRecordingCallback);
         downloadbutton.style.display = block;
      });
   </script> 
</body> 
</html>

I think below code must be changed

from:

<audio style="display: none;"></audio>

to:

<audio id="audio" style="display: none;"></audio>

I think you forgot to add ‘id’ attribute to ‘audio’ element Sir.

Thank you very much; I feel a little silly for not noticing that earlier, but I very much appreciate your help!

1 Like