Delay in Saving Captured Video Frame URL to Database

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 = function() {
	// Logging
	console.log('Capture initiated');

    // Check if the video is available for capture
	if ( {
		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.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' });

Good news, I found a solution! Create Object needed to be called from a workflow event separate from the button click.


1 Like