Hey folks,
This is my first time writing a plugin and I’m pretty stumped, hoping someone can help.
I am loading a video stream, snapping a frame and saving the URL. On the first attempt, the URL always saves to the Bubble DB blank (and shows blank in the Bubble debugger) even though the Chrome console output is populated and correct. On the second attempt it saves the URL from the first picture capture and lags one behind from there on out. (The images themselves are uploading successfully, it is the URL not being saved properly.)
Here is the workflow where the URL is saved:
If I hit Step by Step in the Bubble debugger, I can see that the action “Create a new User-Images” has not executed yet, but somehow the workflow from the previous attempt is executing WITHOUT walking through the workflow. (It shows up visually on the page.) It’s like the previous attempt is getting stuck and not executing properly.
Below I show the first attempt creating a blank tile without walking through the steps. The blank tile is appearing because a new User-Images DB row has been created (without a URL). How is this possible when the app has not yet run the “Create a new User-Images” step?
I have cleared my browser cache and cookies to help rule out a local issue.
Hopefully someone is able to provide some insight, thanks in advance!!
Here is the JS code for my captureFrame function:
// Capture a single frame
instance.data.captureFrame = function() {
// Logging
console.log('Capture initiated');
// Check if the video is available for capture
if (instance.data.streamWebcam) {
let canvas = document.createElement('canvas');
let context2D = canvas.getContext('2d');
let video = document.querySelector('video');
let size = Math.min(video.videoWidth, video.videoHeight); // This will be the side length of the square
let startX = (video.videoWidth - size) / 2; // Starting X coordinate to center the captured frame
let startY = (video.videoHeight - size) / 2; // Starting Y coordinate to center the captured frame
canvas.width = size; // Set canvas width to square
canvas.height = size; // Set canvas height to square
context2D.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
let imageUrl = canvas.toDataURL('image/png');
let localReader = new FileReader(); // Create a new FileReader instance for each capture
localReader.readAsDataURL(dataURItoBlob(imageUrl));
localReader.onloadend = function() {
var filename = 'captured_frame_' + new Date().getTime() + '.png';
var base64data = localReader.result; // Use the localReader instance
var uploadData = base64data.substr(base64data.indexOf(',') + 1);
context.uploadContent(filename, uploadData, function(err, url) {
console.log("Uploaded URL:", url);
instance.publishState("Uploaded File URL", url); //return the url as an exposed state
instance.triggerEvent("Frame Captured"); //trigger an event for frame capture
});
}
}
}
// Helper function to convert data URI to blob
function dataURItoBlob(dataURI) {
var byteString = atob(dataURI.split(',')[1]);
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ab], { type: 'image/png' });
}