muaz-khan / RecordRTC

RecordRTC is WebRTC JavaScript library for audio/video as well as screen activity recording. It supports Chrome, Firefox, Opera, Android, and Microsoft Edge. Platforms: Linux, Mac and Windows.
https://www.webrtc-experiment.com/RecordRTC/
MIT License
6.57k stars 1.76k forks source link

CPU usage increases after repeated recordings #304

Open sharkeatsbear opened 7 years ago

sharkeatsbear commented 7 years ago

Firstly thank you for the great work on RecordRTC.

I have an application which requires repeated recordings, and requires me to call initRecorder to sync the audio and video stream. I am using the StereoAudioRecorder and MediaStreamRecorder

videoRecorder.initRecorder(function() {
  audioRecorder.initRecorder(function() {
    // Both recorders are ready to record things accurately
    videoRecorder.startRecording();
    audioRecorder.startRecording();
  });
});

So on each new recording, I reset and delete the recorders and then re-initialise them with the function above.

Unfortunately at each new recording, my CPU usage starts to increase, and I believe it may have something with the webWorkers in StereoAudioRecorder.

var webWorker = processInWebWorker(mergeAudioBuffers);

So on every new recording I think it adds a new Worker to do audioProcessing.

I have tried hoisting the webWorker and added a terminate function to StereoAudioRecorder, which I call after I have stopped recording. So now webWorker sits with the recorders other variables

...
var recordingLength = 0;
var webWorker; 
this.terminateWebworker = function(){
  webWorker.terminate()
}

This didn't seem to help the CPU problem at all, and it may perhaps be a bug in the browser.

The other alternative I have tried is to initialise the recorders, and on any repeated recordings, I just use the same recorders and startRecording. However, The lengths of my repeated recorded audio and video files differ from the initial recordings, and for the application I would like to get these consistent. But this does not result in increased CPU usage.

So i'm wondering if there is a way to properly terminate the webWorkers so it doesn't increase CPU usage after multiple recordings?

Thanks for your help

muaz-khan commented 7 years ago

Is there any special reason behind preferring StereoAudioRecorder + WhammyRecorder over MediaStreamRecorder? (because MediaStreamRecorder uses MediaRecorder API, which can record all tracks+streams in single container)

BTW, did you call clearRecordedData before initiating a new recorder? main documentation ref

if (typeof videoRecorder.getInternalRecorder === 'function') {
    var internal = videoRecorder.getInternalRecorder();
    if (internal instanceof WhammyRecorder) {
        internal.clearRecordedData();
    }
}

if (typeof audioRecorder.getInternalRecorder === 'function') {
    var internal = audioRecorder.getInternalRecorder();
    if (internal instanceof StereoAudioRecorder) {
        internal.clearRecordedData();
    }
}

// now re-initate the recorders
videoRecorder.initRecorder(function() {
    audioRecorder.initRecorder(function() {
        // Both recorders are ready to record things accurately
        videoRecorder.startRecording();
        audioRecorder.startRecording();
    });
});
sharkeatsbear commented 7 years ago

My use case is that I would like to play a click track alongside a recorded music segment, so syncing the start times of the recorded video with a metronome is really crucial. Here I start recording at the same time as playing a metronome.

        this.videoRecorder.recordRTC.initRecorder(() => {
        this.audioRecorder.recordRTC.initRecorder(() => {
          this.bar8.play()
          this.audioRecorder.startRecording()
          this.videoRecorder.startRecording()
        })
      })

On repeated recordings I simply do this:

      this.bar8.play()
      this.audioRecorder.startRecording()
      this.videoRecorder.startRecording()

I then play back the recorded metronome with a separate metronome beat. This allows me to see if there is any difference between the start times of the recorded music segment and a regular click track. I make sure all resources are loaded and run:

        this.recordedSound.seek(delay)
        this.videoPlayer.currentTime(delay) 
        this.recordedSound.play()
        this.videoPlayer.play()
        this.bar8.play()

MediaStreamRecorder did not give me the duration of the recording until I played through the video fully. This meant I could not find the delay between the length of the bar8 audio and the recorded sample. Once I had found the duration from a full playback, I found that variation of the length of the video was also quite large, meaning I wouldn't get a full music clip.

However, StereoAudioRecorder gave me the duration back and also consistent results. The WhammyRecorder had some variation, but I was more concerned with get the audio syncing correctly. The delay varied between initial recordings and repeated recordings by 0.1 seconds.

I was also initially using the clearRecordedData() function, but changed to the reset function to see if it would make any difference, unfortunately neither removed the webWorkers.

So getting rid of the webworkers was to try and get consistent recordings as increased CPU usage was interfering with the delay that the recordings experienced. Perhaps i'm doing the entire thing in a very bad way, and would be welcome to any suggestions you may have, with regards to syncing the start time of the recorded metronome beat.

Again, thank you for the help.