.webm not encoded correctly in javascript, why?

63 Views Asked by At

I have this .js code. When I export the .webm video, it doesn't show the progress bar in media players and if I convert it into .mp4 it breaks the video. Any idea why this might be happening?

What this does is take some input from the user, and then, on canvas draw the video, that should work normally, and I've no idea why this doesn't work.

// Recording and Animation
let mediaRecorder;
let recordedChunks = [];

function startRecording() {
  const stream = canvas.captureStream(60); // 60 FPS, adjust as needed
  mediaRecorder = new MediaRecorder(stream, {
    mimeType: 'video/webm; codecs="vp8, opus"',
  });

  mediaRecorder.ondataavailable = function (e) {
    if (e.data.size > 0) {
      recordedChunks.push(e.data);
    }
  };

  mediaRecorder.onstop = downloadRecordedVideo;
  mediaRecorder.start();
}

function stopRecording() {
  mediaRecorder.stop();
}

function downloadRecordedVideo() {
  const blob = new Blob(recordedChunks, { type: "video/webm" });
  const url = URL.createObjectURL(blob);

  const a = document.createElement("a");
  document.body.appendChild(a);
  a.style = "display: none";

  a.href = url;
  a.download = "MySTCInt.webm";
  a.click();

  URL.revokeObjectURL(url);
  document.body.removeChild(a);
}

// Canvas setup
let canvas = document.getElementById("myCanvas");
let ctx = canvas.getContext("2d");
let framerate = 60;

// Image sources
const imageSources = {
  stc: "static/stc.png",
  template: "static/template.png",
};

// Load images
let stcImage = new Image();
stcImage.src = imageSources.stc;
let templateImage = new Image();
templateImage.src = imageSources.template;

let uploadedImage = null;

// Text configuration
const texts = [
  {
    text: "Main Title",
    size: "60px Arial",
    x: 100,
    y: 480,
    bold: true,
    opacity: 1.0,
  },
  {
    text: "Subtitle",
    size: "40px Arial",
    x: 100,
    y: 550,
    bold: false,
    opacity: 0.8,
  },
  {
    text: "Name",
    size: "40px Arial",
    x: 100,
    y: 660,
    bold: true,
    opacity: 1.0,
  },
  {
    text: "Action Group",
    size: "30px Arial",
    x: 100,
    y: 710,
    bold: false,
    opacity: 0.8,
  },
];

// Animation settings
const animationSettings = {
  fadeInDuration: 1,
  fadeOutDuration: 1,
  fadeInTextDuration: 1,
  initialDelay: 1500,
  fadeToBlackDelay: 2000,
  fadeFromBlackDelay: 3000,
  totalAnimationTime: 6000,
};

// Fade in image
function fadeInImage(image, duration, callback) {
  let alpha = 0;
  let step = 1 / (framerate * duration);

  function draw() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.globalAlpha = alpha;
    ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
    alpha += step;
    if (alpha < 1) {
      requestAnimationFrame(draw);
    } else {
      ctx.globalAlpha = 1;
      if (callback) callback();
    }
  }
  draw();
}

// Fade to black
function fadeToBlack(duration, callback) {
  let alpha = 0;
  let step = 1 / (framerate * duration);

  function draw() {
    ctx.fillStyle = `rgba(0, 0, 0, ${alpha})`;
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    alpha += step;
    if (alpha < 1) {
      requestAnimationFrame(draw);
    } else {
      if (callback) callback();
    }
  }
  draw();
}

// Fade from black
function fadeFromBlack(duration) {
  let alpha = 1;
  let step = 1 / (framerate * duration);

  function draw() {
    ctx.globalAlpha = 1;
    ctx.drawImage(templateImage, 0, 0, canvas.width, canvas.height);
    ctx.globalAlpha = alpha;
    ctx.fillStyle = "rgba(0, 0, 0, " + alpha + ")";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    alpha -= step;
    if (alpha > 0) {
      requestAnimationFrame(draw);
    }
  }
  draw();
}

// Fade in text
function fadeInTextWithImage(texts, image, duration) {
  let alpha = 0;
  let step = 1 / (framerate * duration);

  function draw() {
    ctx.globalAlpha = 1;
    ctx.drawImage(templateImage, 0, 0, canvas.width, canvas.height);

    if (image) {
      ctx.globalAlpha = alpha;
      let imageX = canvas.width - image.width - 90;
      let imageY = (canvas.height - image.height) / 2;
      ctx.drawImage(image, imageX, imageY);
    }

    texts.forEach((text) => {
      ctx.font = text.bold ? `bold ${text.size}` : text.size;
      ctx.globalAlpha = text.opacity * alpha;
      ctx.fillStyle = "black";
      ctx.fillText(text.text, text.x, text.y);
    });

    alpha += step;
    if (alpha < 1) {
      requestAnimationFrame(draw);
    }
  }
  draw();
}

function startAnimation() {
  startRecording();
  fadeInImage(stcImage, animationSettings.fadeInDuration);
  setTimeout(
    () => fadeToBlack(animationSettings.fadeOutDuration),
    animationSettings.initialDelay
  );
  setTimeout(
    () => fadeFromBlack(animationSettings.fadeOutDuration),
    animationSettings.fadeToBlackDelay
  );
  setTimeout(
    () =>
      fadeInTextWithImage(
        texts,
        uploadedImage,
        animationSettings.fadeInTextDuration
      ),
    animationSettings.fadeFromBlackDelay
  );
  setTimeout(stopRecording, animationSettings.totalAnimationTime);
}

‎ ‎ ‎ I've tried changing the codecs, didn't work.

0

There are 0 best solutions below