From b6567ade6674c245c69157361111e94250ab3b77 Mon Sep 17 00:00:00 2001 From: Becky Gilbert Date: Wed, 21 Feb 2024 15:06:49 -0800 Subject: [PATCH] Check video container/codec support and set in RecordRTC config (#365) Fixes problems with video playback and mime type errors when webm video is recorded in Chrome without specifying codecs. We now check the browser's support for specific webm/codec combinations and set this accordingly. --- app/mixins/video-record.js | 6 +++--- app/services/s3.js | 2 +- app/services/video-recorder.js | 26 ++++++++++++++++++++++---- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/app/mixins/video-record.js b/app/mixins/video-record.js index cc593266..37ceb8fd 100644 --- a/app/mixins/video-record.js +++ b/app/mixins/video-record.js @@ -421,9 +421,9 @@ export default Ember.Mixin.create({ vid.srcObject = null; vid.muted = false; vid.volume = 1; - this.get('recorder').get('recorder').getDataURL() - .then((dataURI) => { - vid.src = dataURI; + this.get('recorder').get('recorder').getBlob() + .then((blob) => { + vid.src = URL.createObjectURL(blob); vid.controls = true; }) .catch((err) => { diff --git a/app/services/s3.js b/app/services/s3.js index adbd8d46..94ff4c8b 100644 --- a/app/services/s3.js +++ b/app/services/s3.js @@ -31,7 +31,7 @@ class S3 { const createResponse = await this.s3.createMultipartUpload({ Bucket: this.env.bucket, Key: this.key, - ContentType: "video/mp4", + ContentType: "video/webm", }).promise(); this.uploadId = createResponse.UploadId; this.logRecordingEvent(`Connection established.`); diff --git a/app/services/video-recorder.js b/app/services/video-recorder.js index 15b6501c..cc29a709 100644 --- a/app/services/video-recorder.js +++ b/app/services/video-recorder.js @@ -95,6 +95,7 @@ const VideoRecorder = Ember.Object.extend({ recording: Ember.computed.alias('_recording').readOnly(), hasCreatedRecording: Ember.computed.alias('_hasCreatedRecording').readOnly(), micChecked: Ember.computed.alias('_micChecked'), + mimeType: Ember.computed.alias('_mimeType'), connected: false, uploadTimeout: null, // timer counting from attempt to stop until we should just resolve the stopPromise @@ -110,6 +111,7 @@ const VideoRecorder = Ember.Object.extend({ _hasCreatedRecording: false, _nWebcams: 0, _nMics: 0, + _mimeType: "video/webm", _minVolume: 0.1, // Volume required to pass mic check _micChecked: false, // Has the microphone ever exceeded minVolume? _recordPromise: null, @@ -187,6 +189,25 @@ const VideoRecorder = Ember.Object.extend({ $container.append($('
', { id: divId, class: origDivId })); $element.append($container); + // Check the browser's container/codec support, in order of our preference, and set accordingly for use in the recorder's config. + // "video/webm" (without codecs) is our fallback and works fine in FF, but it produces errors in Chrome. + // (If we specify the video codec in the recording config mimeType then we need to give an audio codec too. + // The browser will return true for isTypeSupported without audio codec, but it will cause a "not supported" error + // when trying to create a recorder with a specified video codec that can't also record audio). + const mime_types = [ + "video/webm;codecs=vp9,opus", + "video/webm;codecs=vp8,opus", + "video/webm;codecs=av1,opus" + ]; + let mime_type_index = 0; + while (mime_type_index < mime_types.length) { + if (MediaRecorder.isTypeSupported(mime_types[mime_type_index])) { + this.set('_mimeType', mime_types[mime_type_index]); + break; + } + mime_type_index++; + } + return new RSVP.Promise((resolve, reject) => { // eslint-disable-line no-unused-vars /* var pipeConfig = { @@ -211,10 +232,7 @@ const VideoRecorder = Ember.Object.extend({ var _this = this; const recordRtcConfig = { type: 'video', // audio, video, canvas, gif - mimeType: 'video/webm', - // video/webm;codecs=vp9 - // video/webm;codecs=vp8 - // video/webm;codecs=h264 + mimeType: _this._mimeType, //recorderType: MediaStreamRecorder, disableLogs: false, timeSlice: 1000,