Skip to content

Commit

Permalink
Quality dropdown fix + improvement on longer recordings
Browse files Browse the repository at this point in the history
  • Loading branch information
alyssaxuu committed Feb 17, 2024
1 parent ae5cd3f commit a8881aa
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 146 deletions.
2 changes: 1 addition & 1 deletion build/background.bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/contentScript.bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/manifest.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"description":"__MSG_extDesc__","version":"3.1.7","manifest_version":3,"name":"__MSG_extName__","default_locale":"en","background":{"service_worker":"background.bundle.js"},"action":{"default_icon":"assets/img/icon-34.png"},"icons":{"128":"assets/img/icon-128.png"},"host_permissions":["<all_urls>"],"content_scripts":[{"matches":["<all_urls>"],"js":["contentScript.bundle.js"],"css":["assets/fonts/fonts.css"]}],"web_accessible_resources":[{"resources":["content.styles.css","blank.mp4","playground.html","editor.html","assets/*","setup.html","worker.js","vendor/*","recorder.html","recorderoffscreen.html","sandbox.html","wrapper.html","camera.html","permissions.html","region.html","waveform.html","playground.html","editorfallback.html","download.html","*"],"matches":["<all_urls>"]}],"oauth2":{"client_id":"560517327251-m7n1k3kddknu7s9s4ejvrs1bj91gutd7.apps.googleusercontent.com","scopes":["https://www.googleapis.com/auth/drive.file"]},"cross_origin_embedder_policy":{"value":"require-corp"},"cross_origin_opener_policy":{"value":"same-origin"},"content_security_policy":{"sandbox":"sandbox allow-scripts allow-modals allow-popups; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob:; object-src 'self';worker-src 'self' blob: ;","extension_pages":"script-src 'self' 'wasm-unsafe-eval'; object-src 'self'; media-src 'self' data: blob: *;"},"sandbox":{"pages":["editor.html"]},"commands":{"start-recording":{"suggested_key":{"default":"Alt+Shift+G"},"description":"Start recording"},"cancel-recording":{"suggested_key":{"default":"Alt+Shift+X"},"description":"Cancel recording"},"pause-recording":{"suggested_key":{"default":"Alt+Shift+M"},"description":"Pause/Resume recording"}},"permissions":["identity","activeTab","storage","unlimitedStorage","downloads","tabs","tabCapture","scripting"],"optional_permissions":["offscreen","desktopCapture","alarms"]}
{"description":"__MSG_extDesc__","version":"3.1.8","manifest_version":3,"name":"__MSG_extName__","default_locale":"en","background":{"service_worker":"background.bundle.js"},"action":{"default_icon":"assets/img/icon-34.png"},"icons":{"128":"assets/img/icon-128.png"},"host_permissions":["<all_urls>"],"content_scripts":[{"matches":["<all_urls>"],"js":["contentScript.bundle.js"],"css":["assets/fonts/fonts.css"]}],"web_accessible_resources":[{"resources":["content.styles.css","blank.mp4","playground.html","editor.html","assets/*","setup.html","worker.js","vendor/*","recorder.html","recorderoffscreen.html","sandbox.html","wrapper.html","camera.html","permissions.html","region.html","waveform.html","playground.html","editorfallback.html","download.html","*"],"matches":["<all_urls>"]}],"oauth2":{"client_id":"560517327251-m7n1k3kddknu7s9s4ejvrs1bj91gutd7.apps.googleusercontent.com","scopes":["https://www.googleapis.com/auth/drive.file"]},"cross_origin_embedder_policy":{"value":"require-corp"},"cross_origin_opener_policy":{"value":"same-origin"},"content_security_policy":{"sandbox":"sandbox allow-scripts allow-modals allow-popups; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob:; object-src 'self';worker-src 'self' blob: ;","extension_pages":"script-src 'self' 'wasm-unsafe-eval'; object-src 'self'; media-src 'self' data: blob: *;"},"sandbox":{"pages":["editor.html"]},"commands":{"start-recording":{"suggested_key":{"default":"Alt+Shift+G"},"description":"Start recording"},"cancel-recording":{"suggested_key":{"default":"Alt+Shift+X"},"description":"Cancel recording"},"pause-recording":{"suggested_key":{"default":"Alt+Shift+M"},"description":"Pause/Resume recording"}},"permissions":["identity","activeTab","storage","unlimitedStorage","downloads","tabs","tabCapture","scripting"],"optional_permissions":["offscreen","desktopCapture","alarms"]}
2 changes: 1 addition & 1 deletion build/sandbox.bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "__MSG_extName__",
"description": "__MSG_extDesc__",
"default_locale": "en",
"version": "3.1.7",
"version": "3.1.8",
"background": {
"service_worker": "background.bundle.js"
},
Expand Down
162 changes: 62 additions & 100 deletions src/pages/Background/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -365,123 +365,84 @@ function blobToBase64(blob) {
}

const handleChunks = async (chunks, override = false) => {
// Order chunks by timestamp
chunks.sort((a, b) => {
return a.timestamp - b.timestamp;
});
const { sandboxTab } = await chrome.storage.local.get(["sandboxTab"]);
const { sendingChunks, sandboxTab } = await chrome.storage.local.get([
"sendingChunks",
"sandboxTab",
]);

if (sendingChunks) {
console.warn("Chunks are already being sent, skipping...");
return;
}
await chrome.storage.local.set({ sendingChunks: true });

if (chunks.length === 0) {
sendMessageTab(sandboxTab, { type: "make-video-tab", override: override });
await chrome.storage.local.set({ sendingChunks: false });
sendMessageTab(sandboxTab, { type: "make-video-tab", override });
return;
}
let lastTimestamp = 0;
const batchSize = 10; // Number of chunks to send in each batch
const chunksCount = chunks.length;

// Order chunks by timestamp
chunks.sort((a, b) => a.timestamp - b.timestamp);

let currentIndex = 0;
const maxRetries = 5; // Maximum number of retry attempts per batch
const retryDelay = 1000; // Delay in milliseconds between retry attempts
const batchSize = 10;
const maxRetries = 3;
const retryDelay = 1000;
const chunksCount = chunks.length;

sendMessageTab(sandboxTab, {
type: "chunk-count",
count: chunksCount,
override: override,
override,
});

const sendNextBatch = async (retryCount = 0) => {
// Determine the range of chunks for the current batch
const start = currentIndex;
const end = Math.min(currentIndex + batchSize, chunksCount);

// Collect the chunks for the batch
const batch = [];
for (let i = start; i < end; i++) {
const chunk = chunks[i];
const chunkData = chunk.chunk;
const index = chunk.index;

// Check if timestamp is higher than lastTimestamp
if (chunk.timestamp < lastTimestamp) {
continue;
const sendBatch = async (batch, retryCount = 0) => {
try {
const response = await sendMessageTab(sandboxTab, {
type: "new-chunk-tab",
chunks: batch,
});
if (!response) {
throw new Error("No response or failed response from tab.");
}
lastTimestamp = chunk.timestamp;
try {
const base64 = await blobToBase64(chunkData);
if (base64) {
batch.push({ chunk: base64, index: index });
} else {
console.error("Error converting a chunk to Base64:", chunk);

// Handle the error by trying again
if (retryCount < maxRetries) {
setTimeout(() => {
sendNextBatch(retryCount + 1);
}, retryDelay);
} else {
console.error("Maximum retry attempts reached for this batch.");
}

return;
}
} catch (error) {
console.error("Error converting a chunk to Base64:", error);

// Handle the error by trying again
if (retryCount < maxRetries) {
setTimeout(() => {
sendNextBatch(retryCount + 1);
}, retryDelay);
} else {
console.error("Maximum retry attempts reached for this batch.");
}

return;
} catch (error) {
if (retryCount < maxRetries) {
console.error(
`Sending batch failed, retrying... Attempt ${retryCount + 1}`,
error
);
setTimeout(() => sendBatch(batch, retryCount + 1), retryDelay);
} else {
console.error("Maximum retry attempts reached for this batch.", error);
}
}
};

if (batch.length > 0) {
sendMessageTab(
sandboxTab,
{
type: "new-chunk-tab",
chunks: batch,
},
(response) => {
if (response) {
currentIndex += batchSize;
if (currentIndex < chunksCount) {
sendNextBatch();
} else {
chrome.tabs.sendMessage(sandboxTab, {
type: "make-video-tab",
override: override,
});
}
} else {
if (retryCount < maxRetries) {
setTimeout(() => {
sendNextBatch(retryCount + 1);
}, retryDelay);
} else {
console.error("Maximum retry attempts reached for this batch.");
}
}
while (currentIndex < chunksCount) {
const end = Math.min(currentIndex + batchSize, chunksCount);
const batch = await Promise.all(
chunks.slice(currentIndex, end).map(async (chunk, index) => {
try {
const base64 = await blobToBase64(chunk.chunk);
return { chunk: base64, index: currentIndex + index };
} catch (error) {
console.error("Error converting chunk to Base64", error);
return null;
}
);
} else {
currentIndex += batchSize;
if (currentIndex < chunksCount) {
sendNextBatch();
} else {
chrome.tabs.sendMessage(sandboxTab, {
type: "make-video-tab",
override: override,
});
}
})
);

// Filter out any failed conversions
const filteredBatch = batch.filter((chunk) => chunk !== null);
if (filteredBatch.length > 0) {
await sendBatch(filteredBatch);
}
};
currentIndex += batchSize;
}

// Start sending batches
sendNextBatch();
await chrome.storage.local.set({ sendingChunks: false });
sendMessageTab(sandboxTab, { type: "make-video-tab", override });
};

const sendChunks = async (override = false) => {
Expand Down Expand Up @@ -1448,6 +1409,7 @@ const handleSaveToDrive = async (sendResponse, request, fallback = false) => {
const desktopCapture = async (request) => {
const { backup } = await chrome.storage.local.get(["backup"]);
const { backupSetup } = await chrome.storage.local.get(["backupSetup"]);
chrome.storage.local.set({ sendingChunks: false });
if (backup) {
if (!backupSetup) {
localDirectoryStore.clear();
Expand Down
47 changes: 28 additions & 19 deletions src/pages/Background/modules/tabHelper.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,50 @@
const sendMessageTab = async (
tabId,
message,
responseCallback = false,
noTab = false
responseCallback = null,
noTab = null
) => {
if (tabId === null || message === null) return;
if (tabId === null || message === null)
return Promise.reject("Tab ID or message is null");

try {
const tab = await new Promise((resolve) => {
const tab = await new Promise((resolve, reject) => {
chrome.tabs.get(tabId, (tab) => {
resolve(tab);
if (chrome.runtime.lastError) {
reject(chrome.runtime.lastError.message);
} else {
resolve(tab);
}
});
});

// Check if tab is an internal chrome:// page
if (
(tab && tab.url && tab.url.startsWith("chrome://")) ||
!tab ||
!tab.url ||
tab.url.startsWith("chrome://") ||
tab.url.startsWith("chromewebstore.google.com") ||
tab.url.startsWith("chrome.google.com/webstore") ||
tab.url === "" ||
tab.url === "about:blank"
) {
return;
} else if (!tab || !tab.url) {
return;
return Promise.reject("Invalid tab URL");
}

if (tab && tab.id) {
if (responseCallback && typeof responseCallback === "function") {
chrome.tabs.sendMessage(tab.id, message, responseCallback);
} else {
chrome.tabs.sendMessage(tab.id, message);
}
} else if (noTab && typeof noTab === "function") {
return new Promise((resolve, reject) => {
chrome.tabs.sendMessage(tab.id, message, (response) => {
if (chrome.runtime.lastError) {
reject(chrome.runtime.lastError.message);
} else {
responseCallback ? responseCallback(response) : resolve(response);
}
});
});
} catch (error) {
console.error("Error sending message to tab:", error);
if (noTab && typeof noTab === "function") {
noTab();
}
} catch (error) {
// Tab doesn't exist or can't be accessed
return Promise.reject(error);
}
};

Expand Down
3 changes: 1 addition & 2 deletions src/pages/Content/context/ContentState.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -1049,8 +1049,7 @@ const ContentState = (props) => {
});
} else if (
(ram < 8 || width < 3840 || height < 2160) &&
(contentState.qualityValue === "4k" ||
contentState.qualityValue === "1080p")
contentState.qualityValue === "4k"
) {
setContentState((prevContentState) => ({
...prevContentState,
Expand Down
3 changes: 1 addition & 2 deletions src/pages/Content/popup/layout/SettingsMenu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ const SettingsMenu = (props) => {
});
} else if (
(ram < 8 || width < 3840 || height < 2160) &&
(contentState.qualityValue === "4k" ||
contentState.qualityValue === "1080p")
contentState.qualityValue === "4k"
) {
setContentState((prevContentState) => ({
...prevContentState,
Expand Down
48 changes: 30 additions & 18 deletions src/pages/Sandbox/context/ContentState.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -361,23 +361,37 @@ const ContentState = (props) => {
}, [contentState.chunkCount]);

const handleBatch = async (chunks, sendResponse) => {
for (const chunk of chunks) {
// Check if too many chunks have been received
if (contentStateRef.current.chunkIndex >= chunkCount.current) {
makeVideoTab(null, { override: true });
return;
}
// Process chunks with a promise to ensure all async operations are completed
await Promise.all(
chunks.map(async (chunk) => {
if (contentStateRef.current.chunkIndex >= chunkCount.current) {
console.warn("Too many chunks received");
// Handling for too many chunks
return Promise.resolve(); // Resolve early for this case
}

const chunkData = base64ToUint8Array(chunk.chunk);
videoChunks.current.push(chunkData);
setContentState((prevState) => ({
...prevState,
chunkIndex: prevState.chunkIndex + 1,
}));
}
sendResponse({ status: "ok" });
const chunkData = base64ToUint8Array(chunk.chunk);
videoChunks.current.push(chunkData);

// Assuming setContentState doesn't need to be awaited
setContentState((prevState) => ({
...prevState,
chunkIndex: prevState.chunkIndex + 1,
}));

return Promise.resolve(); // Resolve after processing each chunk
})
)
.then(() => {
// Only send response after all chunks are processed
sendResponse({ status: "ok" });
})
.catch((error) => {
console.error("Error processing batch", error);
// Handle error scenario, possibly notify sender of failure
});

return;
return true; // Keep the messaging channel open for the response
};

// Check Chrome version
Expand Down Expand Up @@ -420,9 +434,7 @@ const ContentState = (props) => {
override: message.override,
}));
} else if (message.type === "new-chunk-tab") {
handleBatch(message.chunks, sendResponse);

return true;
return handleBatch(message.chunks, sendResponse);
} else if (message.type === "make-video-tab") {
makeVideoTab(sendResponse, message);

Expand Down

0 comments on commit a8881aa

Please sign in to comment.