Utilize video frames to create a dynamic canvas background in JavaScript

I want to use the first frame of a video as the background for a canvas, but I've been struggling with it. I can set a background and extract a frame from a video, but I can't seem to make that frame the background. It seems like I need a URL for the frame in order to set it as the background using CSS. For that, I believe I need a blob on which I can call createObjectURL() (although I am aware that this method may be deprecated).

Here is some code:

    <!DOCTYPE html>
<html lang="en">
<canvas id="back" style="background-image: url('path/to/.png')";></canvas>
<input type="file" accept="video/*" />


<script>

  document.querySelector('input').addEventListener('change', extractFrame, false);

  var canvas = document.getElementById('back');
  var context = canvas.getContext('2d');
  var imageObj = new Image();
  var image;
  imageObj.onload = function() {
          var height = imageObj.height;
          var width = imageObj.width;
          canvas.height = height;
          canvas.width = width;
          context.drawImage(imageObj, 0, 0, back.width, back.height);
  };
  imageObj.src = "path/to/.png";



  var draw_canvas = document.getElementById('back');
  var draw_context = draw_canvas.getContext('2d');
  var corners = [];
  draw_canvas.addEventListener('mousedown',startDrawing,false);

  function startDrawing(e){
    corners.length=0;
    corners.push([e.layerX, e.layerY]);
    corners.push([e.layerX+1, e.layerY+1]);
    draw_canvas.addEventListener('mousemove', updateCorners,false);
    draw_canvas.addEventListener('mouseup',function(){
        draw_canvas.removeEventListener('mousemove', updateCorners,false);
    },false);
  }

  function updateCorners(e){
    corners[1] = [e.layerX, e.layerY]
    redraw();
  }

  function redraw(){
    draw_context.clearRect(0, 0, canvas.width, canvas.height);
    draw_context.beginPath()
    draw_context.lineWidth = "2";
    draw_context.strokeStyle = "red";
    draw_context.rect(corners[0][0], corners[0][1], corners[1][0] - corners[0][0], corners[1][1] - corners[0][1]);
    draw_context.stroke();
  }

  function extractFrame(){
    var video = document.createElement('video');
    var array = [];

    function initCanvas(){
        canvas.width = this.videoWidth;
        canvas.height = this.videoHeight;
    }

    function drawFrame(e) {
        this.pause();
        context.drawImage(this, 0, 0);
        var blob = canvas.toBlob(saveFrame, 'image/png');
        var dataUrl = URL.createObjectURL(array[0]);
        document.getElementById('back').style.background = "url('${dataUrl}')";
        URL.revokeObjectURL(dataUrl);
    }

    function saveFrame(blob) {
        console.log(array);
        array.push(blob);
        console.log(array);
    }

    video.muted = true;
    video.addEventListener('loadedmetadata', initCanvas, false);
    video.addEventListener('timeupdate', drawFrame, false);
    video.src = URL.createObjectURL(this.files[0]);
    video.play();
  }

</script>

I've tried reordering the code, adjusting objects passed around, and more, but nothing seems to work. One common error I encounter is:

Failed to execute 'createObjectURL' on 'URL': Overload resolution failed.

According to another source, this could be due to the object in the array being undefined or None, but the logged array shows that it contains blobs.

Any advice would be greatly appreciated. Let me know if you need more code or specifications. Thank you!

EDIT: I have added additional code for clarity. I am testing this locally, so hopefully it will suffice for now.

Answer №1

UPDATED

    function displayImage(e) {
        this.stop();
        context.drawImage(this, 0, 0);
        canvas.toBlob(saveImage,'image/jpeg');
    }

    function saveImage(blob) {
        imageURL = URL.createObjectURL(blob);
        document.getElementById('background').style.background = 'url(' + imageURL + ')';
        URL.revokeObjectURL(imageDataUrl);
    }

Thanks to @Kaiido's advice, I learned how to utilize a blob instead of a data url.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Automating the click of JavaScript buttons with Selenium

Test page Experimenting with the above Indeed link to test my selenium automation skills. I am attempting to automate the clicking of the 'apply' button using the Firefox webdriver. My code snippet is as follows: from selenium import webdriver ...

transform array inside returned object to a dropdown list using JavaScript

I have gone through multiple examples trying to figure out how to accomplish this task, but the solution still evades me. The issue at hand involves an ajax call returning an object with a couple of properties along with an array of other objects. My goal ...

I keep encountering the following error message: " ERROR Error Code: 200 Message: Http failure during parsing for http://localhost:3000/login"

My Angular Login component is responsible for passing form data to the OnSubmit method. The goal is to send form data from the front-end application and authenticate users based on matching usernames and passwords in a MySQL database. ***This login form i ...

Experiencing problems with the CSS on the Login page and have yet to find a solution

Description:- I encountered an issue with my HTML login page where I used an image for the username and password. Everything worked fine when I manually typed in the username and password, but when I selected the username from the auto-fill suggestions pop ...

Can anyone advise on the best way to pass a function as a prop in React using TypeScript?

Hey there! I'm currently attempting to create a button component that can perform two separate actions: one labeled as "START" which initiates a countdown using StoreTimer.start(), and the other labeled as "RESET" which resets the countdown with Store ...

Adding information to a MySQL database using PHP/AJAX, triggering the success function only once the data has been successfully inserted (Callback)

I've been struggling to create a basic website, and some of the information provided here is confusing and irrelevant to my specific situation. My website features a form with three input fields, a button, and a list. When the submit button is clicke ...

What is the process for saving the selected value from a radio button into the database?

Below is an example of code I am working with: <label style="cursor:pointer;"><input type="radio" name="rads" value="'.$correct.'" id = "radio">'.$answer.'</label> <button onclick="myFunction()">Value</butto ...

Guide on generating a child element in a React application using server response

I have developed a react application with multiple nested routes. One of the nested routes utilizes a backend API that returns complete HTML content. My goal is to display this HTML content with the same styling in my UI without directly manipulating the ...

Is there a way to access a random element from an array upon pressing a button?

My dilemma involves a reducer array containing Q/A objects that are displayed in two different divs. I want to create a function that will be triggered by the "Next" button, generating a random number to determine which object from the array is displayed n ...

issue with displaying three images side by side in Internet Explorer

Hello everyone, I have created a code to display 3 images in a row. It works perfectly in Firefox but not in Internet Explorer. Here is my code: echo "<div class=\"container mod\"><ul id=\"three-col\" class=\"press\" ...

Multer error message: "The file or directory you are looking for does not exist"

I am encountering errors while attempting to upload multiple files through Mongoose using multer. As I am new to multer, any assistance would be greatly appreciated. Thank you. Below is my app.js const storage = multer.diskStorage({ destination: functio ...

AngularJS is unable to properly display (parse) data fetched using $http.get from Laravel5

Working on my SPA project, I have integrated Laravel 5 for database management and used AngularJS for the front-end. All Angular files are stored in the public folder. Instead of displaying a list of users when visiting localhost, it shows: {{ user1.name ...

Utilizing a self-invoking function to incorporate JavaScript

In my role, I am responsible for managing a Content Management System (CMS) used by developers to create content that involves JavaScript. In the past, we placed the content in an iFrame for containment purposes; now, it operates as a single-page client-si ...

Struggle for dominance between Bootstrap carousel and Flexslider

Issue with Bootstrap carousel and Flex-slider. When both included, the flex slider does not work properly if I remove bootstrap.js. However, without bootstrap.js, the flex slider works but the carousel malfunctions. Code Snippet: <div class="carousel- ...

Retrieve the template variable on creation in Meteor

When I render a template using Blaze.renderWithData(Template.templateName, { key: value }), I am able to access the value in my template by using {{key}}, but I am facing difficulty accessing it in my JavaScript code. I attempted to retrieve the value by ...

Why React Native's array.map function fails to calculate the sum of a state

I am currently developing a COVID-19 data app for a school project, and I am struggling to sum the total number of tests and positive results from an API. Below is the snippet of code that I am using: function GetDataApi() { if(data !== null) { const ...

Content from ajax request is invalid

Currently, I am facing an issue with loading a comment list and replacing the existing list on my HTML page with the new one. Previously, I used to load a simple XML list, iterate over its elements, and generate content. Although this method worked fine, i ...

I'm having trouble getting PHP/AJAX to return the expected XML data - it keeps

I have a JavaScript script that looks like this: function showItems(type) { var xmlhttp = new XMLHttpRequest(); //creating object var call = "getitems"; xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState ...

Restricted user voting using MongoDB

In my simple forum, users can sign up, login, and make posts. I am currently working on adding a feature that allows users to like posts, but I'm facing difficulties in ensuring that a user can only like a post once. At the moment, when a user clicks ...

Is it advisable to tidy up handlePress variables within useEffect?

As a newcomer to react native, I find myself struggling with figuring out which objects need to be cleaned up before a component unMount. I understand that API calls should be cleaned, but what else? For example, if I have a button like this: const _rende ...