Tutorial Para Criação De Videos Curtos Em Python Para O YouTube Shorts

by LBertini in Circuits > Software

279 Views, 0 Favorites, 0 Comments

Tutorial Para Criação De Videos Curtos Em Python Para O YouTube Shorts

pieslices.png

Este código apresenta uma possível sequência de ações para se criar videos curtos no formato apropriado para o YouTube Shorts, utilizando-se a linguagem Python. Não é a única maneira, mas apenas uma possível solução.

Pode ser utilizado para a criação de animações de algoritmos ou apenas qualquer arte computacional que se deseje mostrar passo a passo.

O usuário poderá utilizar qualquer função da biblioteca ImageDraw, como circulos, linhas, retangulos, etc. para criar as imagens. (Ver https://pillow.readthedocs.io/en/stable/reference/ImageDraw.html):

The ImageDraw module provides simple 2D graphics for Image objects. You can use this module to create new images, annotate or retouch existing images, and to generate graphics on the fly for web use.


A criação do vídeo é composta por três etapas:

  1. Criação das imagens que serão os frames do vídeo;
  2. Conversão dos frames em um vídeo sem áudio;
  3. Inclusão do áudio usando a ferramenta ffmpeg

Supplies

Google Colab

Criação Dos Frames.

Os frames serão gerados em uma pasta img e toda vez que o código abaixo for executado, essa pasta será removida e uma nova pasta será criada.

O formato ideal para os vídeos curtos no YouTube é 1080x1920. Essas são as dimensões atribuídas nas variáveis h e w, respectivamente, na linha:

img = Image.new('RGB', (w, h),color = 'blue')

Nessa mesma linha, a cor de fundo pode ser alterada. Uma lista de nomes de cores definidos pode ser obtida aqui: https://matplotlib.org/stable/gallery/color/named_colors.html.

O padrão de tupla (R,G,B) também pode ser utilizado. Exemplo:

img = PIL.Image.new(mode='RGB', size=(200,200), color=(153,153,255))

A cada objeto novo desenhado, pode-se determinar que um novo frame de vídeo será gerado. Para isso basta que a imagem seja gerada na pasta img:

img.save('img/saida' + str(frame+1000) + '.png')

A variável frame será incrementada para cada nova imagem gerada. Assim teremos arquivos saida1001.png, saida1002.png, saida1003.png, etc.

O código abaixo gera imagens sucessivas com um novo objeto draw.pieslice() inserido com as coordenadas de modo a cobrir a tela toda.

No final há a inclusão de texto através de draw.text() e de um logotipo com a função img.paste(). Antes disso a imagem do logotipo recebe um resize utilizando a própria biblioteca PIL, assim mantendo a propriedade transparente da imagem .png.

No final há a criação de 30 frames idênticos, para que haja uma extensão do tempo de exibição do quadro final.

from PIL import Image, ImageDraw, ImageFont
import os
import shutil
from random import randint

# deleta a pasta 'img' 
shutil.rmtree('img', ignore_errors=True)

#cria a pasta 'img'
os.mkdir('img')

# tamanho da imagem
h = 1920
w = 1080

# número de série dos frames
frame=0

# cria a imagem
img = Image.new('RGB', (w, h),color = 'blue')
draw = ImageDraw.Draw(img)

size = 180
for x in range(0,w,size):
  for y in range(0,h,size):
    # randomização do pieslice, início e fim
    a=randint(0,360)
    b=(a+60)%360
    # randomização da cor 
    c1=randint(0,255)
    c2=randint(0,255)
    if(a<120):
      cor=(c1,c2,0)
    elif(a<240):
      cor=(c1,0,c2)
    else:
      cor=(0,c1,c2)

    # desenho do pieslice
    draw.pieslice((x, y, x+size-5, y+size-5), start=b, end=a, 
               fill=cor, outline=(0, 0, 0), width=5)

    # cria um frame
    frame=frame+1
    img.save('img/saida' + str(frame+1000) + '.png')

# posiciona o logo
logoIm = Image.open('unifei3.png')
scale=2
logoWidth, logoHeight = logoIm.size
logoWidth = logoWidth//scale
logoHeight = logoHeight//scale
logoIm=logoIm.resize((logoWidth,logoHeight))
img.paste(logoIm, (w-logoWidth-50, h-logoHeight-50),logoIm)

# cria um frame
frame=frame+1
img.save('img/saida' + str(frame+1000) + '.png')

# posiciona alguns textos
font = ImageFont.truetype("/usr/share/fonts/truetype/liberation/LiberationMono-Bold.ttf", 50)
draw.text((10, 10),"Tutorial de criação de video curto",(255,255,127),font=font)
draw.text((10, 80),"Autores:",(255,255,127),font=font)
draw.text((50, 150),"Autor 1",(255,255,127),font=font)
draw.text((50, 220),"Autor 2",(255,255,127),font=font)
draw.text((50, 290),"Autor 3",(255,255,127),font=font)

# cria 30 frames iguais
for i in range(30):
  # cria um frame
  frame=frame+1
  img.save('img/saida' + str(frame+1000) + '.png')


Composição Do Video Com OpenCV

O código desta etapa pega todas as imagens contidas na pasta img e gera um video de nome video.mp4 de duração video_duration. O que determina os frames por segundo é essa variável video_duration. Se na pasta img existirem 30 imagens e video_duration = 30, então resultará em um vídeo de fps=1.

É interessante utilizar a duração de 30 segundos. O limite máximo para o Youtube é 60. O exemplo deste tutorial utilizou 10.2 porque essa é a duração do arquivo de áudio escolhido para a etapa seguinte. Não é interessante utilizar um arquivo de som maior que a duração do vídeo porque não poderá se aproveitar do desfecho do som. O audio será truncado.

Nesta parte do código, o único ajuste a ser feito é estabelecer o valor de video_duration.

Adaptado da página "Python cv2.VideoWriter() Examples" em https://www.programcreek.com/python/example/72134/cv2.VideoWriter


import cv2
import os

image_folder = 'img'
video_name = 'video.mp4'
video_duration = 10.2       #duração do video em segundos

images = [img for img in os.listdir(image_folder) if img.endswith(".png")]
images.sort()
num_frames = len(images)
fps=num_frames/video_duration
print(fps)

frame = cv2.imread(os.path.join(image_folder, images[0]))
height, width, layers = frame.shape

fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
video = cv2.VideoWriter(video_name, fourcc, fps, (width,height))

for image in images:
    video.write(cv2.imread(os.path.join(image_folder, image)))        

cv2.destroyAllWindows()
video.release()

Adição Do Áudio Com FFmpeg

Aqui o único ajuste é fazer é o upload do arquivo de áudio e a alteração do nome do arquivo no código.

É importante que o áudio escolhido seja livre de direitos autorais. Para isso, uma possibilidade é buscar arquivos de som no site https://freesound.org/. Deve-se citar na descrição o autor e a licença, como mostrado abaixo no texto da descrição. Verifique no áudio escolhido quais são as restrições impostas pelo autor.

O áudio escolhido para este tutorial está em: https://freesound.org/people/milton./sounds/86877/

Ver https://github.com/kkroening/ffmpeg-python para entendimento da ferramenta FFmpeg e alternativas de utilização, como por exemplo inclusão de áudio estéreo.

Antes de executar essa etapa, é necessário instalar o FFmpeg:

pip install ffmpeg-python


import ffmpeg

input_audio = ffmpeg.input('walk-away.wav')
input_video = ffmpeg.input('video.mp4')

(
    ffmpeg
    .filter(input_audio, 'join', inputs=1, channel_layout='mono')
    .output(input_video.video, 'video-com-audio.mp4', shortest=None, vcodec='copy')
    .overwrite_output()
    .run()
)


Texto para a descrição do video:


Video criado em python com um simples loop com a função draw.pieslice() do pacote PIL ImageDraw. Créditos da música para Milton (https://freesound.org/people/milton./) que distribui com licença Attribution- NonComercial 3.0 https://creativecommons.org/licenses/by-nc/3.0/


Vídeo Publicado


https://youtube.com/shorts/lKYrdgLRRAs