codinggames

Como criar thumbnails para seus vídeos automaticamente com Node.js

A melhor forma de criar thumbnails para seus vídeos no Instagram

Escrito em 25 de outubro de 2023 - 🕒 5 min. de leitura

Apenas na semana passada eu postei sobre como fazer upload de Reels para o Instagram usando Node.js, e no código era possível fazer upload de um thumbnail para o vídeo também, mas eu não expliquei como criar esse thumbnail.

I mean, claro que você pode ir para no Photopea e criar um thumbnail para o seu vídeo, mas e se você quiser automatizar esse processo? E se você quiser criar um thumbnail diferente para todos os seus vídeos automaticamente?

Bem, é isso que eu vou te mostrar hoje.

Ilustração
Ilustração

Encontrando o package certo

Como um desenvolvedor frontend, a única coisa que eu sei sobre manipulação de imagens é usando canvas, e felizmente existe um package para Node.js que nos permite fazer isso, ele se chama node-canvas.

Com ele, nós podemos criar um canvas, desenhar imagens, textos, formas, etc. É bem legal, dê uma olhada no exemplo abaixo:

const { createCanvas, loadImage } = require('canvas');
const { writeFileSync } = require('fs');

const canvas = createCanvas(200, 200);
const ctx = canvas.getContext('2d');
ctx.font = '30px Impact';
ctx.fillStyle = '#000';
ctx.fillText('Hello World!', 0, 0);
canvas.toBuffer('image/png', (err, buffer) => {
  writeFileSync('./hello-world.png', buffer);
});

Criando um design

Eu não sou um designer, então eu não vou te ensinar como criar um bom design, mas eu posso te mostrar como eu criei o design para as minhas thumbnails.

Eu comecei criando um novo arquivo no Photopea com o mesmo tamanho do vídeo do Instagram Reels, que é 1080x1920px. Então eu adicionei uma imagem de fundo e um texto com o título do vídeo, e também uma cor de fundo para o texto com um pouco de opacidade.

E para finalizar, eu adicionei uma imagem com fundo transparente com uma imagem minha em pixel art.

Thumbnail para Reels
Thumbnail para Reels

Criando a thumbnail

Agora que nós temos o design, nós podemos começar a programar. Primeiro, nós precisamos criar uma função que irá criar a thumbnail para nós, e ela irá receber uma imagem de fundo, uma imagem de primeiro plano, um título e o caminho para salvar a thumbnail como parâmetros.

const generateImageForPost = async (
  backgroundImagePath,
  foregroundImagePath,
  title,
  outputPath
) => {
  const backgroundImage = await loadImage(backgroundImagePath);
  const foregroundImage = await loadImage(foregroundImagePath);

  const canvas = createCanvas(backgroundImage.width, backgroundImage.height);
  const ctx = canvas.getContext('2d');

  ctx.drawImage(foregroundImage, 0, 0);

  // TODO add text
  // addCenteredTextWithBackground(ctx, title, canvas.width, canvas.height);

  await new Promise((resolve, reject) => {
    const out = createWriteStream(outputPath);
    const stream = canvas.createPNGStream();
    stream.pipe(out);

    out.on('finish', () => {
      console.log('The PNG file was created.');
      resolve();
    });

    out.on('error', (err) => {
      reject(err);
    });
  });
};

Esse código irá carregar as imagens de fundo e primeiro plano, criar um canvas com o mesmo tamanho da imagem de fundo, desenhar a imagem de primeiro plano no canvas, e salvar o canvas como um arquivo PNG. Essa foi a parte fácil, agora nós precisamos adicionar o texto.

O desafio aqui é adicionar o texto no centro do canvas, e garantir que ele não irá ultrapassar o canvas. Vamos ver como podemos fazer isso.

Adicionando o texto

Primeiro, nós precisamos criar uma função que irá adicionar o texto no centro do canvas, e ela irá receber o texto e o canvas como parâmetros. Nós iremos fazer isso na função addCenteredTextWithBackground.

const addCenteredTextWithBackground = (
  ctx,
  text,
  canvasWidth,
  canvasHeight
) => {
  const fontSize = 150;
  ctx.font = `${fontSize}px Impact`;
  const lines = text.split(' ');

  const textHeight = fontSize * lines.length;
  const rectWidth = canvasWidth;
  const rectHeight = textHeight + 60;

  const rectX = (canvasWidth - rectWidth) / 2;
  const rectY = 300;

  ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
  ctx.fillRect(rectX, rectY, rectWidth, rectHeight);

  ctx.fillStyle = 'white';
  for (const [i, line] of lines.entries()) {
    const textX = (canvasWidth - ctx.measureText(line).width) / 2;
    const textY = rectY + fontSize * (i + 1);
    ctx.fillText(line, textX, textY);
  }
};

Essa função irá calcular o tamanho do retângulo que será o fundo do texto, e então irá desenhar o retângulo e o texto no canvas. Infelizmente, apenas fazer text.split(' '); não irá funcionar, porque dividir o texto por espaços irá simplesmente aumentar a altura do texto, mas não necessariamente irá fazer o texto caber no canvas.

Então vamos criar uma função chamada breakTextToFitCanvas que irá receber o texto, o contexto do canvas e uma largura máxima como parâmetros, e irá retornar um array de strings com o texto dividido em linhas que irão caber no canvas.

const breakTextToFitCanvas = (ctx, text, maxWidth) => {
  const words = text.split(' ');
  const lines = [];
  let currentLine = words[0];

  for (let i = 1; i < words.length; i++) {
    const word = words[i];
    const { width } = ctx.measureText(`${currentLine} ${word}`);

    if (width < maxWidth) {
      currentLine += ` ${word}`;
    } else {
      lines.push(currentLine);
      currentLine = word;
    }
  }

  lines.push(currentLine);

  return lines;
};

Juntando tudo

Agora que nós temos todas as funções que precisamos, nós podemos juntar tudo e criar a thumbnail. Vamos criar uma função chamada generateThumbnail que irá receber o título do vídeo e o caminho para salvar a thumbnail como parâmetros.

const generateThumbnail = async (title, outputPath) => {
  const backgroundImagePath = './background.png';
  const foregroundImagePath = './foreground.png';

  await generateImageForPost(
    backgroundImagePath,
    foregroundImagePath,
    title,
    outputPath
  );
};

E agora nós podemos chamar essa função e criar a thumbnail.

generateThumbnail('How to create thumbnails for your videos with Node.js', './thumbnail.png');

Conclusão

E é isso! Agora você pode criar thumbnails para seus vídeos automaticamente. Eu espero que você tenha gostado desse post, e não se esqueça de ver como fazer upload de Reels para o Instagram usando Node.js.

Até a próxima!

Tags:


Publicar um comentário

Comentários

Nenhum comentário.