From 1e17e349fa9bed3ceb00eb952f5a861ceb8ce3fb Mon Sep 17 00:00:00 2001 From: nick-delirium Date: Mon, 26 May 2025 17:54:41 +0200 Subject: [PATCH] spot: rotate mime types --- spot/entrypoints/background.ts | 2 - spot/entrypoints/offscreen/main.js | 65 +++++++++++++++--------------- 2 files changed, 33 insertions(+), 34 deletions(-) diff --git a/spot/entrypoints/background.ts b/spot/entrypoints/background.ts index 08dd336e0..59c13b93d 100644 --- a/spot/entrypoints/background.ts +++ b/spot/entrypoints/background.ts @@ -959,7 +959,6 @@ export default defineBackground(() => { target: { tabId: tab.id }, files: ["/content-scripts/content.js"], }); - console.log("restoring content at", tab); } catch (e) { console.error("Error restoring content script", e); } @@ -1147,7 +1146,6 @@ export default defineBackground(() => { state: getRecState(), activeTabId: null, }; - console.log(tabId, "activation for new"); attachDebuggerToTab(tabId); void sendToActiveTab(msg); }); diff --git a/spot/entrypoints/offscreen/main.js b/spot/entrypoints/offscreen/main.js index 7bb7ca8a3..7160a757d 100644 --- a/spot/entrypoints/offscreen/main.js +++ b/spot/entrypoints/offscreen/main.js @@ -121,6 +121,7 @@ class ScreenRecorder { this.chunks = []; this.stream = null; this.audioTrack = null; + this.ignoreHandleStop = false; } init(settings) { @@ -161,45 +162,42 @@ class ScreenRecorder { mimeType: this.settings.mimeType, videoKeyFrameIntervalDuration: 1000, }; + const retryRecorder = (e) => { + if (!this.stream) { + console.error("MediaRecorder error + stream is not available.", e); + return; + } + this.ignoreHandleStop = true; + this.mRecorder.stop(); + + mimeTypeNum = (mimeTypeNum + 1) % mimeTypes.length; + const nextType = mimeTypes[mimeTypeNum]; + if (!nextType) { + console.error("No more mime types to try, stopping recording."); + this.isRecording = false; + this.clearDurationInterval(); + return; + } + console.error(`MediaRecorder error; retrying with ${nextType}`, e); + this.settings.mimeType = nextType; + mRecorderSettings.mimeType = nextType; + + this.mRecorder = new MediaRecorder(this.stream, mRecorderSettings); + this.mRecorder.ondataavailable = this._handleDataAvailable; + this.mRecorder.onstop = this._handleStop; + this.mRecorder.onerror = retryRecorder; + this.mRecorder.start(1000); + }; this.stream = combinedStream; this.mRecorder = new MediaRecorder(combinedStream, mRecorderSettings); this.mRecorder.ondataavailable = this._handleDataAvailable; this.mRecorder.onstop = this._handleStop; - this.mRecorder.onerror = (ev) => { - const nextType = mimeTypes[mimeTypeNum + 1]; - console.error( - `MediaRecorder error (depth = ${mimeTypeNum}; restarting with ${nextType}):`, - ev.error, - ); - this.settings.mimeType = nextType; - mRecorderSettings.mimeType = this.settings.mimeType; - mimeTypeNum++; - setTimeout(() => { - this.mRecorder = new MediaRecorder(combinedStream, mRecorderSettings); - this.mRecorder.ondataavailable = this._handleDataAvailable; - this.mRecorder.onstop = this._handleStop; - this.mRecorder.start(1000); - }, 1); - }; + this.mRecorder.onerror = retryRecorder; this.isRecording = true; this.mRecorder.start(1000); this.trackDuration(); - - let checks = 0; - const int = setInterval(() => { - if (checks < 50) { - checks++; - console.log( - this.settings.mimeType, - this.mRecorder.state, - this.mRecorder.stream.active, - ); - } else { - clearInterval(int); - } - }, 500); } stop() { @@ -349,10 +347,14 @@ class ScreenRecorder { }; recorded = false; + ignoreHandleStop = false; _handleStop = () => { + if (this.ignoreHandleStop) { + this.ignoreHandleStop = false; + return; + } const blob = new Blob(this.chunks, { type: this.settings.mimeType }); const url = URL.createObjectURL(blob); - console.log("offscreen: raw blob byteLength =", blob.size); this.videoBlob = blob; this.videoUrl = url; this.videoStream.getTracks().forEach((track) => track.stop()); @@ -426,7 +428,6 @@ browser.runtime.onMessage.addListener((message, _, respond) => { respond({ status: "empty" }); } convertBlobToBase64(data.blob).then(({ result, size }) => { - console.log("offscreen: base64 payload length:", size); if (size > hardLimit) { respond({ status: "parts" }); result.forEach((chunk, i) => {