javascriptvideoframe-rateweb-mediarecorder

Record "raw" webcam stream at constant FPS and without canvas


I created a web (Vue.js) and desktop app (Tauri) that records my camera's video stream with getUserMedia. The camera is 4K resolution which is recognized as a webcam by CamLink. And finally for the recording part I use MediaRecorder. It would have been so beautiful if it were that simple...

Picture quality is really good but I quickly discovered that it didn't record at a consistent framerate. The videos are sometimes 29.042 fps, then 30.512 fps, etc. This makes a big problem for what I want to do later. When I open the videos in after effects it jerks.

I implemented @kaiido solution with the help of the canvas but I wanted to know if there was a solution to do it without the canvas like use only MediaRecorder since it degrades the performance of the app.

I don't want to manipulate the video. I want to have the best possible quality in a constant frame rate.


Solution

  • The frame rate should be specified on the input MediaStreamTrack, e.g in the call to getUserMedia(constraints).

    const constraints = {
      video: { frameRate: { exact: 30 } }
    };
    const stream = await navigator.mediaDevices.getUserMedia(constraints);
    

    Though a too restrictive constraint like that has good chances of not being supported, so you might prefer request an initial ideal value, and then try to force an exact one through MediaStreamTrack#applyConstraints().

    const [track] = stream.getVideoTracks();
    try {
      await track.applyConstraints(constraints);
    }
    catch(err) {
      // maybe try again with another value,
      // e.g the one from track.getSettings().frameRate
    }